JUnit 4 与 TestNG 对比
原文出处: 付学良的网志
原文出处2: http://www.importnew.com/16270.html
————————————————————————————————————————————
Junit 4 和 TestNG 都是 Java 方面非常流行的单元测试框架。在功能上两个框架都非常类似。到底哪个比较好?在Java项目中我们应该选择哪个框架?
下图将会对Junit 4 和 TestNG 做个功能特征的对比。

注解支持
Junit 4 和 TestNG 在注解方面的实现非常相似。
|
特性 |
JUnit 4 |
TestNG |
|
测试注解 |
@Test |
@Test |
|
测试套件在执行之前需要执行的 |
– |
@BeforeSuite |
|
测试套件在执行之后需要执行的 |
– |
@AfterSuite |
|
在测试之前需要执行的 |
– |
@BeforeTest |
|
在测试之后需要执行的 |
– |
@AfterTest |
|
在一个测试方法所属于的任意一个组的第一个方法被调用之前执行 |
– |
@BeforeGroups |
|
在一个测试方法所属于的任意一个组的最后一个方法被调用之后执行 |
– |
@AfterGroups |
|
在当前类的第一个测试方法调用之前执行 |
@BeforeClass |
@BeforeClass |
|
在当前类的最后一个测试方法调用之后执行 |
@AfterClass |
@AfterClass |
|
每个测试方法之前需要执行 |
@Before |
@BeforeMethod |
|
每个测试方法之后需要执行 |
@After |
@AfterMethod |
|
忽略 |
@ignore |
@Test(enbale=false) |
|
预期异常 |
@Test(expected = ArithmeticException.class) |
@Test(expectedExceptions = ArithmeticException.class) |
|
超时 |
@Test(timeout = 1000) |
@Test(timeout = 1000) |
JUnit 4 和 TestNG 之间注解方面的区别主要有以下几点:
1. 在Junit 4 中,如果我们需要在方法前面使用@BeforeClass和@AfterClass,那么该测试方法则必须是静态方法。TestNG 在方法定义部分则更加的灵活,它不需要类似的约束。
2. 3个附加的setUp/tearDown级别:套件和分组(@Before/AfterSuite, @Before/AfterTest, @Before/AfterGroup)。想了解详细的请看这里
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"); } |
在Junit 4中,注解的命名是比较令人困惑的,例如 Before, After and Expected,我们不是很确切的能理解在方法前面有Before和After这样的注解是做什么的,同样Expected也如此。TestNG在这方面做的就好很多,注解使用了BeforeMethod,AfterMethod和ExpectedException,这样的名字就非常好理解了。
异常测试
异常测试的意思是在单元测试中应该抛出什么异常是合理的,这个特性在两个框架都已经实现。
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; } |
忽略测试
忽略测试意思是在单元测试哪些是可以被忽略的,这个特性在两个框架都已经实现。
JUnit 4
|
1 2 3 4 5 |
@Ignore("Not Ready to Run") @Test public void divisionWithException() { System.out.println("Method is not ready yet"); } |
TestNG
|
1 2 3 4 |
@Test(enabled=false) public void divisionWithException() { System.out.println("Method is not ready yet"); } |
时间测试
时间测试意思是如果一个单元测试运行的时间超过了一个指定的毫秒数,那么测试将终止并且标记为失败的测试,这个特性在两个框架都已经实现。
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); } |
套件测试
套件测试就是把几个单元测试组合成一个模块,然后运行,这个特性两个框架均已实现。然而却是用了两个不同的方式来实现的。
JUnit 4
@RunWith 和 @Suite注解被用于执行套件测试。下面的代码是所展示的是在JunitTest5被执行之后需要JunitTest1 和 JunitTest2也一起执行。所有的声明需要在类内部完成。
|
1 2 3 4 5 6 7 |
@RunWith(Suite.class) @Suite.SuiteClasses({ JunitTest1.class, JunitTest2.class }) public class JunitTest5 { } |
TestNG
执行套件测试是使用XML文件配置的方式来做。下面的 XML 的文件可以使得TestNGTest1和TestNGTest2一起执行。
|
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可以在这块做的更好,使用了组的概念,每个方法都可以被分配到一个组里面,可以根据功能特性来分组。例如:
这是一个有4个方法,3个组(method1, method2 和 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()"); } |
下面XML文件定义了一个只是执行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> |
使用分组的概念,集成测试就会更加强大。例如,我们可以只是执行所有测试中的组名为DatabaseFuntion的测试。
参数化测试
参数化测试意思是给单元测试传多个参数值。这个特性在JUnit 4 和TestNG。然后两个框架实现的方式却完全不同。
JUnit 4
@RunWith 和 @Parameter 注解用于为单元测试提供参数值,@Parameters必须返回 List,参数将会被作为参数传给类的构造函数。
|
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); } } |
它在使用上有许多的限制;我们必须遵循 JUnit 的方式去声明参数,参数必须通过构造函数的参数去初始化类的成员来用于测试。返回的参数类型必须是List [],数据已经被限定为String或者是一个原始值。
TestNG
使用XML文件或者@DataProvider注解来给测试提供参数。
XML文件配置参数化测试
只是在方法上声明@Parameters注解,参数的数据将由 TestNG 的 XML 配置文件提供。这样做之后,我们可以使用不同的数据集甚至是不同的结果集来重用一个测试用例。另外,甚至是最终用户,QA 或者 QE 可以提供使用 XML 文件来提供他们自己的数据来做测试。
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 文件
|
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> |
@DataProvider 注解做参数化测试
使用XML文件初始化数据可以很方便,但是测试偶尔需要复杂的类型,一个String或原始值并不能完全满足。 TestNG 的@ DataProvider的注解,可以更好的把复杂的参数类型映射到一个测试方法来处理这种情况。
@DataProvider 可以使用 Vector, String 或者 Integer 类型的值作为参数
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
@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"}} }; } |
@DataProvider 作为对象的参数
P.S “TestNGTest6_3_0” 是一个简单的对象,使用了get和set方法。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
@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} }; } |
TestNG的参数化测试使用起来非常的友好和灵活 (不管是XML配置还是在类里面注解的方式). 它可以使用许多复杂的数据类型作为参数的值,并且没有什么限制。如上面的例子所示, we even can pass in our own object (TestNGTest6_3_0) for parameterized test
依赖测试
参数化测试意味着测试的方法是有依赖的,也就是要执行的的方法在执行之前需要执行的部分。如果依赖的方法出现错误,所有的子测试都会被忽略,不会被标记为失败。
JUnit 4
JUnit 框架主要聚焦于测试的隔离,暂时还不支持这个特性。
TestNG
它使用dependOnMethods来实现了依赖测试的功能,如下:
|
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"); } |
如果method1()成功执行,那么method2()也将被执行,否则method2()将会被忽略。
讨论总结
当我们做完所有特性的对比以后,我建议使用 TestNG 作为 Java 项目的主要单元测试框架,因为 TestNG 在参数化测试、依赖测试以及套件测试(组)方面功能更加强大。TestNG 意味着高级的测试和复杂的集成测试。它更加的灵活,特别是对大的套件测试。另外,TestNG 也涵盖了 JUnit4 的全部功能。那就没有任何理由使用 Junit了。
参考资料
TestNG
————
http://en.wikipedia.org/wiki/TestNG
http://www.ibm.com/developerworks/java/library/j-testng/
http://testng.org/doc/index.html
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 与 TestNG 对比的更多相关文章
- JUnit 4 Vs TestNG比较
JUnit 4和TestNG都是Java中非常受欢迎的单元测试框架.两种框架在功能上看起来非常相似. 哪一个更好? 在Java项目中应该使用哪个单元测试框架? 下面表中概括了JUnit 4和TestN ...
- JUnit 4 和 TestNG
JUnit 4和TestNG都是Java中非常受欢迎的单元测试框架.两种框架在功能上看起来非常相似.哪一个更好?在Java项目中应该使用哪个单元测试框架? 下面表中概括了JUnit 4和TestNG之 ...
- 关于testNG和JUnit的对比
关于选择JUnit还是选testNG,这几篇文章,建议读一读: API参考文档: Junit API文档:http://junit.org/junit4/javadoc/latest/index.ht ...
- 单元测试——测试神器,testng
为什么用它 建议使用 TestNG 作为 Java 项目的主要单元测试框架,因为 TestNG 在参数化测试.依赖测试以及套件测试(组)方面功能更加强大.TestNG 意味着高级的测试和复杂的集成测试 ...
- testNg vs junit 4.X @Test
http://www.ibm.com/developerworks/cn/java/j-cq08296/ 一个简单的测试用例 初看起来,JUnit 4 和 TestNG 中实现的测试非常相似.为了更好 ...
- testng入门教程11 TestNG运行JUnit测试
现在,您已经了解了TestNG和它的各种测试,如果现在担心如何重构现有的JUnit代码,那就没有必要,使用TestNG提供了一种方法,从JUnit和TestNG按照自己的节奏.也可以使用TestNG执 ...
- 在Eclipse中开发使用Spring IOC的JUnit/TestNG测试用例之详解
转载自:http://blog.csdn.net/radic_feng/article/details/6740438 我们期望能像在产品代码中一样,在测试用例中使用的bean也由Spring Con ...
- Java Unit Testing - JUnit & TestNG
转自https://www3.ntu.edu.sg/home/ehchua/programming/java/JavaUnitTesting.html yet another insignifican ...
- 单元测试利器 JUnit 4
引言 毋庸置疑,程序员要对自己编写的代码负责,您不仅要保证它能通过编译,正常地运行,而且要满足需求和设计预期的效果.单元测试正是验证代码行为是否满足预期的有效手段之一.但不可否认,做测试是件很枯燥无趣 ...
随机推荐
- WebGIS中基于控制点库进行SHP数据坐标转换的一种查询优化策略
文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.前言 目前项目中基于控制点库进行SHP数据的坐标转换,流程大致为:遍 ...
- 你真的会玩SQL吗?和平大使 内连接、外连接
你真的会玩SQL吗?系列目录 你真的会玩SQL吗?之逻辑查询处理阶段 你真的会玩SQL吗?和平大使 内连接.外连接 你真的会玩SQL吗?三范式.数据完整性 你真的会玩SQL吗?查询指定节点及其所有父节 ...
- [占位-未完成]scikit-learn一般实例之十一:异构数据源的特征联合
[占位-未完成]scikit-learn一般实例之十一:异构数据源的特征联合 Datasets can often contain components of that require differe ...
- Devexpress Ribbon Add Logo
一直在网上找类似的效果.在Devpexress控件里面的这个是一个Demo的.没法查看源代码.也不知道怎么写的.所以就在网上搜索了半天的. 终于找到类似的解决办法. 可以使用重绘制的办法的来解决. [ ...
- spider RPC框架的需求来源与特性介绍(一)
spider RPC 特性介绍 spider RPC 性能测试 spider RPC 入门指南 spider RPC 配置文件参考 spider RPC 开发指南 spider RPC 安全性 spi ...
- Hibernate(二)__简单实例入门
首先我们进一步理解什么是对象关系映射模型? 它将对数据库中数据的处理转化为对对象的处理.如下图所示: 入门简单实例: hiberante 可以用在 j2se 项目,也可以用在 j2ee (web项目中 ...
- transformjs玩转星球
如你所见.这篇就是要讲下使用transformjs制作星球的过程.你也可以无视文章,直接去看源码和在线演示: 源码 | 在线演示 代码100行多一点,直接看也没有什么压力.下面分几步讲解下. 生成球上 ...
- 深入理解DOM节点类型第二篇——文本节点Text
× 目录 [1]特征 [2]空白 [3]属性[4]方法[5]性能 前面的话 文本节点顾名思义指向文本的节点,网页上看到的文字内容都属于文本节点.该节点简单直观,本文将详细介绍该部分内容 特征 文本节点 ...
- javascript代码 调试方法
你的代码可能包含语法错误,逻辑错误,如果没有调试工具,这些错误比较难于发现. 通常,如果 JavaScript 出现错误,是不会有提示信息,这样你就无法找到代码错误的位置. 在程序代码中寻找错误叫做代 ...
- Microsoft Dynamics CRM 2013 Js Odata 查询
实现功能: 在新建记录时,(大区,省区,城市)的值默认为当前用户的值.tips:字段均为lookup类型; function Default_region(){ var fromtype=Xrm. ...