轉自 http://www.blogjava.net/fanscial/archive/2005/12/14/23780.htmlhtml
1. JDK 5 Annotations (JDK 1.4 能夠用JavaDoc代替).java
一個典型的Junit的測試類web
import junit.framework.TestCase;數組
public class Jtest extends TestCase {ide
protected void setUp() throws Exception {單元測試
super.setUp();測試
//some initial codeui
}編碼
protected void tearDown() throws Exception {spa
super.tearDown ();
//release resource and rollback
}
public void testFunction {
//test code
}
}
對應的TestNG的測試類,咱們寫最簡單的狀況。
public class NGtest{
@Configuration(beforeTestClass=true)
public void setUp() {
//some initial code
}
@Configuration(afterTestClass = true)
public void tearDown (){
//release resource and rollback
}
@Test( )
public void testFunction (){
//test code
}
}
這樣寫能夠比較明顯的看到二者的對應關係(注意TestNG的方法的名字是能夠隨便取的,取同樣的名字只是爲了讓你容易找到對應的關係)
這說明TestNG是從Junit發展而來的,至少借鑑了不少Junit的思想(實際上TestNG的做者自己就是Junit的小組成員之一)。
咱們從最表面的現象來看看吧
l TestNG沒有繼承任何類,甚至接口!!
l JDK 5 Annotations
這2者是息息相關的,爲何咱們不用繼承任何類,由於信息都在註釋裏面,這樣會帶來不少好處(毫不僅僅是命名的方便)。
2. 靈活的test configuration
先看一下Junit的執行順序
Setup( ) test1( ) tearDown( ) Setup( ) test2( ) tearDown( )…………
下面是TestNG的
實際上外面還有一個beforeSuite和afterSuite的方法,是在測試項目開始的時候就運行了,實際上若是個人每一個方法都要用到的初始化的代碼,爲何要運行那麼屢次,若是其中有EJB這種重量級的容器要初始化,效率差可想而知。事實上TestNG能夠作到更加的靈活,就是分組。
3. TestNG 的靈魂
配置文件(testng.xml)
Junit中要定義測試任務是要寫TestSuit的,竟然要寫硬編碼,而TestNG所有寫在testng.xml(名字能夠自定義的)中的,而後能夠經過ant來調用。
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="my suite">
<test name="test1">
<groups>
<run name="group1">
</run>
</groups>
<classes>
<class name="ClassA" />
</classes>
</test>
<test name="test2" >
<groups>
<run name="group2">
</run>
</groups>
<classes>
<class name="ClassB"/>
<class name="ClassC"/>
</classes>
</test>
</suite>
上面包含了配置文件的基本的主幹,一個配置文件只有一個Suite,基本上一個項目寫一個配置文件就能夠了,固然若是你的項目足夠大,可能須要幾個配置文件。測試是按照從大到小的順序進行的,先執行suite,test,class,其中的group和class是平級的,在講group的時候再詳細的解釋。有了這個文件,咱們就能夠很清楚的理解@configuration裏面的類型
public boolean beforeSuite() default false;
public boolean afterSuite() default false;
public boolean beforeTest() default false;
public boolean afterTest() default false;
public boolean beforeTestClass() default false;
public boolean afterTestClass() default false;
public boolean beforeTestMethod() default false;
public boolean afterTestMethod() default false;
從字面意思能夠看出方法的執行順序,惟一的疑惑是執行的次數,官方的文檔的解釋是至關讓人疑惑的,好在咱們能夠本身測試,beforeTestMethod是當類中任何方法調用都要執行的,beforeTest和beforeTestClass在一個Test中是隻執行一次的(沒試過把2個相同的類寫到一個Test裏面),而beforeSuite在一個配置文件中只執行一次。上面都沒有考慮分組的狀況,分組會更加的複雜,彷佛靈活過頭了,可是考慮到項目的複雜性,每一個測試方法的初始化均可能不一樣,如今咱們作的項目要求天天要將單元測試寫進daily build的build文件裏面自動執行,彷佛只有用TestNG這樣靈活的配置才能達到。
4. 分組
將一個測試方法或者配置方法分組是很容易的。
@Configuration(beforeTestClass=true,groups=「group1」)
@Test(groups=」group1」)
只要象上面寫就能夠了,名字隨便取,並且不須要預先定義。
咱們在一個類作2個組,看看效果
@Configuration(beforeTestClass=true,groups=「group1」)
Public void C1(){}
@Test(groups=」group1」)
Public void T1(){}
@Configuration(beforeTestClass=true,groups=「group2」)
Public void C2(){}
@Test(groups=」group2」)
Public void T2(){}
只選group1
…………………
<groups>
<run name="group1">
</run>
</groups>
…………
執行C1 T1
只選group2
…………………
<groups>
<run name="group2">
</run>
</groups>
…………
執行C2 T2
2個都選
…………………
<groups>
<run name="group1">
<run name="group2">
</run>
</groups>
…………
我最早覺得的順序是C1 T1 C2 T2 (A)
然而其實是 C1 C2 T1 C1 C2 T2 (B)
要想達到(A)的效果,只能把2個group分開了放在不一樣的Test裏面,其實只要知道一點,TestNG是先找Class,而後纔去找Group的。
4. 參數
Junit是不帶任何參數的,不管是測試方法仍是配置方法,而TestNG都是能夠添加參數的,有2種方法。
(1) 使用Parameter參數
@Parameters({ "first-name" })
@Test
public void testSingleString(String firstName) {
System.out.println("Invoked testString " + firstName);
assert "Cedric".equals(firstName);
}
參數的值放到配置文件中
<suite name="My suite">
<parameter name="first-name" value="Cedric"/>
<test name="Simple example">
這種方法偶爾用之還能夠,可是很遺憾的是第一隻能傳String(可能能夠其餘的基本數據類型??但至少不能傳複雜對象),第二數據寫在配置文件中,不能所見即所得。
可是下面的方法真的給咱們驚喜。
(2) DataProvider
這是從4.0之後增長的功能,看看怎麼實現。
// This method will provide data to any test method that declares that its Data Provider
// is named "test1"
@DataProvider(name = "test1")
public Object[][] createData1() {
return new Object[][] {
new Object[] { "Cedric", new Integer(36) },
new Object[] { "Anne", new Integer(37)},
};
}
// This test method declares that its data should be supplied by the Data Provider
// named "test1"
@Test(dataProvider = "test1")
public void verifyData1(String n1, Integer n2) {
System.out.println(n1 + " " + n2);
}
執行的結果
Cedric 36
Anne 37
DataProvider返回的是個2維數組的對象,什麼數據均可以提供了吧,並且可讓你的測試方法執行屢次。並且最重要的是和測試方法寫在一塊兒,所見即所得。
5. Ant的集成和Daily Build
TestNG對Ant提供了很好的支持,這是我寫得測試用的Ant腳本
<project default="testng">
<property file="build.properties" />
<path id="cpath">
<fileset dir="lib">
<include name="*.jar"/>
</fileset>
</path>
//定義testng的任務
<taskdef resource="testngtasks" classpath="lib/testng-4.4-jdk15.jar" />
<target name="compile">
<mkdir dir="test/classes"/>
<javac destdir="test/classes"
srcdir="${testng.dir}"
debug="true"
encoding="GBK" >
<classpath refid="cpath"/>
</javac>
</target>
//執行testng的任務
<target name="testng" depends="compile">
<testng classpath="test/classes">
<xmlfileset dir="${configure.dir}" includes="testing.xml" />
</testng>
</target>
</project>
簡單的不能在簡單了,你只要告訴ant來調用,而後告訴ant配置文件在哪裏,剩下的事都交給testng本身的配置文件去作就好了,而後ant之後都不用修改了。不建議將任務的細節寫在ant裏面,首先功能不如testng本身的配置文件強大,並且ant須要維護。
下面基本上是TestNG纔有的特色了,和Junit沒有什麼關係,但爲了延續,仍是用了上面的題目。
7 .依賴關係
先給個例子
@Test
public void serverStartedOk() {}
@Test(dependsOnMethods = { "serverStartedOk" })
public void method1() {}
在這個例子中,method1()必須在serverStartedOk()執行後才能執行,並且serverStartedOk()不能fail,不然method1()會被skip掉
基本上相似於ant的依賴關係,也很容易理解,只是分爲強依靠和弱依靠,區別是弱依靠只管執行的順序,強依靠除了順序,還要正確,不然後面的不執行,上面的例子是強依靠,下面是弱依靠,加上alwaysrun=」true」
@Test
public void serverStartedOk() {}
@Test(dependsOnMethods = { "serverStartedOk" },alwaysrun=」true」)
public void method1() {}
若是有興趣,能夠看看下面的文章,裏面有有趣的爭論
http://beust.com/weblog/archives/000171.html
8.其餘特性
還有不少,工廠模式,並行運行(Parallel running ),BeanShell 等等,感受不是特別重要,並且寫了那麼多感受好累啊,就不寫了,有興趣的能夠去看看官方的文檔。
http://testng.org/doc/documentation-main.html