paint-brush
Java'da Test Etme: Temel Kavramlar [Bölüm 1: Birim Testi]ile@gromspys
1,621 okumalar
1,621 okumalar

Java'da Test Etme: Temel Kavramlar [Bölüm 1: Birim Testi]

ile Sergei Korneev10m2023/11/14
Read on Terminal Reader

Çok uzun; Okumak

Bu makalede, basit kod örnekleri, parametrelendirme, istisna testi ve ek açıklamalar dahil olmak üzere Java birim testinin temel kavramlarını inceleyeceğiz.
featured image - Java'da Test Etme: Temel Kavramlar [Bölüm 1: Birim Testi]
Sergei Korneev HackerNoon profile picture

Birim testi, yazılım geliştirmede kodunuzun güvenilirliğini ve doğruluğunu sağlayan temel bir uygulamadır. Bu makalede, basit kod örnekleri, parametrelendirme, istisna testi, @Before , @BeforeEach , @After ve @AfterEach gibi ek açıklamaların yanı sıra örnek ve taslakların kullanımı da dahil olmak üzere Java birim testinin temel kavramlarını inceleyeceğiz. .


Ayrıca alay etmek için popüler Mockito kitaplığını tanıtacağız ve Maven eklentilerini kullanarak kod kapsamının ölçülmesi konusunda rehberlik sağlayacağız.

Birim Testinin Önemi

Birim testi, doğruluğunu doğrulamak için ayrı ayrı bileşenlerin veya kod birimlerinin ayrı ayrı test edilmesi uygulamasıdır. Birincil amaç, geliştirme sürecinin başlarında hataları tespit edip düzeltmek, böylece her kod biriminin beklendiği gibi davranmasını sağlamaktır.


Örneklerimiz için kullanabileceğimiz basit bir hesap makinesi sınıfı oluşturarak başlayalım. Calculator sınıfı temel aritmetik işlemleri içerir:

 public class Calculator { public int add(int a, int b) { return a + b; } public int subtract(int a, int b) { return a - b; } public int multiply(int a, int b) { return a * b; } public int divide(int a, int b) { return a / b; } }

Basit Bir Birim Testi Yazma

Calculator sınıfımıza yönelik bir birim testi oluşturmak için Java için popüler bir test çerçevesi olan JUnit çerçevesini kullanabilirsiniz. add yöntemi için basit bir birim testi yazalım:

 import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; public class CalculatorTest { @Test public void testAdd() { Calculator calculator = new Calculator(); int result = calculator.add(2, 3); assertEquals(5, result); } }

Bu testte gerekli JUnit sınıflarını içe aktarıyoruz ve test yöntemine @Test ile açıklama ekliyoruz. Daha sonra Calculator sınıfının bir örneğini oluşturuyoruz ve add yönteminin sonucunun beklenen değere (5) eşit olduğunu iddia ediyoruz.

Parametreli Testler

Parametrelendirilmiş testler, aynı test mantığını birden fazla giriş verisi kümesiyle çalıştırmanıza olanak tanır. Bu, çeşitli giriş değerlerine sahip bir yöntemi test etmek için kullanışlıdır. Bunu JUnit'te yapmak için @ParameterizedTest ek açıklamasını kullanabilir ve giriş değerlerini ve beklenen sonuçları parametre olarak sağlayabilirsiniz. İşte bir örnek:

 import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; import static org.junit.jupiter.api.Assertions.assertEquals; public class CalculatorTest { @ParameterizedTest @CsvSource({"2, 3, 5", "4, 7, 11", "0, 0, 0"}) public void testAdd(int a, int b, int expected) { Calculator calculator = new Calculator(); int result = calculator.add(a, b); assertEquals(expected, result); } }

Bu örnekte @ParameterizedTest ek açıklaması, birden fazla giriş değeri kümesi ve beklenen sonuçları CSV formatında sunmamıza olanak tanır. add yönteminin doğruluğu sağlanarak her kombinasyon için test yöntemi yürütülür.

İstisna Testi

