在編寫TestNG代碼的時候,若沒有下載TestNG的jar包的話,代碼會出錯,下載jar包方法見該鏈接中java+selenium環境搭建的第二步即可:http://www.cnblogs.com/hong-fithing/p/7622215.html
運行測試步驟方法有如下兩種:
1、 直接在Eclipse運行testNG的測試用例, 在代碼編輯區域鼠標右鍵, 選擇Run as ->testNG Test
2、 在工程的根目錄下, 建立testng.xml文件, 並在文件中輸入配置內容:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE suite SYSTEM "http://beust.com/testng/testng-1.0.dtd" > 3 <suite name="suite1"> 4 <test name="test1"> 5 <classes> 6 <class name="com.ui.day4.CalcTest" /> 7 <class name="com.testng.demo_1" /> 8 </classes> 9 </test> 10 </suite>
然后在工程中的testNG.xml上方鼠標右鍵單擊, 在彈出的菜單中選擇Run as ->Test Suite即可運行測試用例,suite代表一個XML文件。 它可以包含一個或多個測試, 並被定義由<suite>標記標簽<test>代表一個測試, 並可以包含一個或多個TestNG的類<class>的標簽代表一個TestNG的類是一個Java類,它包含至少一個TestNG的注解。它可以包含一個或多個測試方法。
執行結果查看方式:
1、 在Console可以查看測試結果
2、 testNG的Results可以查看
3、 testNG的Html格式測試報告, 該測試報告存在與工程目錄下的“test-output”目錄下,emailable-report.html和index.html。


