前言
本文翻译自:TestNG Vs JUnit: What's the Difference?
本文重点分析Junit和TestNG的特点。这些特点可以帮助开发者在进行开发单元测试时使用哪个框架。 TestNG和Junit都是用于单元测试的测试框架。由于TestNG是受Junit和Nunit启发而开发的测试框架, 因此二者很相似。与Junit相比,TestNG增加了部分功能。这部分功能让TestNG比Junit更加强大。
异同点
首先分析TestNG和Junit4之间的相同点。以下表格分别说明了Junit和TestNG所支持的特性。通过该表格可以对二者进行快速比较,有助于我们快速确定哪种技术更适合单元测试。
对比项 | Junit4 | TestNg |
---|---|---|
注解 | 支持 | 支持 |
套件测试 | 支持 | 支持 |
忽略测试 | 支持 | 支持 |
异常测试 | 支持 | 支持 |
超时处理 | 支持 | 支持 |
忽略测试 | 支持 | 支持 |
参数化测试 | 支持 | 支持 |
依赖测试 | 不支持 | 支持 |
从上表可以看到,TestNg与Junit一两个特性不一样之外,其他都一样。 |
注解
Junit和TestNG都是支持注解,并且二者的注解名称看起来很相似。比如:TestNG使用注解 @BeforeMethod
,@AfterMethod
而Junit中使用@Before
, @After
。而对于超时注解,二者都是用@Test(timeout=1000)
。以下表格提供了更多详细信息。
序号 | 说明 | TestNg | Junit4 |
---|---|---|---|
1 | 测试注解 | @Test | @Test |
2 | 单元测试类中第一个测试方法执行前需要执行的逻辑 | @BeforeClass | @BeforeClass |
3 | 单元测试类所有测试方法执行后需要执行的逻辑 | @AfterClass | @AfterClass |
4 | 每个测试方法执行前需要执行的逻辑 | @BeforeMethod | @Before |
5 | 每个测试方法执行后需要执行的逻辑 | @AfterMethod | @After |
6 | 用于忽略测试的注解 | @Test(enable=false) | @Ignore |
7 | 用于异常的注解 | @Test(expectedExceptions = ArithmeticException.class) | @Test(expected = ArithmeticException.class) |
8 | 超时注解 | @Test(timeout = 1000) | @Test(timeout = 1000) |
9 | 在所有测试套件中的测试之前执行的逻辑 | @BeforeSuite | 无 |
10 | 在所有测试套件中的测试之后执行的逻辑 | @AfterSuite | 无 |
11 | 在测试开始之前执行 | @BeforeTest | 无 |
12 | 在测试开始之后执行 | @AfterTest | 无 |
13 | 所在测试组的第一个测试方法被反射调用前执行 | @BeforeGroups | 无 |
14 | 所在测试组的最后一个测试方法被反射调用执行结束执行 | @AfterGroups | 无 |
套件测试
套件通常用于一起执行多个测试。TestNG和Junit都可以创建套件测试。然而,套件在测试很多不同测试方法时,TestNG体现得更好。通过以下代码可以体现出来。
使用JUnit进行套件测试
Junit使用定义类得方式来进行套件测试。
package guru99.junit;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
@RunWith(Suite.class)
@Suite.SuiteClasses({
SuiteTest1.class,
SuiteTest2.class,
})
public class JunitTest {
// This class remains empty,it is used only as a holder for the above annotations
}
使用TestNG进行套件测试
TestNG使用xml文件绑定所有得测试方法。以下xml文件用于描述一个TestNg得测试套件。
<!DOCTYPE suite SYSTEM "http://beust.com/testng/testng-1.0.dtd" >
<suite name="My test suite">
<test name="testing">
<classes>
<class name="com.guru99.SuiteTest1" />
<class name="com.guru99.SuiteTest2" />
</classes>
</test>
</suite>
无效测试用例
使用不同的方式时跳过指定的单元测试。以下为样例代码。
Junit
在Junit中使用@Ignore
注解来跳过单元测试。如下代码段:
@Ignore
public void method1()
{
System.out.println("Using @Ignore , this execution is ignored");
}
TestNG
在TestNg使用 @Test(enabled=false)
注解来跳过指定的单元测试。如下代码段:
@Test(enabled=false)
public void TestWithException()
{
System.out.println("Method should be ignored as it's not ready yet");
}
异常测试
TestNg和Junit均支持异常测试。异常测试用于校验测试中异常是否抛出正确。
使用Junit
@Test(expected = ArithmeticException.class)
public void divideByZero()
{
Int i = 1/0;
}
使用TestNG
@Test(expectedExceptions = ArithmeticException.class)
public void divideByZero()
{
Int i = 1/0;
}
超时
该特性在TestNG和Junit均有实现。超时用于终止一个执行了超过了指定时间(单位: 毫秒)的单元测试。
使用junit
@Test(timeout = 1000)
public void method1()
{
while (true);
}
使用TestNG
@Test(timeOut = 1000)
public void method1()
{
while (true);
}
参数测试
Junit提供了一个比较简单和容易理解方法去测试,该方法被称为参数测试。TestNG和Junit都支持参数测试, 但是他们定义参数的方式不同。以下一个一个解释。
使用junit
注解@RunWith
和@Parameter
为单元测试提供参数值。注解@Parameters
用于返回一个列表参数值。注解中的参数值会作为类构造方法的值传入。
@RunWith(value = Parameterized.class)
public class JunitTest{
privateint number;
public JunitTest6(int number)
{
this.number = number;
}
@Parameters
public static Collection<Object[]> data()
{
Object[][] data = new Object[][] { { 1 }, { 2 }, { 3 }, { 4 } };
returnArrays.asList(data);
}
@Test
public void parameterTest()
{
System.out.println("Parameterized Number is : " + number);
}
}
使用TestNG
在TestNg中,使用xml文件或者@DataProvider
注解来为单元测试提供参数。
在TestNg中,@Parameters
注解用来申明该方法需要参数进行测试。用作参数的数据会在TestNG的xml配置文件提供。使用这种方法,我们可以使用不同的参数集合来复用一个测试用例,
并且得到不同的结果。
测试用例
public class Test1 {
@Test
@Parameters(value="number")
public void parameterTest(int number)
{
System.out.println("Parameterized Number is : " + number);
}
}
xml配置文件:
<!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.guru99.Test1" />
</classes>
</test>
</suite>
总结
我们详细的比较了TestNg和Junit,看到了除了参数测试与依赖测试之外的相同点。简单的说,基于灵活性和需求,我们可以任意其中的一个用于单元测试。
Junit 指的是Junit4