logo
eng-flag

JUnit Notları ve İpuçları

İçindekiler

  1. Kurulum
  2. Temel Notasyonlar
  3. Assertions (Doğrulamalar)
  4. Test Yaşam Döngüsü
  5. Parametreli Testler
  6. Varsayımlar
  7. Zaman Aşımı
  8. İstisna Testi
  9. Test Kümesi
  10. Gelişmiş Özellikler
  11. En İyi Uygulamalar

Kurulum

Maven Bağımlılığı

pom.xml dosyanıza şunu ekleyin:

<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-api</artifactId>
    <version>5.9.2</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-engine</artifactId>
    <version>5.9.2</version>
    <scope>test</scope>
</dependency>

Gradle Bağımlılığı

build.gradle dosyanıza şunu ekleyin:

testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.2'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.2'

Temel Notasyonlar

import org.junit.jupiter.api.*;

public class MyTest {
    @Test
    void testMethod() {
        // Test kodu burada
    }

    @BeforeEach
    void setUp() {
        // Her testten önce çalışır
    }

    @AfterEach
    void tearDown() {
        // Her testten sonra çalışır
    }

    @BeforeAll
    static void setUpAll() {
        // Sınıftaki tüm testlerden önce bir kez çalışır
    }

    @AfterAll
    static void tearDownAll() {
        // Sınıftaki tüm testlerden sonra bir kez çalışır
    }

    @Disabled("Devre dışı bırakılma nedeni")
    @Test
    void disabledTest() {
        // Bu test çalışmayacak
    }
}

Assertions (Doğrulamalar)

import static org.junit.jupiter.api.Assertions.*;

@Test
void testAssertions() {
    assertEquals(expected, actual);
    assertTrue(condition);
    assertFalse(condition);
    assertNull(object);
    assertNotNull(object);
    assertSame(expected, actual);
    assertNotSame(expected, actual);
    assertArrayEquals(expectedArray, actualArray);
    assertThrows(ExpectedException.class, () -> {
        // ExpectedException fırlatması gereken kod
    });
    assertAll("gruplandırılmış doğrulamalar",
        () -> assertEquals(expected1, actual1),
        () -> assertEquals(expected2, actual2)
    );
}

Test Yaşam Döngüsü

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class LifecycleTest {
    @BeforeAll
    void initAll() {
        // Tüm test yöntemlerinden önce bir kez çalışır
    }

    @BeforeEach
    void init() {
        // Her test yönteminden önce çalışır
    }

    @Test
    void testMethod1() {
        // Test kodu
    }

    @Test
    void testMethod2() {
        // Test kodu
    }

    @AfterEach
    void tearDown() {
        // Her test yönteminden sonra çalışır
    }

    @AfterAll
    void tearDownAll() {
        // Tüm test yöntemlerinden sonra bir kez çalışır
    }
}

Parametreli Testler

import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.*;

class ParameterizedTests {
    @ParameterizedTest
    @ValueSource(strings = { "racecar", "radar", "able was I ere I saw elba" })
    void palindromes(String candidate) {
        assertTrue(isPalindrome(candidate));
    }

    @ParameterizedTest
    @CsvSource({
        "apple,  1",
        "banana, 2",
        "'lemon, lime', 3"
    })
    void testWithCsvSource(String fruit, int rank) {
        assertNotNull(fruit);
        assertTrue(rank > 0);
    }

    @ParameterizedTest
    @EnumSource(TimeUnit.class)
    void testWithEnumSource(TimeUnit timeUnit) {
        assertNotNull(timeUnit);
    }

    @ParameterizedTest
    @MethodSource("stringProvider")
    void testWithMethodSource(String argument) {
        assertNotNull(argument);
    }

    static Stream<String> stringProvider() {
        return Stream.of("apple", "banana", "cherry");
    }
}

Varsayımlar

import static org.junit.jupiter.api.Assumptions.*;

