JUnitとTestNGの簡単な比較

こんにちは、Habr。「JavaQAAutomation Engineer」コースの将来の学生と、テストのトピックに関心のあるすべての人のために、資料の翻訳を用意しました。



また、オープンウェビナー
「PageObjectPattern」にアクセスすることをお勧めします自動テストを読み直してリファクタリングする必要がないようにするには、すぐにアーキテクチャについて考える必要があります。ここでパターンが助けになります。ウェビナーの参加者は、専門家と一緒に、彼らの中で最も人気のあるものに精通します。






1。概要

JUnitとTestNGは、間違いなくJavaエコシステムで最も人気のある2つの単体テストフレームワークです。JUnitはTestNGのインスピレーションとして機能しましたが、後者には多くの違いがあり、JUnitとは異なり、機能的でより高いレベルのテストで機能します。





, .





2.

- , . .





JUnit , . @BeforeEach, @AfterEach @BeforeAll @AfterAll :





public class SummationServiceTest {

    private static List<Integer> numbers;

    @BeforeAll
    public static void initialize() {
        numbers = new ArrayList<>();
    }

    @AfterAll
    public static void tearDown() {
        numbers = null;
    }

    @BeforeEach
    public void runBeforeEachTest() {
        numbers.add(1);
        numbers.add(2);
        numbers.add(3);
    }

    @AfterEach
    public void runAfterEachTest() {
        numbers.clear();
    }

    @Test
    public void givenNumbers_sumEquals_thenCorrect() {
        int sum = numbers.stream().reduce(0, Integer::sum);
        assertEquals(6, sum);
    }
}
      
      



, JUnit 5. JUnit 4 @Before @After, @BeforeEach @AfterEach. , @BeforeAll @AfterAll @BeforeClass @AfterClass JUnit 4.





JUnit, TestNG . @BeforeClass @AfterClass , @BeforeMethod @AfterMethod:





@BeforeClass
public void initialize() {
    numbers = new ArrayList<>();
}

@AfterClass
public void tearDown() {
    numbers = null;
}

@BeforeMethod
public void runBeforeEachTest() {
    numbers.add(1);
    numbers.add(2);
    numbers.add(3);
}

@AfterMethod
public void runAfterEachTest() {
    numbers.clear();
}
      
      



TestNG @BeforeSuite, @AfterSuite, @BeforeGroup @AfterGroup (suite) :





@BeforeGroups("positive_tests")
public void runBeforeEachGroup() {
    numbers.add(1);
    numbers.add(2);
    numbers.add(3);
}

@AfterGroups("negative_tests")
public void runAfterEachGroup() {
    numbers.clear(); 
}
      
      



, @BeforeTest @AfterTest, - -, XML- TestNG:





<test name="test setup">
    <classes>
        <class name="SummationServiceTest">
            <methods>
                <include name="givenNumbers_sumEquals_thenCorrect" />
            </methods>
        </class>
    </classes>
</test>
      
      



, @BeforeClass @AfterClass JUnit . , TestNG .





3.

-, -. JUnit @Ignore:





@Ignore
@Test
public void givenNumbers_sumEquals_thenCorrect() {
    int sum = numbers.stream().reduce(0, Integer::sum);
    Assert.assertEquals(6, sum);
}
      
      



TestNG @Test «enabled» true



false



:





@Test(enabled=false)
public void givenNumbers_sumEquals_thenCorrect() {
    int sum = numbers.stream.reduce(0, Integer::sum);
    Assert.assertEquals(6, sum);
}
      
      



4.  

JUnit, TestNG, -.





JUnit 5 @RunWith, @SelectPackages @SelectClasses - . — -, .





- Suite @SelectPackages



:





@RunWith(JUnitPlatform.class)
@SelectPackages({ "org.baeldung.java.suite.childpackage1", "org.baeldung.java.suite.childpackage2" })
public class SelectPackagesSuiteUnitTest {

}
      
      



, , JUnit 5 @SelectClasses:





@RunWith(JUnitPlatform.class)
@SelectClasses({Class1UnitTest.class, Class2UnitTest.class})
public class SelectClassesSuiteUnitTest {

}
      
      



, JUnit 4 @Suite:





@RunWith(Suite.class)
@Suite.SuiteClasses({ RegistrationTest.class, SignInTest.class })
public class SuiteTest {

}
      
      



TestNG XML:





<suite name="suite">
    <test name="test suite">
        <classes>
            <class name="com.baeldung.RegistrationTest" />
            <class name="com.baeldung.SignInTest" />
        </classes>
    </test>
</suite>
      
      



, RegistrationTest



SignInTest



.





, TestNG @Test (groups = "groupName")



:





@Test(groups = "regression")
public void givenNegativeNumber_sumLessthanZero_thenCorrect() {
    int sum = numbers.stream().reduce(0, Integer::sum);
    Assert.assertTrue(sum < 0);
}
      
      



XML :





<test name="test groups">
    <groups>
        <run>
            <include name="regression" />
        </run>
    </groups>
    <classes>
        <class 
          name="com.baeldung.SummationServiceTest" />
    </classes>
</test>
      
      



regression.





5.

JUnit, TestNG.





, :





public class Calculator {
    public double divide(double a, double b) {
        if (b == 0) {
            throw new DivideByZeroException("Divider cannot be equal to zero!");
        }
        return a/b;
    }
}
      
      



JUnit 5 API assertThrows



:





@Test
public void whenDividerIsZero_thenDivideByZeroExceptionIsThrown() {
    Calculator calculator = new Calculator();
    assertThrows(DivideByZeroException.class, () -> calculator.divide(10, 0));
}
      
      



JUnit 4 , @Test (expected = DivideByZeroException.class



) API.





TestNG :





