Unit testing is a very important thing in applications. By testing your class you can prove that your code is free of most bugs and complies with the specification (you can’t remove all bugs, but can make your code harder to crash).
Java offers two most popular testing frameworks for unit testing: JUnit and TestNG. I will try to compare both frameworks (TestNG 6.0.1 and JUnit 4.9b2).
The basic test in JUnit checking whether 1 == 1 will be looking something like:
import static junit.framework.Assert.assertEquals; import org.junit.Test; public class JUnitTest { @Test public void test1() { assertEquals(1, 1); } }
And in TestNG:
import static org.testng.Assert.assertEquals; import org.testng.annotations.Test; public class TestNGTest { @Test public void test1() { assertEquals(1, 1); } }
Someone would ask: Why we are thinking about which framework to choose if they both look the same? The same annotation driven tests and names of methods?
The answer is very simple. The advanced options of both frameworks. JUnit provides only simple annotations and simple functionalities. TestNG has everything that JUnit plus lots of simplifying life features.
Check out JUnit set of most important method annotations:
@Test – contains the test – you can specify timeout and expected exception,
@Before – executes before all test-methods,
@After – executes after all test-methods,
@AfterClass – executes after all tests,
@BeforeClass – executes before all tests.
As you see, JUnit has very simple functionality.
——-
How it will be when comparing to TestNG? See the annotations:
@Test – contains the test as it was in JUnit. But look on the params: alwaysRun, dataProvider, dataProviderClass, dependsOnGroups, dependsOnMethods, description, enabled, expectedExceptions, groups, invocationCount, invocationTimeOut, priority, successPercentage, singleThreaded, timeOut, threadPoolSize. Here we can specify a way more things. Params are intuitive, so I will show basic usage on the example.
@DataProvider – indicates that this method will provide data for another test method.
@BeforeGroups – executes before groups of methods,
@AfterGroups – executes after groups of methods,
@BeforeClass – executes before all tests,
@AfterClass – executes after all tests,
@BeforeMethod – executes before test-method,
@AfterMethod – executes after test-method.
Annotations above has following params: alwaysRun, dependsOnGroups, dependsOnMethods, enabled, groups, inheritGroups.
Leave alone JUnit. Lets write some code in TestNG framework:
import static org.testng.Assert.assertEquals; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; public class TestNGTest { private int i = 20; @Test(dependsOnMethods = { "throwExceptionWithMessage" }) public void dependsOnMethodTest() { assertEquals(30, i); } @Test public void basicEquals() { assertEquals(1, 1); } private final static String PROVIDER_NAME = "PROVIDER_NAME"; @DataProvider(name = PROVIDER_NAME) public Object[][] dataProvider() { return new Object[][] { { 1, 2 }, { 3, 4 }, { 5, 7 }, { 8, 9 } }; } @Test(dataProvider = PROVIDER_NAME, successPercentage = 75) public void providerTest(int a, int b) { assertEquals(a, b - 1); } @Test(expectedExceptions = Exception.class, expectedExceptionsMessageRegExp = "^.*bare.*$") public void throwExceptionWithMessage() throws Exception { i = 30; throw new Exception("very bad exception, just can't bare it"); } }
Result:
PASSED: throwExceptionWithMessage PASSED: dependsOnMethodTest PASSED: providerTest(1, 2) PASSED: providerTest(3, 4) PASSED: providerTest(8, 9) PASSED: basicEquals =============================================== Default test Tests run: 7, Failures: 0, Skips: 0 ===============================================
Here you see things you can’t do in JUnit. JUnit was designed only to do simple unit testing. TestNG provides lots of advanced, but very simple to learn features.
To sum up, JUnit could be used in very simple projects which doesn’t have to use advanced features. But when it comes to do something above that, you should choose TestNG (now my favourite unit testing framework).