@Test
void testOnlyOnDeveloperWorkstation() {
    assumeTrue("DEV".equals(System.getenv("ENV")));
    // testin geri kalanı
}

@Test
void testOnlyOnCiServer() {
    assumeTrue("CI".equals(System.getenv("ENV")),
               () -> "Test iptal ediliyor: CI sunucusunda değil");
    // testin geri kalanı
}

Zaman Aşımı

@Test
@Timeout(value = 500, unit = TimeUnit.MILLISECONDS)
void timeoutTest() {
    // 500 milisaniye içinde tamamlanması gereken test kodu
}

İstisna Testi

@Test
void exceptionTesting() {
    Exception exception = assertThrows(ArithmeticException.class, () -> {
        int result = 1 / 0;
    });

    assertEquals("/ by zero", exception.getMessage());
}

Test Kümesi

@Suite
@SelectClasses({
    TestClass1.class,
    TestClass2.class
})
class TestSuite {
    // Bu sınıf boş kalır
}

Gelişmiş Özellikler

İç İçe Testler

@Nested
class NestedTests {
    @Test
    void test1() {
        // Test kodu
    }

    @Test
    void test2() {
        // Test kodu
    }
}

Dinamik Testler

@TestFactory
Collection<DynamicTest> dynamicTests() {
    return Arrays.asList(
        dynamicTest("1. dinamik test", () -> assertTrue(true)),
        dynamicTest("2. dinamik test", () -> assertEquals(4, 2 * 2))
    );
}

Test Arayüzleri

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
interface TestLifecycleLogger {
    @BeforeAll
    default void beforeAllTests() {
        System.out.println("Tüm testlerden önce");
    }

    @AfterAll
    default void afterAllTests() {
        System.out.println("Tüm testlerden sonra");
    }

    @BeforeEach
    default void beforeEachTest(TestInfo testInfo) {
        System.out.println("Çalıştırılacak [" + testInfo.getDisplayName() + "]");
    }

    @AfterEach
    default void afterEachTest(TestInfo testInfo) {
        System.out.println("Çalıştırma tamamlandı [" + testInfo.getDisplayName() + "]");
    }
}

class TestInterfaceDemo implements TestLifecycleLogger {
    @Test
    void test1() {
        // Test kodu
    }
}

En İyi Uygulamalar

  1. Açıklayıcı test metodu isimleri kullanın

    @Test
    void shouldReturnTrueWhenInputIsValid() {
        // Test kodu
    }
    
  2. Testleri bağımsız tutun

    • Her test diğerlerinden bağımsız olarak çalışabilmelidir
  3. Kurulum ve temizleme için @BeforeEach ve @AfterEach kullanın

    • Her test temiz bir durumla başlamalıdır
  4. İlgili testleri @Nested sınıfları kullanarak gruplayın

    • Okunabilirlik ve organizasyonu artırır
  5. Birden fazla girdi test etmek için parametreli testler kullanın

    • Kod tekrarını azaltır
  6. Hızlı testler hedefleyin

    • Harici bağımlılıklar için mock veya stub kullanın
  7. AAA desenini takip edin: Arrange (Hazırla), Act (Uygula), Assert (Doğrula)

    @Test
    void testAddition() {
        // Arrange
        Calculator calc = new Calculator();
        
        // Act
        int result = calc.add(2, 3);
        
        // Assert
        assertEquals(5, result);
    }
    
  8. Ortam spesifik testler için varsayımlar kullanın

    • Testlerin ortam sorunları nedeniyle başarısız olmasını önler
  9. Testlerde mantıktan kaçının

    • Testler basit ve anlaşılır olmalıdır
  10. Birden fazla ilgili doğrulama için assertAll kullanın

    • Bir doğrulama başarısız olsa bile tüm doğrulamaların kontrol edilmesini sağlar

2024 © Tüm hakları saklıdır - buraxta.com