İstisnaları test etmek, kodunuzun hataları uygun şekilde işlemesini sağlamak için çok önemlidir. İstisna durumlarını test etmek için JUnit tarafından assertThrows yöntemiyle birlikte @Test ek açıklamasını kullanabilirsiniz.


İşte bir örnek:

 javaCopy codeimport org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertThrows; public class CalculatorTest { @Test public void testDivideByZero() { Calculator calculator = new Calculator(); assertThrows(ArithmeticException.class, () -> calculator.divide(5, 0)); } }

Bu testte, Calculator sınıfında bir sayının sıfıra bölünmesinin bir ArithmeticException oluşturduğunu doğrularız.

Ek Açıklamaları Kullanma: @Before, @BeforeEach, @After ve @AfterEach

@Before , @BeforeEach , @After ve @AfterEach gibi ek açıklamalar test ortamını kurmak ve yıkmak için kullanılır. Bu ek açıklamalar, ortak test başlatma ve temizleme görevlerinin yönetilmesine yardımcı olur.


  • @Before ve @After test sınıfındaki tüm test yöntemlerinden önce ve sonra sırasıyla bir kez çalıştırılır.
  • @BeforeEach ve @AfterEach her test yönteminden önce ve sonra çalışır.


İşte bir örnek:

 import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; public class CalculatorTest { private Calculator calculator; @BeforeEach public void setUp() { calculator = new Calculator(); } @AfterEach public void tearDown() { calculator = null; } @Test public void testAdd() { int result = calculator.add(2, 3); assertEquals(5, result); } @Test public void testSubtract() { int result = calculator.subtract(5, 3); assertEquals(2, result); } }

Bu örnekte, setUp yöntemine @BeforeEach ile açıklama eklenmiştir ve her testten önce Calculator nesnesini başlatır. @AfterEach ile açıklamalı tearDown yöntemi, her testten sonra kaynakları temizler.

Alaylar ve Taslaklar

Test edilen kodu veritabanları veya web hizmetleri gibi harici bağımlılıklardan izole etmek istediğinizde birim testinde taklitler ve taslaklar çok önemlidir. Bu bağımlılıkların davranışını simüle etmenize olanak tanırlar.


  • Sahte: Sahte, gerçek bir nesnenin davranışını taklit eden ancak sizin kontrolünüz altında olan bir nesnedir. Etkileşimleri kaydeder ve belirli yöntemlerin çağrıldığını doğrulamanıza olanak tanır.


  • Saplama: Bir saplama, yöntem çağrılarına hazır yanıtlar sağlar. Önceden tanımlanmış verileri döndürür ve harici bir sistemin belirli davranışlarını simüle etmek için kullanılır.


Calculator sınıfını, dış bağımlılık içeren bir yöntem içerecek şekilde genişletelim ve ardından bu bağımlılığı simüle etmek için bir saplama oluşturalım.

 public class Calculator { private ExternalService externalService; public Calculator(ExternalService externalService) { this.externalService = externalService; } public int performComplexCalculation(int a, int b) { int result = externalService.multiply(a, b); return result + externalService.getConstant(); } }

Bu güncellenmiş Calculator sınıfında, performComplexCalculation çarpma ve sabit bir değer elde etme için bir ExternalService dayanır.