@Test(expectedExceptions = ArithmeticException.class) 
public void givenNumber_whenThrowsException_thenCorrect() { 
    int i = 1 / 0;
}
      
      



, .





6.

. , . , .





JUnit 5 , . JUnit 5 source-, :





  • @ValueSource



    : Short



    , Byte



    , Int



    , Long



    , Float



    , Double



    , Char



    String



    :





@ParameterizedTest
@ValueSource(strings = { "Hello", "World" })
void givenString_TestNullOrNot(String word) {
    assertNotNull(word);
}
      
      



  • @EnumSource



    Enum- :





@ParameterizedTest
@EnumSource(value = PizzaDeliveryStrategy.class, names = {"EXPRESS", "NORMAL"})
void givenEnum_TestContainsOrNot(PizzaDeliveryStrategy timeUnit) {
    assertTrue(EnumSet.of(PizzaDeliveryStrategy.EXPRESS, PizzaDeliveryStrategy.NORMAL).contains(timeUnit));
}
      
      



  • @MethodSource



    — (passes) , :





static Stream<String> wordDataProvider() {
    return Stream.of("foo", "bar");
}

@ParameterizedTest
@MethodSource("wordDataProvider")
void givenMethodSource_TestInputStream(String argument) {
    assertNotNull(argument);
}
      
      



  • @CsvSource



    CSV :





@ParameterizedTest
@CsvSource({ "1, Car", "2, House", "3, Train" })
void givenCSVSource_TestContent(int id, String word) {
	assertNotNull(id);
	assertNotNull(word);
}
      
      



, @CsvFileSource



, CSV- classpath, @ArgumentSource



, ArgumentsProvider



.





JUnit 4 @RunWith



, , @Parameter



, .





TestNG @Parameter @DataProvider. XML- @Parameter



:





@Test
@Parameters({"value", "isEven"})
public void 
  givenNumberFromXML_ifEvenCheckOK_thenCorrect(int value, boolean isEven) {
    Assert.assertEquals(isEven, value % 2 == 0);
}
      
      



XML:





<suite name="My test suite">
    <test name="numbersXML">
        <parameter name="value" value="1"/>
        <parameter name="isEven" value="false"/>
        <classes>
            <class name="baeldung.com.ParametrizedTests"/>
        </classes>
    </test>
</suite>
      
      



XML , .





@DataProvider



, .





@DataProvider



:





@DataProvider(name = "numbers")
public static Object[][] evenNumbers() {
    return new Object[][]{{1, false}, {2, true}, {4, true}};
}

@Test(dataProvider = "numbers")
public void givenNumberFromDataProvider_ifEvenCheckOK_thenCorrect
  (Integer number, boolean expected) {
    Assert.assertEquals(expected, number % 2 == 0);
}
      
      



@DataProvider



:





@Test(dataProvider = "numbersObject")
public void givenNumberObjectFromDataProvider_ifEvenCheckOK_thenCorrect
  (EvenNumber number) {
    Assert.assertEquals(number.isEven(), number.getValue() % 2 == 0);
}

@DataProvider(name = "numbersObject")
public Object[][] parameterProvider() {
    return new Object[][]{{new EvenNumber(1, false)},
      {new EvenNumber(2, true)}, {new EvenNumber(4, true)}};
}
      
      



, , . , Spring.





, TestNG, @DataProvider



, .





7. -

- , , . JUnit, TestNG -. JUnit 5 - :





@Test
public void givenExecution_takeMoreTime_thenFail() throws InterruptedException {
    Assertions.assertTimeout(Duration.ofMillis(1000), () -> Thread.sleep(10000));
}
      
      



JUnit 4 TestNG , @Test (timeout = 1000)





@Test(timeOut = 1000)
public void givenExecution_takeMoreTime_thenFail() {
    while (true);
}
      
      



8.

TestNG . , , , , , JUnit.





, , :





@Test
public void givenEmail_ifValid_thenTrue() {
    boolean valid = email.contains("@");
    Assert.assertEquals(valid, true);
}

@Test(dependsOnMethods = {"givenEmail_ifValid_thenTrue"})
public void givenValidEmail_whenLoggedIn_thenTrue() {
    LOGGER.info("Email {} valid >> logging in", email);
}
      
      



9.

JUnit 4 TestNG , . , Java Reflection API. JUnit 4, , .





, @FixMethodOrder



:





@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class SortedTests {

    @Test
    public void a_givenString_whenChangedtoInt_thenTrue() {
        assertTrue(
          Integer.valueOf("10") instanceof Integer);
    }

    @Test
    public void b_givenInt_whenChangedtoString_thenTrue() {
        assertTrue(
          String.valueOf(10) instanceof String);
    }

}
      
      



MethodSorters.NAME_ASCENDING



. , MethodSorter.DEFAULT



MethodSorter.JVM



.





TestNG . priority



() @Test:





@Test(priority = 1)
public void givenString_whenChangedToInt_thenCorrect() {
    Assert.assertTrue(
      Integer.valueOf("10") instanceof Integer);
}

@Test(priority = 2)
public void givenInt_whenChangedToString_thenCorrect() {
    Assert.assertTrue(
      String.valueOf(23) instanceof String);
}
      
      



, priority



, , .





TestNG , . dependsOnMethods



@Test, .





10.

, , IDE. JUnit 5 , @DisplayName



.





, :





@ParameterizedTest
@ValueSource(strings = { "Hello", "World" })
@DisplayName("Test Method to check that the inputs are not nullable")
void givenString_TestNullOrNot(String word) {
    assertNotNull(word);
}
      
      



, , .





TestNG .





11.

JUnit, TestNG — Java.





.





TestNG junit-5 Github.






"Java QA Automation Engineer".





« PageObject».








All Articles