【IT168 分析评论】
大家都知道JUnit已经成为Java单元测试的标准,但是进几年来出现的其他工具突破了JUnit的限制.TestNG就是其中的一个,最近在IBM developerWorks上有一篇文章就4点特性比较了TestNG和JUnit.
我们知道JUnit 4并不是第一个基于注释的提供灵活的模型Java™测试框架,事实上,TestNG在JUnit修改之前就已经将自己作为一个基于注释的框架了. TestNG是在Java编程中用注释进行测试的先驱,这也使得它和JUnit在测试方面不分伯仲.既然两个框架都有其强大的功能,那么二者有哪些区别和相同点呢?
表面上的相似性
JUnit和TestNG有很多共有的特性,二者都有活跃的社区来支持其发展,同时也产生非常丰富的文档.
这两个框架的不同在于他们的核心设计, JUnit一直是一个单元测试框架,意思是它在单个对象方面很容易,另一方面, TestNG在更高的水平上创建地址测试,因此, TestNG有很多JUnit没有的特性.
一个简单的测试示例:
乍看,在JUnit和TestNG中执行的测试看起来很相似,看Listing 1的代码, JUnit测试有一个macro-fixture(fixture是在测试运行前就会被调用), macro-fixture是由@BeforeClass属性来表示的.
Listing 1. 简单的JUnit 4测试示例:
JUnit用户可能会立即注意到这个类缺少先前版本所需的(syntactic sugar)语法糖块,没有setUp()方法,这个类并没有继承TestCase类,甚至从测试开始就没有任何方法.这个类也使用Java 5的特性,像静态导入等.package test.com.acme.dona.dep;
![]()
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import org.junit.BeforeClass;
import org.junit.Test;
![]()
public class DependencyFinderTest ...{
private static DependencyFinder finder;
![]()
@BeforeClass
public static void init() throws Exception ...{
finder = new DependencyFinder();
}
![]()
@Test
public void verifyDependencies()
throws Exception ...{
String targetClss =
"test.com.acme.dona.dep.DependencyFind";
![]()
Filter[] filtr = new Filter[] ...{
new RegexPackageFilter("java|junit|org")};
![]()
Dependency[] deps =
finder.findDependencies(targetClss, filtr);
![]()
assertNotNull("deps was null", deps);
assertEquals("should be 5 large", 5, deps.length);
}
}
更好用的例子:
在Listing 2,是同样的测试例子,但是这次使用TestNG来执行, Listing 2的代码和Listing 1代码有细微的不同.
Listing 2. A TestNG test case
显然,这两个Listing的代码非常相似,但是如果你仔细看, TestNG代码的更灵活的比JUnit,在Listing 1中, JUnit迫使将@BeforeClass中的方法为static,因此要求声明fixture和finder为static,同时不得不声明init()方法为public的,而Listing 2,这些不会要求,因为这些约定俗称没有被要求,init()方法即不是static的也不是public的.package test.com.acme.dona.dep;
![]()
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Configuration;
import org.testng.annotations.Test;
![]()
public class DependencyFinderTest ...{
private DependencyFinder finder;
![]()
@BeforeClass
private void init()...{
this.finder = new DependencyFinder();
}
![]()
@Test
public void verifyDependencies()
throws Exception ...{
String targetClss =
"test.com.acme.dona.dep.DependencyFind";
![]()
Filter[] filtr = new Filter[] ...{
new RegexPackageFilter("java|junit|org")};
![]()
Dependency[] deps =
finder.findDependencies(targetClss, filtr);
![]()
assertNotNull(deps, "deps was null" );
assertEquals(5, deps.length, "should be 5 large");
}
}
灵活性是TestNG的一个亮点,但它不是卖点, TestNG还有许多测试特性是JUnit没有的.