Here i did a feature comparison between JUnit 4 and TestNG.

1. Annotation Support
The annotation supports are implemented in both JUnit 4 and TestNG look similar.| Feature | JUnit 4 | TestNG |
| test annotation | @Test | @Test |
| run before all tests in this suite have run | – | @BeforeSuite |
| run after all tests in this suite have run | – | @AfterSuite |
| run before the test | – | @BeforeTest |
| run after the test | – | @AfterTest |
| run before the first test method that belongs to any of these groups is invoked | – | @BeforeGroups |
| run after the last test method that belongs to any of these groups is invoked | – | @AfterGroups |
| run before the first test method in the current class is invoked | @BeforeClass | @BeforeClass |
| run after all the test methods in the current class have been run | @AfterClass | @AfterClass |
| run before each test method | @Before | @BeforeMethod |
| run after each test method | @After | @AfterMethod |
| ignore test | @ignore | @Test(enbale=false) |
| expected exception | @Test(expected = ArithmeticException.class) | @Test(expectedExceptions = ArithmeticException.class) |
| timeout | @Test(timeout = 1000) | @Test(timeout = 1000) |
1. In JUnit 4, we have to declare “@BeforeClass” and “@AfterClass” method as static method. TestNG is more flexible in method declaration, it does not have this constraints.
2. 3 additional setUp/tearDown level: suite and group (@Before/AfterSuite, @Before/AfterTest, @Before/AfterGroup). See more detail here.
JUnit 4
@BeforeClass
public static void oneTimeSetUp() {
// one-time initialization code
System.out.println("@BeforeClass - oneTimeSetUp");
}
@BeforeClass
public void oneTimeSetUp() {
// one-time initialization code
System.out.println("@BeforeClass - oneTimeSetUp");
}
2. Exception Test
The “exception testing” means what exception throw from the unit test, this feature are implemented in both JUnit 4 and TestNG.JUnit 4
@Test(expected = ArithmeticException.class) public void divisionWithException() { int i = 1/0; }
@Test(expectedExceptions = ArithmeticException.class) public void divisionWithException() { int i = 1/0; }
3. Ignore Test
The “Ignored” means whether it should ignore the unit test, this feature are implemented in both JUnit 4 and TestNG .JUnit 4
@Ignore("Not Ready to Run") @Test public void divisionWithException() { System.out.println("Method is not ready yet"); }
@Test(enabled=false) public void divisionWithException() { System.out.println("Method is not ready yet"); }
4. Time Test
The “Time Test” means if an unit test takes longer than the specified number of milliseconds to run, the test will terminated and mark as fails, this feature is implemented in both JUnit 4 and TestNG .JUnit 4
@Test(timeout = 1000) public void infinity() { while (true); }
@Test(timeOut = 1000) public void infinity() { while (true); }
5. Suite Test
The “Suite Test” means bundle a few unit test and run it together. This feature is implemented in both JUnit 4 and TestNG. However both are using very different method to implement it.JUnit 4
The “@RunWith” and “@Suite” are use to run the suite test. The below class means both unit test “JunitTest1” and “JunitTest2” run together after JunitTest5 executed. All the declaration is define inside the class.
@RunWith(Suite.class) @Suite.SuiteClasses({ JunitTest1.class, JunitTest2.class }) public class JunitTest5 { }
XML file is use to run the suite test. The below XML file means both unit test “TestNGTest1” and “TestNGTest2” will run it together.
<!DOCTYPE suite SYSTEM "http://beust.com/testng/testng-1.0.dtd" > <suite name="My test suite"> <test name="testing"> <classes> <class name="com.fsecure.demo.testng.TestNGTest1" /> <class name="com.fsecure.demo.testng.TestNGTest2" /> </classes> </test> </suite>
Here is a class with four methods, three groups (method1, method2 and method3)
@Test(groups="method1") public void testingMethod1() { System.out.println("Method - testingMethod1()"); } @Test(groups="method2") public void testingMethod2() { System.out.println("Method - testingMethod2()"); } @Test(groups="method1") public void testingMethod1_1() { System.out.println("Method - testingMethod1_1()"); } @Test(groups="method4") public void testingMethod4() { System.out.println("Method - testingMethod4()"); }
<!DOCTYPE suite SYSTEM "http://beust.com/testng/testng-1.0.dtd" > <suite name="My test suite"> <test name="testing"> <groups> <run> <include name="method1"/> </run> </groups> <classes> <class name="com.fsecure.demo.testng.TestNGTest5_2_0" /> </classes> </test> </suite>
6. Parameterized Test
The “Parameterized Test” means vary parameter value for unit test. This feature is implemented in both JUnit 4 and TestNG. However both are using very different method to implement it.JUnit 4
The “@RunWith” and “@Parameter” is use to provide parameter value for unit test, @Parameters have to return List[], and the parameter will pass into class constructor as argument.
@RunWith(value = Parameterized.class) public class JunitTest6 { private int number; public JunitTest6(int number) { this.number = number; } @Parameters public static Collection<Object[]> data() { Object[][] data = new Object[][] { { 1 }, { 2 }, { 3 }, { 4 } }; return Arrays.asList(data); } @Test public void pushTest() { System.out.println("Parameterized Number is : " + number); } }
TestNG
XML file or “@DataProvider” is use to provide vary parameter for testing.
XML file for parameterized test.
Only “@Parameters” declares in method which needs parameter for testing, the parametric data will provide in TestNG’s XML configuration files. By doing this, we can reuse a single test case with different data sets and even get different results. In addition, even end user, QA or QE can provide their own data in XML file for testing.
Unit Test
public class TestNGTest6_1_0 { @Test @Parameters(value="number") public void parameterIntTest(int number) { System.out.println("Parameterized Number is : " + number); } }
<!DOCTYPE suite SYSTEM "http://beust.com/testng/testng-1.0.dtd" > <suite name="My test suite"> <test name="testing"> <parameter name="number" value="2"/> <classes> <class name="com.fsecure.demo.testng.TestNGTest6_0" /> </classes> </test> </suite>
While pulling data values into an XML file can be quite handy, tests occasionally require complex types, which can’t be represented as a String or a primitive value. TestNG handles this scenario with its @DataProvider annotation, which facilitates the mapping of complex parameter types to a test method.
@DataProvider for Vector, String or Integer as parameter
@Test(dataProvider = "Data-Provider-Function") public void parameterIntTest(Class clzz, String[] number) { System.out.println("Parameterized Number is : " + number[0]); System.out.println("Parameterized Number is : " + number[1]); } //This function will provide the patameter data @DataProvider(name = "Data-Provider-Function") public Object[][] parameterIntTestProvider() { return new Object[][]{ {Vector.class, new String[] {"java.util.AbstractList", "java.util.AbstractCollection"}}, {String.class, new String[] {"1", "2"}}, {Integer.class, new String[] {"1", "2"}} }; }
P.S “TestNGTest6_3_0” is an simple object with just get set method for demo.
@Test(dataProvider = "Data-Provider-Function") public void parameterIntTest(TestNGTest6_3_0 clzz) { System.out.println("Parameterized Number is : " + clzz.getMsg()); System.out.println("Parameterized Number is : " + clzz.getNumber()); } //This function will provide the patameter data @DataProvider(name = "Data-Provider-Function") public Object[][] parameterIntTestProvider() { TestNGTest6_3_0 obj = new TestNGTest6_3_0(); obj.setMsg("Hello"); obj.setNumber(123); return new Object[][]{ {obj} }; }
7. Dependency Test
The “Parameterized Test” means methods are test base on dependency, which will execute before a desired method. If the dependent method fails, then all subsequent tests will be skipped, not marked as failed.JUnit 4
JUnit framework is focus on test isolation; it did not support this feature at the moment.
TestNG
It use “dependOnMethods “ to implement the dependency testing as following
@Test public void method1() { System.out.println("This is method 1"); } @Test(dependsOnMethods={"method1"}) public void method2() { System.out.println("This is method 2"); }



0 Comments