Gerçek ExternalService bağlı olmadan Calculator sınıfını test etmek için nasıl bir saplama oluşturabileceğiniz aşağıda açıklanmıştır.

 import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.*; public class CalculatorTest { @Test public void testPerformComplexCalculation() { // Create a stub for ExternalService ExternalService externalServiceStub = new ExternalService() { @Override public int multiply(int a, int b) { return a * b; } @Override public int getConstant() { return 5; // Stubbed constant value } }; // Create the Calculator with the stubbed ExternalService Calculator calculator = new Calculator(externalServiceStub); // Test the performComplexCalculation method int result = calculator.performComplexCalculation(2, 3); assertEquals(11, result); // 2*3 + 5 (constant) = 11 } }

Bu testte, gerekli yöntemleri geçersiz kılan anonim bir sınıf oluşturularak, ExternalService test yönteminin içine yerleştirilir. Bu şekilde Calculator test yöntemi, ExternalService gerçek uygulamasına bağlı olmadan çalışır.


Saplamalar, bir sınıfın veya yöntemin belirli işlevselliğini izole etmek ve test etmek amacıyla harici sistemlerin veya bağımlılıkların davranışını simüle etmek için kullanışlıdır. Bu, saplamanın davranışını kontrol etmenize ve gerçek harici hizmetlere ihtiyaç duymadan test edilen üniteye odaklanmanıza olanak tanır.

Alay Etmek için Mockito'yu Tanıtıyoruz

Mockito, sahte nesneler oluşturmak ve yönetmek için kullanılan popüler bir Java kütüphanesidir. Diyelim ki harici bir ödeme ağ geçidiyle etkileşime giren bir PaymentService sınıfımız var. Ödeme ağ geçidi için bir örnek oluşturmak amacıyla Mockito'yu kullanabiliriz:

 import org.junit.jupiter.api.Test; import static org.mockito.Mockito.*; public class PaymentServiceTest { @Test public void testProcessPayment() { PaymentGateway paymentGateway = mock(PaymentGateway.class); PaymentService paymentService = new PaymentService(paymentGateway); when(paymentGateway.charge(100.0)).thenReturn(true); boolean result = paymentService.processPayment(100.0); assertTrue(result); verify(paymentGateway, times(1)).charge(100.0); } }

Bu örnekte, sahte bir PaymentGateway oluşturuyoruz ve davranışını tanımlamak için when yöntemini kullanıyoruz. Daha sonra PaymentService sınıfında processPayment yöntemini çağırırız ve charge yönteminin beklenen parametrelerle çağrıldığını doğrularız.

Kod Kapsamı ve Maven Eklentisi

Kod kapsamı, birim testleriniz tarafından yürütülen kod satırlarının, dalların veya ifadelerin yüzdesini ölçer. Test edilmemiş kodu ve ek test gerektirebilecek alanları belirlemenize yardımcı olur.


Maven, Java projeleri için popüler bir oluşturma aracıdır ve JaCoCo gibi eklentileri kullanarak kod kapsamı analizini Maven projenize entegre edebilirsiniz. JaCoCo'yu projenize nasıl ekleyeceğiniz aşağıda açıklanmıştır:


  1. Projenizin pom.xml dosyasını açın.
  2. JaCoCo Maven eklenti yapılandırmasını ekleyin:
 <build> <plugins> <plugin> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> <version>0.8.7</version> <executions> <execution> <goals> <goal>prepare-agent</goal> </goals> </execution> <execution> <id>report</id> <phase>test</phase> <goals> <goal>report</goal> </goals> </execution> </executions> </plugin> </plugins> </build>


Maven yapınızı aşağıdaki komutla çalıştırın:

 mvn clean verify


Derlemeyi çalıştırdıktan sonra kod kapsamı raporunu target/site/jacoco/index.html dosyasında bulabilirsiniz. Bu rapor, kodunuzun birim testlerinizin kapsamı hakkında ayrıntılı bilgi sağlar.

Çözüm

Java birim testi, kodunuzun güvenilirliğini ve doğruluğunu sağlamak için önemli bir uygulamadır. JUnit ve Mockito gibi araçlarla bileşenleriniz için etkili birim testleri ve modeller yazabilirsiniz.


Kod kapsamı analizini Maven ve JaCoCo ile entegre ederek testlerinizin kod tabanınızın önemli bir bölümünü kapsamasını sağlayabilirsiniz. Birim testlerini düzenli olarak test etmek ve sürdürmek, yüksek kaliteli ve sağlam Java uygulamaları üretmenize yardımcı olacaktır.


Bu serinin bir sonraki bölümünde, genel sistemin doğru şekilde çalıştığından emin olmak için farklı bileşenler ve hizmetler arasındaki etkileşimlerin test edilmesini içeren, yazılım testinin kritik bir yönü olan entegrasyon testini inceleyeceğiz.


Entegrasyon testinin heyecan verici dünyasına dalacağımız ikinci bölüm için bizi izlemeye devam edin!