<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      測試框架TestNG學(xué)習(xí)筆記

      一、TestNG的基本介紹和如何在maven中引用

      1、適合測試人員使用的原因
      1)比Junit涵蓋功能更全面的測試框架
      2)Junit更適合隔離性比較強(qiáng)的單元測試
      3)TestNG更適合復(fù)雜的集成測試

      2、TestNG的使用
      pom.xml的依賴包將信息都填寫好,maven框架將自動下載和使用。

      二、TestNG基本注解與執(zhí)行順序?qū)崙?zhàn)

      1、Idea創(chuàng)建一個(gè)項(xiàng)目和對應(yīng)的modle,目錄結(jié)構(gòu)如下:

      2.1 注解實(shí)戰(zhàn) @Test標(biāo)簽

      1、創(chuàng)建包 com.course.testng
      2、創(chuàng)建類 BasicAnnotation.java

      package com.course.testng;
      import org.testng.annotations.Test;
      
      public class BasicAnnotation{
          // 最基本的注解,用來把方法標(biāo)記成測試用例
          @Test
          public void testCase1(){
              System.out.println("這是測試用例1");
          }
      }
      

      1)@Test 需要 alt+enter 鍵,add ‘testng’ to classpath
      pom.xml文件會自動增加依賴:

      2)@Test 需要導(dǎo)入包
      import org.testng.annotations.Test;

      3、運(yùn)行結(jié)果

      @Test是最基本的注解,用來把方法標(biāo)記成測試用例

      2.2 注解實(shí)戰(zhàn) BeforeMethod和AfterMethod

      1、在測試方法之前運(yùn)行的標(biāo)簽 @BeforeMethod
      2、在測試方法之后運(yùn)行的標(biāo)簽 @AfterMethod

      3、多個(gè)測試方法執(zhí)行

      說明:如果有多個(gè)測試方法,在每一個(gè)測試方法之前和之后,BeforeMethod、AfterMethod都運(yùn)行一次。

      2.3 注解實(shí)戰(zhàn)BeforeClass和AfterClass

      1、在測試類之前運(yùn)行的標(biāo)簽 @BeforeClass
      2、在測試類之后運(yùn)行的標(biāo)簽 @AfterClass

      說明:BeforeClass 和 AfterClass在類中,只運(yùn)行一次。
      注冊對象,靜態(tài)方法,變量賦值等都可以用到。

      2.4 注解實(shí)戰(zhàn):BeforeSuite和AfterSuit

      1、BeforeSuite 在整個(gè)測試套件開始之前運(yùn)行
      2、AfterSuite 在整個(gè)測試套件結(jié)束之后運(yùn)行

      說明:BeforeSuit 和 AfterSuit 在類中,只運(yùn)行一次。

      • 關(guān)注點(diǎn)在于執(zhí)行順序:
      • beforeSuite --> beforeClass --> beforeMethod --> 測試方法1 --> afterMethod --> beforeMethod --> 測試方法2 --> afterMethod --> afterClass --> afterSuite

      2.5 Before/After注解總結(jié)

      代碼舉例:

      package com.course.test;
      import org.testng.annotations.*;
      
      public class BasicAnnotation {
      
          @Test
          public void testCase1(){
              System.out.println("這是測試用例1");
          }
      
          @Test
          public void testCase2(){
              System.out.println("這是測試用例2");
          }
      
          @BeforeMethod
          public void beforeMethod(){
              System.out.println("beforeMethod在測試方法運(yùn)行之前運(yùn)行");
          }
      
          @AfterMethod
          public void afterMethod(){
              System.out.println("afterMethod在測試方法運(yùn)行之后運(yùn)行");
          }
      
          @BeforeClass
          public void beforeClass(){
              System.out.println("beforeClass在類運(yùn)行之前運(yùn)行");
          }
      
          @AfterClass
          public void afterClass(){
              System.out.println("afterClass在類運(yùn)行之后運(yùn)行");
          }
      
          @BeforeSuite
          public void beforeSuite(){
              System.out.println("beforeSuite在類運(yùn)行之前運(yùn)行");
          }
      
          @AfterSuite
          public void afterSuite(){
              System.out.println("afterSuite在類運(yùn)行之后運(yùn)行");
          }
      }
      

      結(jié)果:

      beforeSuite在類運(yùn)行之前運(yùn)行
      beforeClass在類運(yùn)行之前運(yùn)行
      beforeMethod在測試方法運(yùn)行之前運(yùn)行
      這是測試用例1
      afterMethod在測試方法運(yùn)行之后運(yùn)行
      beforeMethod在測試方法運(yùn)行之前運(yùn)行
      這是測試用例2
      afterMethod在測試方法運(yùn)行之后運(yùn)行
      afterClass在類運(yùn)行之后運(yùn)行
      afterSuite在類運(yùn)行之后運(yùn)行
      

      三、套件測試

      測試套件是用于測試軟件程序的行為或一組行為的測試用例的集合。在TestNG中,我們無法定義一個(gè)套件,但它可以由一個(gè)XML文件表示,因?yàn)樘准菆?zhí)行的功能。它還允許靈活配置要運(yùn)行的測試。 套件可以包含一個(gè)或多個(gè)測試,并由標(biāo)記定義。

      • 是testng.xml的根標(biāo)記。 它描述了一個(gè)測試套件,它又由幾個(gè)部分組成。
      • 接收的所有定義的合法屬性。

      3.1 創(chuàng)建suite包

      創(chuàng)建類:suiteConfig.java、LoginTest.java、PayTest.java

      package com.course.test.suite;
      import org.testng.annotations.AfterSuite;
      import org.testng.annotations.AfterTest;
      import org.testng.annotations.BeforeSuite;
      import org.testng.annotations.BeforeTest;
      
      // 測試套件之前需要運(yùn)行的方法
      public class SuiteConfig {
          @BeforeSuite
          public void beforeSuite(){
              System.out.println("before Suite運(yùn)行了");
          }
      
          @AfterSuite
          public void afterSuite(){
              System.out.println("after Suite運(yùn)行了");
          }
      
          @BeforeTest
          public void beforeTest(){
              System.out.println("beforeTest");
          }
      
          @AfterTest
          public void afterTest(){
              System.out.println("afterTest");
          }
      }
      
      package com.course.test.suite;
      import org.testng.annotations.Test;
      
      // 寫測試類
      public class LoginTest {
          @Test
          public void loginTaobao(){
              System.out.println("淘寶登錄成功!");
          }
      }
      
      package com.course.test.suite;
      import org.testng.annotations.Test;
      
      public class PayTest {
          @Test
          public void paySuccess(){
              System.out.println("淘寶支付成功!");
          }
      }
      

      3.2 在 resources中創(chuàng)建suite.xml

      目錄:src/main/resources/suite.xml

      <?xml version="1.0" encoding="UTF-8" ?>
      
      <suite name="test">
          <test name="login">
              <classes>
                  <class name="com.course.test.suite.SuiteConfig" />
                  <class name="com.course.test.suite.LoginTest"/>
              </classes>
          </test>
      
          <test name="pay">
              <classes>
                  <class name="com.course.test.suite.SuiteConfig" />
                  <class name="com.course.test.suite.PayTest"/>
              </classes>
          </test>
      </suite>
      
      • 說明:使用suite.xml文件,該文件用來管理測試用例,并與運(yùn)行testNG。
        套件就是將所有測試類整理在一起,形成一套測試用例
        測試集是指測試模塊,一般一個(gè)項(xiàng)目可以按照模塊分幾部分,即不同的test
        測試集下的所有測試類
        具體測試類,name 屬性指定測試類的路徑
        測試類下具體的測試方法,如果不寫此標(biāo)簽,則默認(rèn)包含測試類下的所有方法

      3.3 運(yùn)行suite.xml文件

      運(yùn)行結(jié)果:

      說明:
      測試套件test中,有2個(gè)測試模塊login和pay。
      login模塊下的測試類是 SuiteConfig.java和LoginTest.java,執(zhí)行該測試類下所有方法。
      pay模塊下的測試類是 SuiteConfig.java和PayTest.java,執(zhí)行該測試類下所有方法。
      由于suite.xml只有一個(gè)測試套件test,所以beforeSuite()/afterSuite()只運(yùn)行一次。beforeTest()/afterTest()針對每個(gè)測試方法都執(zhí)行一次。測試方法 loginTaobao()、paySuccess() 分別執(zhí)行一次。

      四、忽略測試

      1、什么時(shí)忽略測試:本次測試執(zhí)行不想執(zhí)行該用例,或者編寫的代碼沒有準(zhǔn)備就緒,并且測試用例要測試該方法/代碼是否成功或失敗。
      使用注釋 @Test(enable=false) 禁用此測試用例,繞過該測試用例。

      2、新建 IgnoreTest.java

      package com.course.testng;
      import org.testng.annotations.Test;
      
      public class IgnoreTest {
          @Test
          public void ignore1(){
              System.out.println("ignore1 執(zhí)行!");
          }
      
          @Test(enabled = false)
          public void ignore2(){
              System.out.println("ignore2 執(zhí)行!");
          }
      
          @Test(enabled = true)
          public void ignore3(){
              System.out.println("ignore3 執(zhí)行!");
          }
      }
      

      執(zhí)行結(jié)果:

      ignore1 執(zhí)行!
      ignore3 執(zhí)行!
      

      說明: @Test(enabled = false) 的用例會被忽略

      五、分組測試

      分組測試允許你將方法調(diào)度到適當(dāng)?shù)牟糠郑?zhí)行復(fù)雜的測試方法分組。
      它不僅可以聲明屬于某個(gè)分組的方法,還可以指定包含其他組的組。然后調(diào)用 TestNG,并要求其包含一組特定的組(或正則表達(dá)式),同時(shí)排除另一個(gè)分組。
      組測試提供了如何分區(qū)測試的最大靈活性,如果您想要背靠背運(yùn)行兩組不同的測試,則不需要重新編譯任何內(nèi)容。
      使用 標(biāo)記在testng.xml文件中指定分組。 它可以在標(biāo)簽下找到。
      標(biāo)簽中指定分組適用于其下的所有標(biāo)簽。

      5.1 分組測試-方法分組測試

      1、新建組groups,新建類 GroupsOnMethod.java

      package com.course.testng.groups;
      import org.testng.annotations.AfterGroups;
      import org.testng.annotations.BeforeGroups;
      import org.testng.annotations.Test;
      
      public class GroupsOnMethod {
          @Test(groups = "server")
          public void test1(){
              System.out.println("這是服務(wù)端組的測試方法1111");
          }
      
          @Test(groups = "server")
          public void test2(){
              System.out.println("這是服務(wù)端組的測試方法2222");
          }
      
          @Test(groups = "client")
          public void test3(){
              System.out.println("這是客戶端組的測試方法3333");
          }
      
          @Test(groups = "client")
          public void test4(){
              System.out.println("這是客戶端組的測試方法4444");
          }
      
          @BeforeGroups("server")
          public void beforeGroupsOnServer(){
              System.out.println("這是服務(wù)端組運(yùn)行之前運(yùn)行的方法:beforeGroupsOnServer");
          }
      
          @AfterGroups("server")
          public void afterGroupsOnServer(){
              System.out.println("這是服務(wù)端組運(yùn)行之后運(yùn)行的方法:afterGroupsOnServer");
          }
      
          @BeforeGroups("client")
          public void beforeGroupsOnClient(){
              System.out.println("這是客戶端組運(yùn)行之前運(yùn)行的方法:beforeGroupsOnClient");
          }
      
          @AfterGroups("client")
          public void afterGroupsOnClient(){
              System.out.println("這是客戶端組運(yùn)行之后運(yùn)行的方法:afterGroupsOnClient");
          }
      }
      

      結(jié)果:

      這是服務(wù)端組運(yùn)行之前運(yùn)行的方法:beforeGroupsOnServer
      這是服務(wù)端組的測試方法1111
      這是服務(wù)端組的測試方法2222
      這是服務(wù)端組運(yùn)行之后運(yùn)行的方法:afterGroupsOnServer
      這是客戶端組運(yùn)行之前運(yùn)行的方法:beforeGroupsOnClient
      這是客戶端組的測試方法3333
      這是客戶端組的測試方法4444
      這是客戶端組運(yùn)行之后運(yùn)行的方法:afterGroupsOnClient
      

      說明:

      • 方法test1()、test2() 屬于分組server,beforeGroupsOnServer()在server組的方法執(zhí)行之前運(yùn)行,afterGroupsOnServer()在server組的方法執(zhí)行之后運(yùn)行;
      • 方法test3()、test4() 屬于分組client,beforeGroupsOnClient()在server組的方法執(zhí)行之前運(yùn)行,afterGroupsOnClient()在client組的方法執(zhí)行之后運(yùn)行。

      5.2 分組測試中-類分組測試

      1、新建組:groups,新建類 GroupsOnClass1.java、 GroupsOnClass2.java、GroupsOnClass3.java
      其中 GroupsOnClass1.java和GroupsOnClass2.java是一個(gè)分組stu;GroupsOnClass3.java是一個(gè)分組teacher

      package com.course.testng.groups;
      import org.testng.annotations.Test;
      
      @Test(groups = "stu")
      public class GroupsOnClass1 {
          public void stu1(){
              System.out.println("GroupsOnClass1 中的stu1111運(yùn)行");
          }
      
          public void stu2(){
              System.out.println("GroupsOnClass1 中的stu2222運(yùn)行");
          }
      }
      package com.course.testng.groups;
      import org.testng.annotations.Test;
      @Test(groups = "stu")
      public class GroupsOnClass2 {
          public void stu1(){
              System.out.println("GroupsOnClass2 中的stu1111運(yùn)行");
          }
      
          public void stu2(){
              System.out.println("GroupsOnClass2 中的stu2222運(yùn)行");
          }
      }
      
      package com.course.testng.groups;
      import org.testng.annotations.Test;
      
      @Test(groups = "teacher")
      public class GroupsOnClass3 {
          public void teacher1(){
              System.out.println("GroupsOnClass3 中的teacher1111運(yùn)行");
          }
      
          public void teacher2(){
              System.out.println("GroupsOnClass3 中的teacher2222運(yùn)行");
          }
      }
      

      2、新建 groupsOnClass.xml

      <?xml version="1.0" encoding="UTF-8" ?>
      
      <suite name="suitename">
          <test name="runAll">
              <classes>
                  <class name="com.course.testng.groups.GroupsOnClass1"/>
                  <class name="com.course.testng.groups.GroupsOnClass2"/>
                  <class name="com.course.testng.groups.GroupsOnClass3"/>
              </classes>
          </test>
      
          <test name="OnlyRunStu">
              <groups>
                  <run>
                      <include name="stu"/>
                  </run>
              </groups>
              <classes>
                  <class name="com.course.testng.groups.GroupsOnClass1"/>
                  <class name="com.course.testng.groups.GroupsOnClass2"/>
                  <class name="com.course.testng.groups.GroupsOnClass3"/>
              </classes>
          </test>
      </suite>
      

      說明:
      測試套件suitename中有2個(gè)測試模塊,runAllOnlyRunStu
      runAll模塊下的測試類是 GroupsOnClass1.java、GroupsOnClass2.java、GroupsOnClass3.java,執(zhí)行該測試類下所有方法。
      OnlyRunStu模塊下的測試類是 GroupsOnClass1.java、GroupsOnClass2.java、GroupsOnClass3.java,只執(zhí)行分組為 stu 的類下的方法。

      3、運(yùn)行xml文件,結(jié)果:

      GroupsOnClass1 中的stu1111運(yùn)行
      GroupsOnClass1 中的stu2222運(yùn)行
      GroupsOnClass2 中的stu1111運(yùn)行
      GroupsOnClass2 中的stu2222運(yùn)行
      GroupsOnClass3 中的teacher1111運(yùn)行
      GroupsOnClass3 中的teacher2222運(yùn)行
      GroupsOnClass1 中的stu1111運(yùn)行
      GroupsOnClass1 中的stu2222運(yùn)行
      GroupsOnClass2 中的stu1111運(yùn)行
      GroupsOnClass2 中的stu2222運(yùn)行
      

      六、異常測試

      1、什么時(shí)候會用到異常測試
      在我們期望結(jié)果為某個(gè)異常時(shí),比如:我們傳入了某些不合法參數(shù),程序拋出了異常。也就是說預(yù)期結(jié)果就是該異常。
      2、運(yùn)行時(shí)異常和非運(yùn)行時(shí)異常

      3、舉例
      1)新建 ExpectedException.java

      package com.course.testng;
      import org.testng.annotations.Test;
      
      public class ExpectedException {
          // 這是一個(gè)結(jié)果會失敗的異常
          @Test(expectedExceptions = RuntimeException.class)
          public void runTimeExceptionFailed(){
              System.out.println("這是一個(gè)失敗的異常測試");
          }
      
          // 這是一個(gè)成功的異常測試
          @Test(expectedExceptions = RuntimeException.class)
          public void runTimeExceptionSuccess(){
              System.out.println("這是我的異常測試!");
              throw new RuntimeException();
          }
      }
      

      2)結(jié)果:兩個(gè)用例,pass一個(gè),fail一個(gè)

      七、依賴測試

      7.1 依賴測試

      有時(shí)我們可能需要以特定順序調(diào)用測試用例中的方法,或者希望在方法之間共享一些數(shù)據(jù)和狀態(tài)。
      TestNG支持這種依賴關(guān)系,因?yàn)樗С衷跍y試方法之間顯式依賴的聲明。
      TestNG允許指定依賴關(guān)系:

      • @Test注解中使用屬性 dependsOnMethods
      • @Test注解中使用屬性 dependsOnGroups
        在TestNG中,我們使用dependOnMethodsdependsOnGroups 來實(shí)現(xiàn)依賴測試。 如果依賴方法失敗,則將跳過所有后續(xù)測試方法。
        舉例:test1() 依賴于 test2()

      7.2 dependsOnMethods

      1、如果test1()成功,則執(zhí)行test2()
      新建 DependTest.java

      package com.course.testng;
      import org.testng.annotations.Test;
      
      public class DependTest {
          @Test
          public void test1(){
              System.out.println("test1 run");
          }
      
          @Test(dependsOnMethods = {"test1"})
          public void test2(){
              System.out.println("test2 run");
          }
      }
      

      只運(yùn)行 test2() ,結(jié)果:

      2、如果test1()失敗,則跳過test2()
      修改test1(),使得其運(yùn)行失敗;test2 依賴的方法失敗,自己也不會運(yùn)行成功

      package com.course.testng;
      import org.testng.annotations.Test;
      
      public class DependTest {
          @Test
          public void test1(){
              System.out.println("test1 run");
              throw new RuntimeException();
          }
      
          @Test(dependsOnMethods = {"test1"})
          public void test2(){
              System.out.println("test2 run");
          }
      }
      

      只運(yùn)行 test2() ,結(jié)果:用例執(zhí)行失敗一個(gè),忽略一個(gè)

      7.3 dependsOnGroups

      1、創(chuàng)建java文件:TestServer.java

      package com.course.testng.depend;
      
      import org.testng.annotations.Test;
      
      @Test(groups = "deploy")
      public class TestServer {
          @Test
          public void deployServer(){
              System.out.println("運(yùn)行服務(wù)");
          }
      
          @Test(dependsOnMethods = "deployServer")
          public void deployBackUpServer(){
              System.out.println("如果方法deployServer()成功則運(yùn)行");
          }
      }
      

      2、創(chuàng)建 TestDatabase.java

      package com.course.testng.depend;
      
      import org.testng.annotations.Test;
      
      public class TestDatabase {
      
          @Test(groups = "db",dependsOnGroups = "deploy")
          public void initDB(){
              System.out.println("這是initDB方法");
          }
      
          @Test(dependsOnMethods = {"initDB"},groups = "db")
          public void testConnection(){
              System.out.println("這是testConnection方法");
          }
      }
      

      3、創(chuàng)建TestApp.java

      package com.course.testng.depend;
      
      import org.testng.annotations.Test;
      
      public class TestApp {
          @Test(dependsOnGroups = {"deploy","db"})
          public void method1(){
              System.out.println("這是方法1");
          }
      
          @Test(dependsOnMethods = "method1")
          public void method2(){
              System.out.println("這是方法2");
          }
      }
      

      4、在resource文件下創(chuàng)建depend.xml

      <?xml version="1.0" encoding="UTF-8" ?>
      <suite name="TestDependency">
          <test name="TestCase1">
              <classes>
                  <class name="com.course.testng.depend.TestApp">
                  </class>
                  <class name="com.course.testng.depend.TestDatabase">
                  </class>
                  <class name="com.course.testng.depend.TestServer">
                  </class>
              </classes>
          </test>
      </suite>
      

      5、執(zhí)行結(jié)果:

      八、參數(shù)化測試

      8.1 參數(shù)化測試-xml文件參數(shù)化

      1、如何通過外部或內(nèi)部傳遞參數(shù)
      2、創(chuàng)建包 parameter,創(chuàng)建類 ParameterTest.java

      package com.course.testng.parameter;
      import org.testng.annotations.Parameters;
      import org.testng.annotations.Test;
      
      public class ParameterTest {
          @Test
          @Parameters({"name","age"})
          public void paramTest1(String name,String age){
              System.out.println("name = "+name+"; age = "+age);
          }
      }
      

      3、創(chuàng)建Parameter.xml文件

      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
      <suite name="All Test Suite">
          <test verbose="2" preserve-order="true" name="D:/testngDemo">
              <parameter name="name" value="tom"/>
              <parameter name="age" value="18"/>
              <classes>
                  <class name="com.course.testng.parameter.ParameterTest"/>
              </classes>
          </test>
      </suite>
      

      4、運(yùn)行xml文件,運(yùn)行結(jié)果

      8.2 參數(shù)化測試-DataProvider

      1、第一種參數(shù)化方式其實(shí)比較雞肋,第二種方式才是TestNG參數(shù)化的靈魂,用到了@DataProvider,它會返回一個(gè)二維數(shù)組:

      package org.example;
      
      import org.testng.Assert;
      import org.testng.annotations.*;
       
      public class AppTest {
          // 定義一個(gè)數(shù)據(jù)提供器,叫test01,返回二維數(shù)組
          @DataProvider(name = "test01")
          public Object[][] data() {
              return new Object[][] {
                      {"tom", 18},
                      {"jack", 20}
              };
          }
          
          // 引用這個(gè)數(shù)據(jù)提供器
          @Test(dataProvider = "test01")
          public void test01(String name, int age){
              System.out.println(name + ": " + age);
          }
      }
      

      結(jié)果:

      切記:

      • @DataProvider用于生產(chǎn)數(shù)據(jù),name是唯一標(biāo)識。
      • 在@Test中通過dataProvider屬性指定name。
      • 測試方法的入?yún)⒏鷶?shù)組中元素一一對應(yīng)。

      2、Iterator
      @DataProvide的返回值(參數(shù)類型)除了已經(jīng)提到的Object[][],還可以時(shí)Iterator,它不會一次性生成所有數(shù)據(jù),而是每調(diào)用一次生成一次,節(jié)約內(nèi)存。

      package com.course.testng.parameter;
      import org.testng.annotations.DataProvider;
      import org.testng.annotations.Test;
      import java.util.Arrays;
      import java.util.Iterator;
      
      public class ParameterTest3 {
          @DataProvider(name = "test01")
          public Iterator<Object[]> data(){
              Object[][] myObject = new Object[][]{
                      {"tom",18},
                      {"jack",20}
              };
              return Arrays.asList(myObject).iterator();
          }
          @Test(dataProvider = "test01")
          public void test01(String name,int age){
              System.out.println(name+":"+age);
          }
      }
      

      結(jié)果:

      總結(jié):DataProvider支持?jǐn)?shù)組、迭代器

      3、通過方法名傳遞參數(shù)

      package com.course.testng.parameter;
      import org.testng.annotations.DataProvider;
      import org.testng.annotations.Test;
      import java.lang.reflect.Method;
      
      public class ParameterTest4 {
          @Test(dataProvider = "methodData")
          public void test1(String name,int age){
              System.out.println("test1方法 name="+name+";age="+age);
          }
      
          @Test(dataProvider = "methodData")
          public void test2(String name,int age){
              System.out.println("test2方法 name="+name+";age="+age);
          }
      
          @DataProvider(name = "methodData")
          public Object[][] methodDataTest(Method method){
              Object[][] result = null;
              if (method.getName().equals("test1")){
                  result = new Object[][]{
                          {"hqq1",18},
                          {"hqq2",19}
                  };
              }else if (method.getName().equals("test2")){
                  result = new Object[][]{
                          {"guihua1",20},
                          {"guihua2",22}
                  };
              }
              return  result;
          }
      }
      

      結(jié)果:
      test1方法 name=hqq1;age=18
      test1方法 name=hqq2;age=19
      test2方法 name=guihua1;age=20
      test2方法 name=guihua2;age=22

      九、多線程測試

      實(shí)現(xiàn)testng多線程的兩種方式:

      • 注解實(shí)現(xiàn)
      • xml實(shí)現(xiàn)

      9.1 注解實(shí)現(xiàn)

      package com.course.testng.thread;
      import org.testng.annotations.Test;
      
      public class MultiThreadByAnnotation {
          /**
           * threadPoolSize 為線程池內(nèi)可使用的線程數(shù)
           * 使用threadPoolSize個(gè)線程,將test方法執(zhí)行invocationCount次
           * timeOut配置的是每次執(zhí)行該測試方法所耗費(fèi)時(shí)間的閾值,超過閾值則測試失敗
           */
          @Test(invocationCount = 10,threadPoolSize = 3,timeOut = 1000)
          public void test(){
              System.out.println("hello");
              System.out.println("Thread Id:"+Thread.currentThread().getId());
          }
      }
      

      執(zhí)行結(jié)果:使用了3個(gè)線程,將測試方法test執(zhí)行了10次。

      hello
      hello
      hello
      Thread Id:12
      Thread Id:13
      Thread Id:14
      hello
      hello
      Thread Id:12
      hello
      Thread Id:14
      Thread Id:13
      hello
      Thread Id:12
      Thread Id:14
      hello
      hello
      Thread Id:13
      hello
      Thread Id:12
      

      9.2 xml實(shí)現(xiàn)test、class、method級別的并發(fā)

      1)需要在 testng.xml中suite tag下設(shè)置

      <suite name="Testng Parallel Test" parallel="tests" thread-count="5">
      <suite name="Testng Parallel Test" parallel="classes" thread-count="5">
      <suite name="Testng Parallel Test" parallel="methods" thread-count="5">
      

      他們的共同點(diǎn)都是最多起5個(gè)線程去同時(shí)執(zhí)行不同的用例。thread-count 代表最大并發(fā)線程數(shù)。
      他們的區(qū)別如下:

      • method級別:所有用例都可以在不同的線程去執(zhí)行
      • class級別:不同class tag 下的用例,在不同的線程執(zhí)行;相同class tag下的用例只能在同一個(gè)線程中執(zhí)行
      • tests級別:不同test tag 下的用例,在不同的線程執(zhí)行;相同test tag下的用例只能在同一個(gè)線程中執(zhí)行
        意義:可以將非線程安全的測試類或group統(tǒng)一放到一個(gè)test中,這樣在并發(fā)的同時(shí)又可以保證這些類里面的用例是單線程執(zhí)行。也可以根據(jù)需要設(shè)定class級別的并發(fā),讓同一個(gè)測試類里的用例在同一個(gè)線程中執(zhí)行。
        補(bǔ)充:xml文件配置這種方式不能指定線程池,只有方法上才可以指定線程池。

      2)舉例實(shí)現(xiàn)1:methods

      package com.course.testng.thread;
      import org.testng.annotations.Test;
      
      public class MultiThreadByXml {
          @Test
          public void test1(){
              System.out.println("test1---Thread Id :  " + Thread.currentThread().getId());
          }
      
          @Test
          public void test2(){
              System.out.println("test2---Thread Id :  " + Thread.currentThread().getId());
          }
      
          @Test
          public void test3(){
              System.out.println("test3---Thread Id :  " + Thread.currentThread().getId());
          }
      }
      

      新增multiThread.xml文件:

      <?xml version="1.0" encoding="UTF-8" ?>
      <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
      
      <!--parallel="methods",表示多線程級別為方法級別-->
      <!--thread-count="2",表示線程數(shù)為2-->
      <suite name="thread" parallel="methods" thread-count="2">
          <test name="demo1">
              <classes>
                  <class name="com.course.testng.thread.MultiThreadByXml"/>
              </classes>
          </test>
      </suite>
      

      執(zhí)行xml文件:

      說明:所有用例都可以在不同的線程去執(zhí)行。

      3)舉例實(shí)現(xiàn)2:classes

      新增 MultiThreadByXml.java、MultiThreadByXml2.java、MultiThreadByXml3.java

      package com.course.testng.thread;
      import org.testng.annotations.Test;
      
      public class MultiThreadByXml {
          @Test
          public void test1(){
              System.out.println("test1---Thread Id :  " + Thread.currentThread().getId());
          }
          @Test
          public void test2(){
              System.out.println("test2---Thread Id :  " + Thread.currentThread().getId());
          }
          @Test
          public void test3(){
              System.out.println("test3---Thread Id :  " + Thread.currentThread().getId());
          }
      }
      
      package com.course.testng.thread;
      import org.testng.annotations.Test;
      
      public class MultiThreadByXml2 {
          @Test
          public void test1(){
              System.out.println("test21---Thread Id :  " + Thread.currentThread().getId());
          }
          @Test
          public void test2(){
              System.out.println("test22---Thread Id :  " + Thread.currentThread().getId());
          }
          @Test
          public void test3(){
              System.out.println("test23---Thread Id :  " + Thread.currentThread().getId());
          }
      }
      
      package com.course.testng.thread;
      import org.testng.annotations.Test;
      
      public class MultiThreadByXml3 {
          @Test
          public void test1(){
              System.out.println("test31---Thread Id :  " + Thread.currentThread().getId());
          }
          @Test
          public void test2(){
              System.out.println("test32---Thread Id :  " + Thread.currentThread().getId());
          }
          @Test
          public void test3(){
              System.out.println("test33---Thread Id :  " + Thread.currentThread().getId());
          }
      }
      

      說明:改xml的配置

      <?xml version="1.0" encoding="UTF-8" ?>
      <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
      
      <!--parallel="classes",表示多線程級別為class-->
      <!--thread-count="2",表示線程數(shù)為2-->
      <suite name="thread" parallel="classes" thread-count="2">
          <test name="demo1">
              <classes>
                  <class name="com.course.testng.thread.MultiThreadByXml"></class>
                  <class name="com.course.testng.thread.MultiThreadByXml2"></class>
              </classes>
          </test>
      
          <test name="demo2">
              <classes>
                  <class name="com.course.testng.thread.MultiThreadByXml3"></class>
              </classes>
          </test>
      </suite>
      

      結(jié)果:

      說明:不同class tag下的用例可以在不同線程中執(zhí)行;同一個(gè)class tag標(biāo)簽下的用例只能在同一個(gè)線程中執(zhí)行。

      4)舉例實(shí)現(xiàn)3:tests

      代碼同上一個(gè)例子,只改xml文件

      <?xml version="1.0" encoding="UTF-8" ?>
      <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
      <!--parallel="tests",表示多線程級別為test級別-->
      <!--thread-count="2",表示線程數(shù)為2-->
      <suite name="thread" parallel="tests" thread-count="2">
          <test name="demo1">
              <classes>
                  <class name="com.course.testng.thread.MultiThreadByXml"></class>
              </classes>
          </test>
      
          <test name="demo2">
              <classes>
                  <class name="com.course.testng.thread.MultiThreadByXml2"></class>
              </classes>
          </test>
      </suite>
      


      說明:不同test tag下的用例可以在不同的線程執(zhí)行,相同test tag下的用例只能在同一個(gè)線程中執(zhí)行。

      9.3 多線程總結(jié)

      參考文檔:https://testerhome.com/topics/7895

      9.3.1 多線程并發(fā)執(zhí)行

      必須要指出的是,通過多線程執(zhí)行用例時(shí)雖然可以大大提升用例的執(zhí)行效率,但是我們在設(shè)計(jì)用例時(shí)也要考慮到這些用例是否適合并發(fā)執(zhí)行,以及要注意多線程方式的通病:線程安全與共享變量的問題。建議是在測試代碼中,盡可能地避免使用共享變量。如果真的用到了,要慎用 synchronized 關(guān)鍵字來對共享變量進(jìn)行加鎖同步。否則,難免你的用例執(zhí)行時(shí)可能會出現(xiàn)不穩(wěn)定的情景(經(jīng)常聽到有人提到用例執(zhí)行地不穩(wěn)定,有時(shí) 100% 通過,有時(shí)只有 90% 通過,猜測可能有一部分原因也是這個(gè)導(dǎo)致的)。

      9.3.2 不同級別的并發(fā)

      通常,在 TestNG 的執(zhí)行中,測試的級別由上至下可以分為suite -> test -> class -> method,箭頭的左邊元素跟右邊元素的關(guān)系是一對多的包含關(guān)系。
      這里的 test 指的是 testng.xml 中的 test tag,而不是測試類里的一個(gè)@Test。測試類里的一個(gè)@Test實(shí)際上對應(yīng)這里的 method。所以我們在使用@BeforeSuite、@BeforeTest、@BeforeClass、@BeforeMethod這些標(biāo)簽的時(shí)候,它們的實(shí)際執(zhí)行順序也是按照這個(gè)級別來的。
      1)suite
      一般情況下,一個(gè) testng.xml 只包含一個(gè) suite。如果想起多個(gè)線程執(zhí)行不同的 suite,官方給出的方法是:通過命令行的方式來指定線程池的容量。
      java org.testng.TestNG -suitethreadpoolsize 3 testng1.xml testng2.xml testng3.xml
      即可通過三個(gè)線程來分別執(zhí)行 testng1.xml、testng2.xml、testng3.xml。
      實(shí)際上這種情況在實(shí)際中應(yīng)用地并不多見,我們的測試用例往往放在一個(gè) suite 中,如果真需要執(zhí)行不同的 suite,往往也是在不同的環(huán)境中去執(zhí)行,屆時(shí)也自然而然會做一些其他的配置(如環(huán)境變量)更改,會有不同的進(jìn)程去執(zhí)行。因此這種方式不多贅述。

      2)test, class, method
      test,class,method 級別的并發(fā),可以通過在 testng.xml 中的 suite tag 下設(shè)置。

      • tests 級別:不同 test tag 下的用例可以在不同的線程執(zhí)行,相同 test tag 下的用例只能在同一個(gè)線程中執(zhí)行。
      • classs 級別:不同 class tag 下的用例可以在不同的線程執(zhí)行,相同 class tag 下的用例只能在同一個(gè)線程中執(zhí)行。
      • methods 級別:所有用例都可以在不同的線程去執(zhí)行。

      十、超時(shí)測試

      10.1 套件級別的超時(shí)測試示例

      public class TimeoutSuite 
      {
          @Test
          public void timeTestOne() throws InterruptedException {
              Thread.sleep(1000);
              System.out.println("Time test method one");
          }
          
          @Test
          public void timeTestTwo() throws InterruptedException {
              Thread.sleep(400);
              System.out.println("Time test method two");
          }
      }
      

      添加對應(yīng)的testng.xml文件

      <suite name="Time test Suite" time-out="500" verbose="1" >
        <test name="Timeout Test" >
          <classes>
            <class name="com.howtodoinjava.test.TimeoutSuite"/>
          </classes>
        </test>
      </suite>
      

      運(yùn)行結(jié)果:

      [TestNG] Running: C:\somepath\TestNGExamples\testng.xml
      
      Time test method two
      
      ===============================================
      Time test Suite
      Total tests run: 2, Failures: 1, Skips: 0
      ===============================================
      

      從測試結(jié)果中可以看出,只有timeTestTwo()被執(zhí)行,因?yàn)樗膱?zhí)行時(shí)間少于testng.xml文件中定義的超時(shí)時(shí)間。
      timeTestOne()執(zhí)行被取消,因?yàn)閳?zhí)行完成所需的時(shí)間,超過配置的超時(shí)時(shí)間。

      10.2 方法級別的超時(shí)測試

      public class TimeoutSuite 
      {
          @Test(timeOut=500)
          public void timeTestOne() throws InterruptedException {
              Thread.sleep(1000);
              System.out.println("Time test method one");
          }
          
          @Test(timeOut=500)
          public void timeTestTwo() throws InterruptedException {
              Thread.sleep(400);
              System.out.println("Time test method two");
          }
      }
      

      執(zhí)行結(jié)果:

      [[TestNG] Running: C:\Users\somepath\testng-customsuite.xml
      Time test method two
      PASSED: timeTestTwo
      FAILED: timeTestOne
      
      org.testng.internal.thread.ThreadTimeoutException: Method org.testng.internal.TestNGMethod.timeTestOne() didn't finish within the time-out 500
      
      ===============================================
          Default test
          Tests run: 2, Failures: 1, Skips: 0
      ===============================================
      

      說明:@Test(timeOut=xxx) 指定超時(shí)時(shí)間,單位為毫秒。

      十一、軟斷言和硬斷言

      TestNG提供兩種斷言方式,分別是硬斷言或或者軟斷言,類似于pytest里面的斷言和多重?cái)嘌浴?br> 硬斷言時(shí)Assert直接調(diào)用靜態(tài)方法,軟斷言需要實(shí)例化,才能調(diào)用斷言方法。
      硬斷言(Assert):當(dāng)一個(gè)測試用例中存在多個(gè)斷言,當(dāng)有一個(gè)斷言失敗時(shí),則會拋出異常,不再執(zhí)行該用例中后續(xù)的斷言;
      軟斷言(SoftAssert):當(dāng)一個(gè)測試用例中存在多個(gè)斷言,當(dāng)有一個(gè)斷言失敗時(shí),會執(zhí)行后續(xù)的斷言。

      11.1 硬斷言

      Assert.assertEquals(actual,expected)            查看兩個(gè)對象是否相等;類似于字符串比較實(shí)用equals()方法
      Assert.assertNotEquals(actual,expected)    查看兩個(gè)對象是否不相等;
      Assert.assertNull(object)                              查看對象是否為空;
      Assert.assertNotNull(object)                查看對象是否不為空;
      Assert.assertSame(actual,expected)        查看兩個(gè)對象的引用是否相等,類似于使用“==”比較兩個(gè)對象
      Assert.assertNotSame(actual,expected)    查看兩個(gè)對象的引用是否不相等,類似于使用“!=”比較兩個(gè)對象
      Assert.assertTrue(condition)                判斷條件是否為true
      Assert.assertFalse(condition)                判斷條件是否為false
      assertArrayEquals(actual,expected)        判斷兩個(gè)數(shù)組是否相等。
      Assert.fail();                            讓測試用例失敗
      

      11.2 軟斷言

      SoftAssert的特點(diǎn):

      1. 如果一個(gè)斷言失敗,會繼續(xù)執(zhí)行這個(gè)斷言下的其他語句或者斷言
      2. 也就是一個(gè)用例有多個(gè)斷言,失敗了其中一個(gè),不影響其他斷言的運(yùn)行
      3. 千萬不要忘記在該用例的最后一個(gè)斷言后面調(diào)用assertAll(),否則斷言不執(zhí)行

      總結(jié)
      在實(shí)際的測試工作中,一個(gè)測試用例中往往包含多個(gè)斷言,更適合用軟斷言,一個(gè)斷言失敗,不影響其他的斷言。可能會有疑問,不管是軟斷言還是硬斷言,當(dāng)用例失敗時(shí),都需要我們?nèi)藶榈娜z查錯誤,認(rèn)為兩者是沒有區(qū)別的。
      其實(shí)還是有區(qū)別的,硬斷言報(bào)錯時(shí)只知道當(dāng)前斷言異常,并不知道后續(xù)斷言是否成功。只調(diào)整了當(dāng)前的斷言,之后再次運(yùn)行腳本,后續(xù)斷言還有出錯的概率,需要反復(fù)運(yùn)行確定斷言的正確性,很是耽誤測試時(shí)間,影響工作效率。而軟斷言呢?可以知道所有失敗的斷言,可以統(tǒng)一進(jìn)行調(diào)整。

      posted @ 2023-12-12 11:29  hqq的進(jìn)階日記  閱讀(195)  評論(0)    收藏  舉報(bào)
      主站蜘蛛池模板: 亚洲精品色一区二区三区| 四虎永久精品在线视频| 亚洲不卡一区三区三区四| 亚洲成人精品综合在线| 人成午夜免费视频在线观看| 亚洲男人第一无码av网| 人妻av一区二区三区av免费| 国产精品自拍视频免费看| 日韩中文字幕有码av| 静乐县| 亚洲嫩模一区二区三区| 艳妇乳肉豪妇荡乳xxx| 延吉市| 中文国产不卡一区二区| 老司机精品成人无码av| 亚洲人妻一区二区精品| 激情综合色综合啪啪五月| 中文字幕精品亚洲无线码二区| 国产精品自在线拍国产手机版| 好吊视频一区二区三区在线| 久久这里都是精品二| 亚洲综合av一区二区三区| 亚洲 自拍 另类 欧美 综合| 老司机午夜精品视频资源| 人妻中文字幕精品系列| 南宁市| 天堂av网一区二区三区| 无码熟妇αⅴ人妻又粗又大| 亚洲春色在线视频| 精品人妻无码中文字幕在线| 波多野结衣久久一区二区| 国产综合视频精品一区二区| 国产二区三区不卡免费| 国产午夜伦伦午夜伦无码| 高清破外女出血AV毛片| 麻花传媒免费网站在线观看| 午夜成人无码福利免费视频 | 好紧好湿好黄的视频| 亚洲欧美日韩成人综合一区 | 国产绿帽在线视频看| 久女女热精品视频在线观看|