TestNG常用注解annotation
注解 | 描述 |
@BeforeSuite | 被注釋的方法將在所有測試運行前運行(相當於前置條件) |
@AfterSuite | 被注釋的方法將在所有測試運行后運行比如關閉瀏覽器(使執行其他用例時處於初始狀態) |
@BeforeTest | 被注釋的方法將在測試運行前運行 |
@AfterTest | 被注釋的方法將在測試運行后運行 |
@BeforeGroups | 被配置的方法將在列表中的gourp前運行。這個方法保證在第一個屬於這些組的測試方法調用 前立即執行 |
@AfterGroups | 被配置的方法將在列表中的gourp后運行。這個方法保證在最后一個屬於這些組的測試方法調 用后立即執行 |
@BeforeClass | 被注釋的方法將在當前類的第一個測試方法調用前運行 |
@AfterClass | 被注釋的方法將在當前類的所有測試方法調用后運行 |
@BeforeMethod | 被注釋的方法將在每一個測試方法調用前運行 |
@AfterMethod | 被注釋的方法將在每一個測試方法調用后運行 |
@DataProvider | 標記一個方法用於為測試方法提供數據。 被注釋的方法必須返回Object[][],其中每個Object[] 可以指派為這個測試方法的參數列表。從這個DataProvider接收數@Test方法需要使用一個和 當前注釋相同名稱的dataProvider名稱 |
@Factory | 標記方法作為一個返回對象的工廠, 這些對象將被TestNG用於作為測試類。這個方法必須返回 Object[] |
@Listeners | 定義一個測試類的監聽器 |
@Parameters | 描述如何傳遞參數給@Test方法 |
@Test | 標記一個類或方法作為測試的一部分 |
備注:
Before開頭的注解一般用於初始化環境、 准備測試環境
after開頭的注解一般用於執行測試的環境清理工作
DataProvider一般用作參數化用的, 屬於數據驅動自動化(即不同的測試數據測試相同的測試邏輯)
Listeners 自定義日志或者監控一些testNG用例執行成功或者失敗的時候做些特別的事情
Parameters可以把xml文件定義的參數傳遞到測試程序或者測試類中來使用
1 public class yihuqingjiu_test_demo { 2 3 @Test 4 public void testCase1() { 5 System.out.println("in test case 1"); 6 } 7 @Test 8 public void testCase2() { 9 System.out.println("in test case 2"); 10 } 11 @BeforeMethod 12 public void beforeMethod() { 13 System.out.println("in beforeMethod"); 14 } 15 @AfterMethod 16 public void afterMethod() { 17 System.out.println("in afterMethod"); 18 } 19 @BeforeClass 20 public void beforeClass() { 21 System.out.println("in beforeClass"); 22 } 23 @AfterClass 24 public void afterClass() { 25 System.out.println("in afterClass"); 26 } 27 @BeforeTest 28 public void beforeTest() { 29 System.out.println("in beforeTest"); 30 } 31 @AfterTest 32 public void afterTest() { 33 System.out.println("in afterTest"); 34 } 35 @BeforeSuite 36 public void beforeSuite() { 37 System.out.println("in beforeSuite"); 38 } 39 @AfterSuite 40 public void afterSuite() { 41 System.out.println("in afterSuite"); 42 } 43 44 }
運行結果:
in beforeSuite
in beforeTest
in beforeClass
in beforeMethod
in test case 1
in afterMethod
in beforeMethod
in test case 2
in afterMethod
in afterClass
in afterTest
首先beforeSuite()方法執行一次。
最后afterSuite的()方法執行一次。
其次方法 beforeTest(), beforeClass(), afterClass() 和afterTest() 方法各執行一次。
beforeMethod()方法在執行每個測試用例之前執行一次。
afterMethod()方法在執行每個測試用例之后執行一次。
TestNG測試套件
測試套件是為了測試軟件程序的行為或一系列行為, 是一個集合。 在TestNG中, 不能在測試源代碼中引入測試集合, 但可以用testng.xml文件來進行測試套件的配置。
Testng.xml文件節點屬性
suite常用屬性介紹 | |
注解 | 描述 |
@name | suite的名稱, 必須參數 |
@verbose | 命令行信息打印等級, 不會影響測試報告輸出內容; 可選值(1|2|3|4|5) |
@parallel | 是否多線程並發運行測試; 可選值(false | methods | tests | classes |instances)默認 "false" |
@thread-count | 當為並發執行時的線程池數量, 默認為"5" |
@annotations | 獲取注解的位置, 如果為"javadoc", 則使用javadoc注解, 否則使用jdk注解 |
junit | 是否以Junit模式運行, 可選值(true | false), 默認"false" |
@time-out | 為具體執行單元設定一個超時時間, 具體參照parallel的執行單元設置; 單位為毫秒 |
test常用屬性說明 | |
注解 | 描述 |
@name | test的名字, 必選參數; 測試報告中會有體現 |
@verbose | 命令行信息打印等級, 不會影響測試報告輸出內容; 可選值(1|2|3|4|5) |
@parallel | 是否多線程並發運行測試; 可選值(false | methods | tests | classes |instances)默認 "false" |
@thread-count | 當為並發執行時的線程池數量, 默認為"5" |
@annotations | 獲取注解的位置, 如果為"javadoc", 則使用javadoc注解, 否則使用jdk5注解 |
@time-out | 為具體執行單元設定一個超時時間, 具體參照parallel的執行單元設置; 單位為毫秒 |
@enabled | 設置當前test是否生效, 可選值(true | false), 默認"true" |
testng.xml中有<suite>根標簽。 它描述了一個測試套件, <suite>由一個或多個<test>區段組成, 如下testng.xml文件:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" > 3 <suite name="Suite1"> 4 <test name="exampletest1"> 5 <classes> 6 <class name="com.ui.day1.test1" /> 7 </classes> 8 </test> 9 <test name="exampletest2"> 10 <class name="com.ui.day2.test2"> 11 <methods> 12 <include name="test01"></include> 13 </methods> 14 </class> 15 </test> 16 </suite>
TestNG忽略測試
當測試用例還沒准備好,可以給測試用例加上@Test(enable =false),來禁用此測試用例。
代碼實現:
@Test(enabled = false) public void add(){ Assert.assertEquals(a.add(5, 6), 11); }
TestNG分組測試
顧名思義,是將不同的用例分組,然后再testng.xml文件中配置信息,而執行相應組的用例,代碼實現如下,僅供參考:
1 package com.ui.day4; 2 3 import org.testng.Assert; 4 import org.testng.annotations.BeforeSuite; 5 import org.testng.annotations.Test; 6 7 public class yihuqingjiu_test_group { 8 ca a; 9 @BeforeSuite(groups = {"冒煙","回歸"}) 10 public void reday() { 11 a = new ca(); 12 } 13 @Test(groups = "冒煙") 14 public void add() { 15 Assert.assertEquals(a.add(5, 6), 11); 16 } 17 @Test(groups = "冒煙") 18 public void min() { 19 Assert.assertEquals(a.minus(6, 5), 1); 20 } 21 @Test(groups = "冒煙") 22 public void cheng() { 23 Assert.assertEquals(a.cheng(6, 5), 30); 24 } 25 @Test(groups = "回歸") 26 public void cheng1() { 27 Assert.assertEquals(a.cheng(6, 5), 30); 28 } 29 @Test(groups = "回歸") 30 public void chu() { 31 Assert.assertEquals(a.chu(5, 5), 1); 32 } 33 }
testng.xml文件配置如下:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" > 3 <suite name="Suite1" verbose="3"> 4 <test name="test_one"> 5 <groups> 6 <run> 7 <include name="回歸" /> 8 </run> 9 </groups> 10 <classes> 11 <class name="com.ui.day4.test_group"></class> 12 </classes> 13 </test> 14 </suite>
TestNG依賴測試
按順序來調用測試用例,那么測試用例之間就存在依賴關系,TestNG支持測試用例之間的依賴。TestNG中通過dependsOnMethods屬性來配置依賴方法。
實現如下:
@Test(dependsOnMethods = { "minus" }) public void add() { Assert.assertEquals(a.add(5, 6), 11); }
備注: add測試用例執行的前提條件是必須minus測試方法執行,如果minus用例的屬性設置為enabled = false,那么執行測試的時候就會報錯,因為minus不執行。 注意:被依賴的測試用例必須執行成功才運行下一個測試用例,dependsOnGroups依賴於測試組
TestNG自定義執行順序
按照一定的順序去執行測試方法, 通過priority屬性去設 置,如下代碼實現:
1 public class yihuqingjiu_demo { 2 @Test(priority=2) 3 public void print3(){ 4 System.out.println("壺"); 5 } 6 @Test(priority=0) 7 public void print1(){ 8 System.out.println("溫"); 9 } 10 @Test(priority=1) 11 public void print2(){ 12 System.out.println("一"); 13 } 14 @Test(priority=4) 15 public void print5(){ 16 System.out.println("酒"); 17 } 18 @Test(priority=3) 19 public void print4(){ 20 System.out.println("清"); 21 } 22 }
執行順序為print1--->print2--->print3--->print4--->print5
屬性值為0代表最高優先級
還可以在testng.xml文件中設置,設置如下:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" > <suite name="Suite1"> <test name="test" preserve-order="true"> <classes> <class name="com.ui.day4.test_demo"> <methods> <include name="print5" /> <include name="print2" /> <include name="print4" />
<include name="print1" />
<include name="print3" /> </methods> </class> </classes> </test> </suite>
preserve-order屬性設置為true
依據include配置的順序執行測試方法
TestNG參數化測試
軟件測試中, 經常需要測試大量的數據集。 測試代碼的邏輯完全一樣, 只是測試的參數不一樣。 這樣我們就需要一種 “傳遞測試參數的機制” 。 避免寫重復的測試代碼。
TestNG提供了2種傳遞參數的方式:
第一種: testng.xml 方式使代碼和測試數據分離,方便維護;
第二種: @DataProvider能夠提供比較復雜的參數。(也叫data-driven testing)
使用testng.xml設置參數:
1、 參數在xml文件中可以在suite級別定義, 也可以在test級別定義;
2、 TestNG會嘗試先在包含當前類的test標簽中尋找參數, 如果沒找到則在上層的suite標簽中查找。 即在test標簽中相同的參數對當前類當前方法的優先級比較高。
3、 TestNG支持這種傳參方式的類型如下:
String、 int/Integer、 boolean/Boolean、 byte/Byte、 char/Character、double/Double、 float/Float、 long/Long、 short/Short
使用@DataProvider方式傳參數:
只提供了一個字符串屬性:名稱,供測試方法作為傳遞參數的annotation使用兩種DataProvider,一種是返回一個二維數組對象; 另外一種DataProvider是返回一個Iterator
DataProvider可以向測試方法傳遞任意類型任意數目的參數利用DataProvider提供不同的參數集合對一個測試方法進行多次調用
@DataProvider和testNG.xml兩種方式的比較
1 public class NewTest { 2 WebDriver driver; 3 4 @BeforeSuite 5 public void reday(){ 6 driver=new ChromeDriver(); 7 driver.manage().window().maximize(); 8 driver.manage().timeouts().implicitlyWait(5,TimeUnit.SECONDS); 9 } 10 11 @Test(priority=0) 12 public void index() throws Exception{ 13 driver.get("http://127.0.0.1/iwebshop/"); 14 String title=driver.getTitle(); 15 //斷言 16 //括號中前者是實際結果,后者是預期結果 17 Assert.assertEquals(title,"iWebShop開源電子商務平台"); 18 Thread.sleep(2000); 19 } 20 21 @Test(priority=1) 22 public void login() throws Exception{ 23 driver.findElement(By.cssSelector("p.loginfo a")).click(); 24 Thread.sleep(2000); 25 } 26 27 @DataProvider(name="test") 28 public static Object[][] obj(){ 29 return new Object[][]{{"username","654321"},{"username","123456"},{"username","654321"}}; 30 } 31 @Test(dataProvider="test",priority=2) 32 public void userpassword(String a,String b) throws Exception { 33 driver.findElement(By.className("gray")).sendKeys(a); 34 Thread.sleep(1000); 35 driver.findElement(By.cssSelector("input[name='password']")).sendKeys(b); 36 Thread.sleep(1000); 37 System.out.println(a+":"+b); 38 driver.findElement(By.className("submit_login")).click(); 39 Thread.sleep(2000); 40 41 }
用戶名和密碼依次傳遞給變量a和b,重復登錄操作