Source: Cong Collan's Blog
Original source 2:http://www.importnew.com/16270.html
————————————————————————————————————————————
Junit 4 and TestNG are very popular unit test frameworks in Java. The two frames are very similar in function. Which is better? Which framework should we choose in the Java project?
A comparison of the functional characteristics of JUnit 4 and TestNG will be made.
Annotation support
The implementation of Junit 4 and TestNG in annotations is very similar.
Characteristics |
JUnit 4 |
Testng |
Test notes |
@Test |
@Test |
The test suite needs to be executed before executing the |
– |
@BeforeSuite |
The test suite needs to be executed after execution. |
– |
@AfterSuite |
What you need to do before you test |
– |
@BeforeTest |
What you need to do after the test |
– |
@AfterTest |
Executed before the first method of any one of the groups to which a test method belongs is called |
– |
@BeforeGroups |
Executes after the last method of any group to which a test method belongs is called |
– |
@AfterGroups |
Executes before the first test method call of the current class |
@BeforeClass |
@BeforeClass |
Executes after the last test method call of the current class |
@AfterClass |
@AfterClass |
Each test method needs to be executed before |
@Before |
@BeforeMethod |
After each test method, you need to perform |
@After |
@AfterMethod |
Ignore |
@ignore |
@Test (Enbale=false) |
Expected exception |
@Test (expected = arithmeticexception.class) |
@Test (expectedexceptions = arithmeticexception.class) |
Timeout |
@Test (timeout = 1000) |
@Test (timeout = 1000) |
The differences between the annotations between JUnit 4 and TestNG are mainly as follows:
1. In JUnit 4, if we need to use @beforeclass and @afterclass in front of the method, then the test method must be a static method. TestNG is more flexible in the method definition section, which does not require a similar constraint.
2.3 additional Setup/teardown levels: Kit and grouping (@Before/aftersuite, @Before/aftertest, @Before/aftergroup). To find out more, see here.
JUnit 4
1 2 3 4 5 |
@BeforeClass public static void Onetimesetup () { One-time initialization code System.out.println ("@BeforeClass-onetimesetup"); } |
Testng
1 2 3 4 5 |
@BeforeClass public void Onetimesetup () { One-time initialization code System.out.println ("@BeforeClass-onetimesetup"); } |
In JUnit 4, the naming of annotations is confusing, for example, before, after and expected, we are not quite sure what the annotations in front of the method before and after are doing, as well as expected. TestNG is doing a lot better in this respect, the annotations use Beforemethod,aftermethod and ExpectedException, and the name is very well understood.
Anomaly Testing
The exception test means that it is reasonable to throw any exception in the unit test, which has been implemented in two frameworks.
JUnit 4
1 2 3 4 |
@Test (expected = arithmeticexception.class) public void Divisionwithexception () { int i = 1/0; } |
Testng
1 2 3 4 |
@Test (expectedexceptions = arithmeticexception.class) public void Divisionwithexception () { int i = 1/0; } |
Ignore test
Ignoring the test means that in the unit test which can be ignored, this feature has been implemented in two frameworks.
JUnit 4
1 2 3 4 5 |
@Ignore ("Not Ready to Run") @Test public void Divisionwithexception () { System.out.println ("Method is not a ready yet"); } |
Testng
1 2 3 4 |
@Test (Enabled=false) public void Divisionwithexception () { System.out.println ("Method is not a ready yet"); } |
Time Test
The time test means that if a unit test runs longer than a specified number of milliseconds, the test terminates and marks the test as failed, and this feature has been implemented in two frameworks.
JUnit 4
1 2 3 4 |
@Test (timeout = 1000) public void infinity () { while (true); } |
Testng
1 2 3 4 |
@Test (timeOut = 1000) public void infinity () { while (true); } |
Kit Testing
Suite testing is the combination of several unit tests into a single module, and then run, this feature two frames have been implemented. However, it was implemented in two different ways.
JUnit 4
@RunWith and @Suite annotations are used to perform suite tests. The following code shows that the JUNITTEST5 is executed after the JunitTest1 and JunitTest2 are executed. All declarations need to be done inside the class.
1 2 3 4 5 6 7 |
@RunWith (Suite.class) @Suite. suiteclasses ({ Junittest1.class, Junittest2.class }) public class JunitTest5 { } |
Testng
The execution Suite test is done in a way that uses the XML file configuration. The following XML file can be used to make TestNGTest1 and TestNGTest2 execute together.
1 2 3 4 5 6 7 8 9 |
<! 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> |
TestNG can do better in this block, using the concept of a group, each method can be assigned to a group, can be grouped according to functional characteristics. For example:
This is a class with 4 methods, 3 groups (METHOD1, METHOD2, and METHOD4)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
@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 ()"); } |
The following XML file defines a unit test for a group that simply executes methed1
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<! 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> |
With the concept of grouping, integration testing is more powerful. For example, we can just perform tests in which the group named Databasefuntion is in all tests.
Parametric testing
Parametric testing means that multiple parameter values are passed to the unit test. This feature is in JUnit 4 and testng. The two frameworks are then implemented in a completely different way.
JUnit 4
@RunWith and @Parameter annotations are used to provide parameter values for unit tests, @Parameters must return a List, and parameters will be passed to the constructor of the class as arguments.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
@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); } } |
It has a number of restrictions on its use, and we have to follow JUnit's approach to declaring parameters, which must be used for testing by initializing the members of the class through the parameters of the constructor. The parameter type that is returned must be list [], and the data is already qualified as a string or as a raw value.
Testng
Use an XML file or @dataprovider annotations to provide parameters for the test.
parameterized test of XML file configuration
Just declare the @parameters annotation on the method, and the data for the parameter will be provided by the TestNG XML configuration file. After doing this, we can reuse a test case using a different dataset or even a different result set. In addition, even end-users, QA or QE can provide their own data for testing using XML files.
Unit Test
1 2 3 4 5 6 7 8 9 |
public class Testngtest6_1_0 { @Test @Parameters (value= "number") public void Parameterinttest (int number) { SYSTEM.OUT.PRINTLN ("Parameterized number is:" + number); } } |
XML file
1 2 3 4 5 6 7 8 9 10 11 |
<! 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> |
Parametric testing of @DataProvider annotations
Initializing data with an XML file can be handy, but testing occasionally requires complex types, and a string or raw value is not fully satisfied. TestNG's @ dataprovider annotations can better map complex parameter types to a test method to handle this situation.
@DataProvider can use a Vector, String, or Integer value as a parameter
1 2 3 4 5 6 7 8 9 13 |
@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 would 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"}} }; } |
@DataProvider as an argument to an object
P.S "Testngtest6_3_0" is a simple object that uses the get and set methods.
@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 would 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}
};
}
1 2 3 4 5 6 7 8 9 12 + |
+ + - | width= "585" >
TestNG's parametric testing is very user-friendly and flexible (whether it's an XML configuration or a way to annotate within a class). It can use many complex data types as the values of the parameters, and there are no restrictions. As shown in the example above, we even can pass in our own object (TESTNGTEST6_3_0) for parameterized test
Dependency Testing
Parametric testing means that the method of testing is dependent, that is, the part of the method to be executed before execution. If an error occurs on a dependent method, all child tests are ignored and are not marked as failed.
JUnit 4
The JUnit framework focuses primarily on testing isolation and does not support this feature for the time being.
Testng
It uses Dependonmethods to implement the functionality of the dependent tests, as follows:
1 2 3 4 5 6 7 8 9 |
@Test public void Method1 () { System.out.println ("This is Method 1"); } @Test (dependsonmethods={"Method1"}) public void Method2 () { System.out.println ("This is Method 2"); } |
If METHOD1 () executes successfully, then METHOD2 () will also be executed, otherwise method2 () will be ignored.
Discussion Summary
After we have done the comparison of all the features, I recommend using TestNG as the main unit test framework for the Java project because TestNG is more powerful in parametric testing, dependent testing, and suite testing (groups). TestNG means advanced testing and complex integration testing. It is more flexible, especially for large suite tests. In addition, the TestNG also covers all functions of the JUNIT4. There's no reason to use JUnit.
Resources
Testng
————
Http://en.wikipedia.org/wiki/TestNG
http://www.ibm.com/developerworks/java/library/j-testng/
Http://testng.org/doc/index.html
http://beust.com/weblog/
Junit
———–
Http://en.wikipedia.org/wiki/JUnit
Http://www.ibm.com/developerworks/java/library/j-junit4.html
Http://junit.sourceforge.net/doc/faq/faq.htm
Http://www.devx.com/Java/Article/31983/0/page/3
http://ourcraft.wordpress.com/2008/08/27/writing-a-parameterized-junit-test/
TestNG VS JUnit
——————
Http://docs.codehaus.org/display/XPR/Migration+to+JUnit4+or+TestNG
Http://www.ibm.com/developerworks/java/library/j-cq08296/index.html
http://www.cavdar.net/2008/07/21/junit-4-in-60-seconds/
JUnit 4 vs. TestNG