原文出处: 付学良的网志

原文出处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

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 与 TestNG 对比的更多相关文章

  1. JUnit 4 Vs TestNG比较

    JUnit 4和TestNG都是Java中非常受欢迎的单元测试框架.两种框架在功能上看起来非常相似. 哪一个更好? 在Java项目中应该使用哪个单元测试框架? 下面表中概括了JUnit 4和TestN ...

  2. JUnit 4 和 TestNG

    JUnit 4和TestNG都是Java中非常受欢迎的单元测试框架.两种框架在功能上看起来非常相似.哪一个更好?在Java项目中应该使用哪个单元测试框架? 下面表中概括了JUnit 4和TestNG之 ...

  3. 关于testNG和JUnit的对比

    关于选择JUnit还是选testNG,这几篇文章,建议读一读: API参考文档: Junit API文档:http://junit.org/junit4/javadoc/latest/index.ht ...

  4. 单元测试——测试神器,testng

    为什么用它 建议使用 TestNG 作为 Java 项目的主要单元测试框架,因为 TestNG 在参数化测试.依赖测试以及套件测试(组)方面功能更加强大.TestNG 意味着高级的测试和复杂的集成测试 ...

  5. testNg vs junit 4.X @Test

    http://www.ibm.com/developerworks/cn/java/j-cq08296/ 一个简单的测试用例 初看起来,JUnit 4 和 TestNG 中实现的测试非常相似.为了更好 ...

  6. testng入门教程11 TestNG运行JUnit测试

    现在,您已经了解了TestNG和它的各种测试,如果现在担心如何重构现有的JUnit代码,那就没有必要,使用TestNG提供了一种方法,从JUnit和TestNG按照自己的节奏.也可以使用TestNG执 ...

  7. 在Eclipse中开发使用Spring IOC的JUnit/TestNG测试用例之详解

    转载自:http://blog.csdn.net/radic_feng/article/details/6740438 我们期望能像在产品代码中一样,在测试用例中使用的bean也由Spring Con ...

  8. Java Unit Testing - JUnit & TestNG

    转自https://www3.ntu.edu.sg/home/ehchua/programming/java/JavaUnitTesting.html yet another insignifican ...

  9. 单元测试利器 JUnit 4

    引言 毋庸置疑,程序员要对自己编写的代码负责,您不仅要保证它能通过编译,正常地运行,而且要满足需求和设计预期的效果.单元测试正是验证代码行为是否满足预期的有效手段之一.但不可否认,做测试是件很枯燥无趣 ...

随机推荐

  1. 实验:Oracle直接拷贝物理存储文件迁移

    实验目的:Oracle直接拷贝物理文件迁移,生产库有类似施工需求,故在实验环境简单验证一下. 实验环境: A主机:192.168.1.200 Solaris10 + Oracle 11.2.0.1 B ...

  2. 使用session页面控制登录入口及购物车效果的实现

          由于 Session 是以文本文件形式存储在服务器端的,所以不怕客户端修改 Session 内容.实际上在服务器端的 Session 文件,PHP 自动修改 Session 文件的权限,只 ...

  3. 用Crontab打造简易工作流引擎

    1. 引言 众所周知,Oozie(1, 2)是基于时间条件与数据生成来做工作流调度的,但是Oozie的数据触发条件只支持HDFS路径,故而面临着这样的问题: 无法判断Hive partition是否已 ...

  4. HTML5 网络拓扑图性能优化

    HTML5 中的 Canvas 对文本的渲染(fillText,strokeText)性能都不太好,比如设置字体(font).文本旋转(rotation),如果绘制较多的文本时,一些交互操作会手动很大 ...

  5. web 开发自动化grunt

    现在web开发自动化已很流行,如何进行压缩文件,如何进行测试js是否正确,如何进行 检测html文件是否规范等等都可以通过web自动化技术进行实现,只要打一个命令即可. 本文主要是通过grunt进行实 ...

  6. js实现蛇形矩阵

    参加腾讯前端实习生笔试,真的是被虐了千百遍,除了一条js程序题,其他半点前端都没有,都是考算法,计算机原理,数据结构.下面贴上腾讯笔试最后三大条中的一条,实现一个蛇形矩阵的输出.蛇形矩阵的什么样这里我 ...

  7. WinServer2008R2 + IIS 7.5 + .NET4.0 经典模式 运行WebAPI程序报404错误的解决方案

    在Windows Server 2008 R2系统下,IIS 7.5 + .NET Framework 4.0的运行环境,以经典模式(Classic Mode)部署一个用.NET 4.0编译的 Web ...

  8. 分金币 bzoj 3293

    分金币(1s 128M)  coin [问题描述] 圆桌上坐着n个人,每人有一定数量的金币,金币总数能被n整除.每个人可以给他左右相邻的人一些金币,最终使得每个人的金币数目相等.你的任务是求出被转手的 ...

  9. stm32新建工程详细步骤

    记得好早以前为了建一个keil的工程折腾了好久,在这里写写基本的Keil工程创建方法,以防自己以后再忘记: 新建工程 保存工程 选择器件 在这边新建文件夹,然后就是添加程序代码到里面去了.其中一些文件 ...

  10. axis2+spring集成

    转载自:http://www.cnblogs.com/linjiqin/archive/2011/07/05/2098316.html 1.新建一个web project项目,最终工程目录如下: 注意 ...