1、測試環境
jdk1.8.0 121
myeclipse-10.0-offline-installer-windows.exe
TestNG 插件
org.testng.eclipse 6.8.6.20130607 0745
2、介紹
套件(suite):由一個 XML 文件表示,通過<suite>標簽定義,包含一個或更多測試(test)。測試(test):由<test>定義,包含一個或更多 TestNG 類(class)。TestNG類(class):至少包含一個TestNG注釋(annotation)的java 類,由<class>標簽定義,包含一個或多個測試方法(test medthod)。測試方法(test method):一個附注了@Test 的 java 方法。
3. Annotation
?
更多解釋,可以查看官方文檔的介紹
?4、testng.xml介紹
4.1.例 1
?注:test-output是運行后自動生成的。xmltest.xm1是在對應目錄下新建的,testng-1.0.dtd 也是下載后,手動放進去的。
Test1.java 代碼:
package unittests;
import org.testng.annotations.*
public class Test1 {
@Test
public void func1(){System.out.println("test in func1");
public void func2(){System.out.println("test in func2");
?testng-1.0.dtd下載地址:http://testng.org/testng-1.0.dtd
右鍵 xmltest.xml-> Run As TestNG Suite,運行套件,輸出如下:
?說明:
1、只有被附注了@Test 的方法才會被執行。
2、如果右鍵只能看到 Run As Run Configurations,則右鍵項目,選擇 refresh 刷新
3、TestNG 類沒有歸屬 package,也可以如下編寫 xml(當前版本的插件是不允許新建TestNG Class 時不提供包名的,通常建議提供包名)
?4.2.例 2
也可以指定包名,而非類名,TestNG將查找 unittests 包中所有 class,且僅保留攜帶TestNG 注解的類。
運行結果同上
?4.3.例3
還可以指定需要包含/排除的 group 和方法。
修改 Test1.java 代碼
package unittests;
import org.testng.annotations.*;
public class Test1 {@Test(groups={"functest","checkintest"})public void func1(){System.out.println("test in func1");
@Test(groups={"functest""checkintest"})
public void func2(){
System.out.println("test in func2");
@Test(groups={"functest"})public void func3(){System.out.println("test in func3");
問題:保存代碼后,編輯器中,代碼 package unittests;右側會提示“紅叉”解決方法:
?
?
?
?修改 xmltest.xml
?
?運行結果:未執行任何一個測試方法。
再修改下,把
?
?說明:
1、例中的<include>和<exclude>是 and 關系,而非 or 的關系
2、僅提供 groups 元素配置,不提供 class 元素,執行后不調用任何測試方法
3、還可以為 group 添加其它屬性,比如是否并發運行,使用多少線程,是否運行Junit
?
?運行結果:只執行了 func1 測試方法
說明:
同時設置了groups 和method元素,且同時為groups和method設置了include、exclude為 method 元素設置 include 屬性,那么 groups 元素的設置不起作用,僅執行 method中需要 include 的方法
只為method元素設置exclude屬性,那么根據groups 元素設置得出需要運行的測試方法然后在此基礎上過濾掉 method 元素的 exclude 屬性設置的方法。
4.4.例 4
默認的,TestNG 依據出現在 xm1 中的順序執行測試。可以設置 preserve-order 屬性為false 來改變這一行為。
修改xmltest.xml如下
?5.測試方法(Test method),測試類(Test class),測試組(Test groups)
5.1.測試方法(Test method)
默認的,被附注了@Test 的測試方法,其返回值被忽略,除非設置 allow-return-values值為 true。
<suite allow-return-values="true">
or
<test allow-return-values="true">
5.2.測試組(test groups)
groups 可以位于<test>、<suite>元素內。如果在<suite>標簽下指定 groups,那么 group設置作用于該 suite 下的所有<test>。
5.2.1.例 1
修改 Test1.java 內容下
package unittests;
import org.testng.annotations.*
public class Test1 {@Test(groups={"functest","checkintest"})public void testMethod1(){System.out.println("test in func1");
@Test(groups={"functest","checkintest"})public void testMethod2(){System.out.println("test in func2");
@Test(groups={"functest"})public void testMethod3(){System.out.println("test in func3");
groups 元素放在<test>標簽下
?
?groups 元素放在<suite>標簽下
?5.2.2.例 2
使用正則表達式。
修改 Test1.java 內容下
package unittests;
import org.testng.annotations.*;
public class Test1 {
@Test(groups={"windows.functest"})public void testMethod1(){System.out.println("test in func1");
@Test(groups={"linux.functest"})public void testMethod2(){System.out.println("test in func2");
@Test(groups={"functest"})public void testMethod3(){System.out.println("test in func3");
修改 xmltest.xml如下
?運行結果:
只執行了 testMethod1
5.2.3.例 3
方法組(method groups)包含、排除單個測試方法修改 xmltest.xm1 內容如下:
?
?運行結果:testMethod1,testMethod2,testMethod3 都被執行了。
嵌套組
組可以包含組。
修改 Test1.java 如下
package unittests;
import org.testng.annotations.*;
public class Test1 {@Test(groups={"functest","checkintest"})public void testMethod1(){System.out.println("test in func1");
@Test(groups={"functest","checkintest"})public void testMethod2(){System.out.println("test in func2");
@Test(groups={"functest"})public void testMethod3(){System.out.println("test in func3");
修改xmltest.xm1
?
?運行結果:
3個測試方法都被執行了,為何?難道是 bug?不理解
排除組
?運行結果:
只執行了 testMethod3 測試方法
Partial 組
可在 class級別添加組,然后在方法級別添加組修改 Test1.java 內容如下
package unittests;
import org.testng.annotations.*.
@Test(groups="functest")
public class Test1 {
@Test(groups={"checkintest"})public void testMethod1(){System.out.println("test in func1");
@Test(groups={"checkintest"})public void testMethod2(){System.out.println("test in func2");
@Test
public void testMethod3(){System.out.println("test in func3");
xmltest.xml 內容如下
?運行結果:僅執行了 testMethod3
說明:TestNG類中所有被附注了@Test的測試方法,默認都歸屬在類級別定義的group
6. 參數
6.1.來自 testng.xml 的參數
6.1.1.例 1
修改 Test1.java
?修改 xmltest.xml
?
?
?參數還可以用于@Before/After 和@Factory
6.1.2.例 2可用@0ptional 來聲明參數可選
修改 Test1.java
?說明:如果在 xm1 文件中找不到參數 arg_in_xm1,那么使用 0ptional 括號中的值作為參都
修改 testxml.xm1
?
?6.2.攜帶 DataProvider 的參數
6.2.1.例 1
修改 Test1.java
?
?注意:必須用 dataProvider 屬性指明 Data Provider,屬性值必須和@DataProvider(name="...")中 name 的值保持一致。另外,參數個數得保持一致。
修改 xmltest.xm1
?運行結果,輸出如下數據:
rebort 36
2014 37
默認的,TestNG 會在當前測試類、其某個父類中査找 Data Provider。如果想把 dataprovider 放在其它的類中,那么被附注的方法必須是靜態方法、或者攜帶無參構造器的類,并在 dataProviderClass 屬性中指定該類。
6.2.2.例 2
在 unittests 包下新建一個 StaticProvider.java,代碼內容如下
?
?
?運行結果,輸出:
42
data provider 返回以下類型之一:
1)返回一個 object[][],數組第一維度的大小,代表了測試方法被調用的次數,第二維度則包含了和測試方法的參數類型匹配的任意對象數組。
2)返回一個迭代器 Iterator<0bject[]>。
eg:
@DataProvider(name ="test1")public Iterator<Object[]>createData(){return new MyIterator(DATA);
6.2.3.例 3
如果聲明@DataProvider接收一個java.lang.reflect.Method作為第一個參數,TestNG將會把當前測試方法傳遞給該參數。
修改 Test1.java 內容如下
?
?如果想在不同的線程池中運行多個 data provider,需要從 xm1 文件中運行它們。
7. 依賴
7.1.使用注解的依賴
7.1.1.例 1
依賴方法
修改 Test1.java 內容如下
?
?運行結果,先后輸出:test2
test1
說明:test1的運行依賴 test2 的運行注意:這種依賴,如果被依賴者運行失敗,那么依賴者的不被執行,報告中被標記為 SKIPeg:修改 test2方法如下,再次運行
?
?7.1.2.例 2
利用@Test 的屬性設置 alwaysRun=true 解決例2中被依賴者運行失敗,不執行依賴者的
問題
修改 Test1.java
?
?7.1.3.例 3
依賴組
?
更多資料參考:?Otaku – Cedric's blog
默認的,依賴方法按組分類,如果方法 test1 和方法 test2 都是同一個測試類的測試方法,test1依賴test2,那么當該類的多個實例被調用時,會先執行完所有test2,再執行test1.
7.1.4.例 4
新建 testNG 測試類
?
?
?
?
?運行結果
?
運行結果
?
?7.2.XML 中的依賴
可選的,可在 testng.xm1 文件中指定組依賴。使用<dependencies>標簽來實現這個。修改 Test1.java 內容如下
?
?修改 xmltest.xml 內容如下
?注意:被依賴的多個組之間用空格分隔。
8. 工廠模式
動態的創建測試。
8.1.例1
假設,你想創建一個測試方法,使用不同的值,多次訪問某個web站點的頁面
?
?如果繼續按這個思路繼續,很快就會變得難以管理。所以考慮使用工廠模式新建 TestNG 類文件 WebTest.java
?新建 TestNG 類文件 WebTestFactory.java
?
?修改 xmltest.xml 如下
?運行結果:webTest 中的測試方法也被執行了
說明:附注@Factory 注解的方法中構造某測試類的實例,會自動調用該測試類中帶有@Test注解的方法
當然,也可以在 java 程序中通過代碼來運行新建 Test2.java,內容如下:
?factory 方法接收類似@Test 和@Before/After 的參數,且必須返回 0bject[]。返回的對象可以是任何類實例(注:對象所在類,不含@xxxx注解的方法不被執行)。
@Factory 也可以配合 data provider 使用,可用于構造器或者普通方法
8.2.例 2
修改 WebTestFactory.java 內容如下
?
?結果:運行了 30 次測試,即 testServer 被調用了 38 次。
9.類級別的注解
?
?
?運行結果:test1,test2都被執行了,也就是說類級別的@Test 注解會把該類的所有公有方法都當作測試方法,不管是否有注解。這種情況下,依舊可為單個類方法進行注解以添加其他屬性,比如歸屬的組別
10.并行和超時
10.1. 并行套件
假如有多個套件需要運行。修改 xmltest.xml如下,復制xmltest.xml分別為xmltest2.xml,xmltest3.xml,修改套件名分別為suite2,suite3
?注意:要先 javac 對類文件進行編譯,否則會報錯,類似如下:ITestNG] [ERROR]
Cannot find class in classpath:unittests.Test1
運行套件
?且想讓每個套件在單獨的線程中運行,可添加-suitethreadpoolsize選項java org.testng.TestNG -suitethreadpoolsize 3 testng.xml testng2.xmltestng3.xml
10.2.并行test,class,method
略
11.返回失敗測試
TestNG 會為每次運行套件失敗的測試,在結果輸出目錄(如果為用 -d outpu_dir 指定目錄則結果輸出目錄為在當前工作目錄下的生成的 test-outputs)下創建一個名為testng-failed.xm1 的文件。可按如下方式運行失敗的用例。src>java org.testng.TestNG test-output/testng-failed.xml
12.JUnit tests
?13.Annotation 轉換略
14.Method Interceptors略
15. TestNG Listeners
哈
16. Dependency injection
貽
17.重寫測試方法
略
18.更改套件、方法略
19.通過編程方式運行 TestNG
?
?
?
?假設想同運行如下假設的 xm1 一樣,通過編程方式運行 TestNG 可如下操作
?
?
?20.測試結果
20.1. 成功,失敗斷言
20.1.1.例 1
修改 Test1.java 內容如下
?為了滿足更復雜對象的斷言,可導入 JUnit 的 Assert 類。20.1.2.例 2
修改 Test1.java 內容如下
?注意:使用 static import 是為了在使用斷言方法,如 assertEquals 時,不用攜帶包名類名,如果不用 static,則需要這么使用:org.testng.AssertJUnit.assertEquals
20.2. Logging和結果
20.2.1.logging 監聽器
例:
?
?
?運行結果
?說明:
1、-listener 選項指定使用的監聽器
也可以在 xm1 中指定監聽器修改 xmltest.xm1 內容如下
?
?運行結果:
?意:命令行運行,testng 自帶的 assert 似乎不起作用,為何?
還可以在.java 文件中指定
?
?
注:如果同時在.java 代碼中和 xm1中指定同一個監聽器,則針對每個測試方法的測試結果,會運行兩次 1og 方法
20.2.2.Logging Reporters略
20.2.3.JUnitReports略
20.2.4.Reporter API略
20.2.5.XML Reports略
參考連接:
http://testng.org/doc/documentation-main.htm1