您的位置:軟件測試 > 開源軟件測試 > 開源單元測試工具 > TestNG
TestNG系列教程:并行執(zhí)行測試
作者:網(wǎng)絡(luò)轉(zhuǎn)載 發(fā)布時(shí)間:[ 2015/3/5 11:05:08 ] 推薦標(biāo)簽:TestNG 單元測試 軟件測試

  并行(多線程)技術(shù)在軟件術(shù)語里被定義為軟件、操作系統(tǒng)或者程序可以并行地執(zhí)行另外一段程序中多個(gè)部分或者子組件的能力。TestNG允許我們以并行(多線程)的方式來執(zhí)行測試。這意味著基于TestNG測試組件的配置,多個(gè)線程可以被同時(shí)啟動(dòng)然后分別執(zhí)行各自的測試方法。相對于傳統(tǒng)的單線程執(zhí)行測試的方式,這種多線程方式擁有很大的優(yōu)勢,主要是它可以減少測試運(yùn)行時(shí)間,并且可以驗(yàn)證某段代碼在多線程環(huán)境中運(yùn)行的正確性。
  目錄
  1.并行執(zhí)行測試的優(yōu)勢
  2.如何并行地執(zhí)行測試方法
  3.如何并行地執(zhí)行測試類
  4.如何并行地執(zhí)行同一測試套件內(nèi)的各個(gè)測試組件
  5.如何配置需要在多線程環(huán)境中執(zhí)行的測試方法
  并行執(zhí)行測試的優(yōu)勢
  并行(多線程)執(zhí)行測試可以給用戶帶來很多好處,主要包括以下兩點(diǎn):
  1)減少了執(zhí)行時(shí)間:并行測試也意味著多個(gè)測試可以在同一時(shí)間被同時(shí)執(zhí)行,從而減少了整體測試所花費(fèi)的時(shí)間。
  2)允許多個(gè)線程并行地測試同一個(gè)測試組件:有了這個(gè)特性,我們能夠?qū)懗鱿鄳?yīng)的測試用例來驗(yàn)證應(yīng)用程序中包含多線程部分的代碼的正確性。
  以上特性被廣泛地應(yīng)用在QA領(lǐng)域的自動(dòng)化功能測試方面。通過簡單的配置,QA人員可以很輕松地使得他們的測試用例在多個(gè)瀏覽器或者操作系統(tǒng)中并行地執(zhí)行。
  TestNG提供了三種不同類型的配置方案來實(shí)現(xiàn)并行測試。
  如何并行地執(zhí)行測試方法
  TestNG為我們提供了多種方式來實(shí)現(xiàn)并行測試,其中一種是每一個(gè)獨(dú)立的線程分別執(zhí)行各自的測試方法。這種方式能夠顯著地減少測試執(zhí)行時(shí)間,這是因?yàn)楫?dāng)有越多的測試方法被并行執(zhí)行時(shí),總體測試消耗時(shí)間將會(huì)越少。
  上述測試類包含了兩個(gè)測試方法,每個(gè)測試方法在執(zhí)行時(shí)都會(huì)在控制臺(tái)中打印出一條信息。每個(gè)測試方法以及它們各自的beforeMehod、afterMethod方法都會(huì)通過Thread.currentThread.getId()這段代碼打印出執(zhí)行該測試方法的線程的ID。
  在項(xiàng)目中新建一個(gè)名為methods-test-testng.xml的文件并將下述代碼寫入該文件中。
  在Eclipse中選中該文件并且以TestNG測試套件方式運(yùn)行它。你將會(huì)在控制臺(tái)中看到以下輸出信息:
  注意:上述截圖中的ThreadId可能與你本地控制臺(tái)中輸出的ThreadId不同,這是因?yàn)門hreadId的值是在程序運(yùn)行時(shí)由JVM動(dòng)態(tài)指派的。
  從上述測試結(jié)果中我們可以很清晰地看出:上述兩個(gè)測試方法以及各自相應(yīng)的beforeMethod和afterMethod方法是在兩個(gè)獨(dú)立的線程中執(zhí)行的。我們可以通過在控制臺(tái)中輸出的ThreadId來證明這一點(diǎn)。
  如何并行地執(zhí)行測試類
  在下個(gè)例子中,我們會(huì)說明如何并行地執(zhí)行測試類:同一個(gè)測試組件(test execution)中的各個(gè)測試類將會(huì)在獨(dú)立的線程中并行地執(zhí)行。
  ParallelClassesTestOne.java
  ParallelClassesTestTwo.java
  在項(xiàng)目中新建一個(gè)名為classes-test-testng.xml的文件并將下述代碼寫入該文件中:
  在Eclipse中選中該文件并且以TestNG測試套件方式運(yùn)行它。你將會(huì)在控制臺(tái)中看到以下輸出信息:
  從上述測試結(jié)果中我們可以很清晰地看出:上述兩個(gè)測試類以及各自相應(yīng)的beforeClass和afterClass方法是在獨(dú)立的兩個(gè)線程中執(zhí)行的。我們可以通過在控制臺(tái)中輸出的ThreadId來證明這一點(diǎn)。
  如何并行地執(zhí)行同一測試套件內(nèi)的各個(gè)測試組件
  接下來我們會(huì)一起學(xué)習(xí)如何并行地執(zhí)行同一個(gè)測試套件內(nèi)的各個(gè)測試組件,即各個(gè)測試組件會(huì)分別在獨(dú)立的線程中執(zhí)行。
  packagecom.howtodoinjava.parallelism;
  importorg.testng.annotations.AfterClass;
  importorg.testng.annotations.AfterTest;
  importorg.testng.annotations.BeforeClass;
  importorg.testng.annotations.BeforeTest;
  importorg.testng.annotations.Parameters;
  importorg.testng.annotations.Test;
  publicclassParallelSuiteTest
  {
  String testName="";
  @BeforeTest
  @Parameters({"test-name"})
  publicvoidbeforeTest(String testName){
  this.testName=testName;
  longid=Thread.currentThread().getId();
  System.out.println("Before test"+testName+".Thread id is:"+id);
  }
  @BeforeClass
  publicvoidbeforeClass(){
  longid=Thread.currentThread().getId();
  System.out.println("Before test-class"+testName+".Thread id is:"
  +id);
  }
  @Test
  publicvoidtestMethodOne(){
  longid=Thread.currentThread().getId();
  System.out.println("Sample test-method"+testName
  +".Thread id is:"+id);
  }
  @AfterClass
  publicvoidafterClass(){
  longid=Thread.currentThread().getId();
  System.out.println("After test-method"+testName
  +".Thread id is:"+id);
  }
  @AfterTest
  publicvoidafterTest(){
  longid=Thread.currentThread().getId();
  System.out.println("After test"+testName+".Thread id is:"+id);
  }
  }
  在項(xiàng)目中新建一個(gè)名為suite-test-testng.xml的文件并將以下代碼寫入該文件中:
  <suitename="Test-class Suite"parallel="tests"thread-count="2">
  <testname="Test-class test 1">
  <parametername="test-name"value="test-method One"/>
  <classes>
  <classname="com.howtodoinjava.parallelism.ParallelSuiteTest"/>
  </classes>
  </test>
  <testname="Test-class test 2">
  <parametername="test-name"value="test-method One"/>
  <classes>
  <classname="com.howtodoinjava.parallelism.ParallelSuiteTest"/>
  </classes>
  </test>
  </suite>
  在Eclipse中選中該文件并且以TestNG測試套件方式運(yùn)行它。你將會(huì)在控制臺(tái)中看到以下輸出信息:
  Before test Test One.Thread id is:9
  Before test Test Two.Thread id is:10
  Before test-classTest One.Thread id is:9
  Before test-classTest Two.Thread id is:10
  Sample test-method Test One.Thread id is:9
  Sample test-method Test Two.Thread id is:10
  After test-method Test Two.Thread id is:10
  After test-method Test One.Thread id is:9
  After test Test One.Thread id is:9
  After test Test Two.Thread id is:10
  從上述測試結(jié)果中我們可以很清晰地看出:上述兩個(gè)測試組件是在獨(dú)立的兩個(gè)線程中分別執(zhí)行的。我們可以通過在控制臺(tái)中輸出的ThreadId來證明這一點(diǎn)。
  如何配置一個(gè)需要在多線程環(huán)境中執(zhí)行的測試方法
  之前我們討論了如何并行(多線程)地執(zhí)行測試方法,測試類以及測試組件。TestNG同時(shí)也提供了一種靈活的方式來配置需要在多線程環(huán)境下運(yùn)行的測試方法:只要在該測試方法的@Test注解上配置一些信息,我們能啟用多線程模式。
  publicclassIndependentTest
  {
  @Test(threadPoolSize=3,invocationCount=6,timeOut=1000)
  publicvoidtestMethod()
  {
  Long id=Thread.currentThread().getId();
  System.out.println("Test method executing on thread with id:"+id);
  }
  }
  上述測試方法是通過在@Test注解中配置threadPoolSize這個(gè)屬性來進(jìn)入多線程模式的。threadPoolSize被設(shè)為3,這說明了該測試方法將會(huì)在三個(gè)不同的線程中同時(shí)執(zhí)行。剩余兩個(gè)屬性:invocationCount配置的是該測試方法應(yīng)被執(zhí)行的總次數(shù),timeOut配置的是每次執(zhí)行該測試方法所耗費(fèi)時(shí)間的閾值,超過閾值則測試失敗。
  在項(xiàng)目中新建一個(gè)名為independent-test-testng.xml的文件,并寫入下述代碼:
  <suitename="Independent test Suite">
  <testname="Independent test">
  <classes>
  <classname="com.howtodoinjava.parallelism.IndependentTest"/>
  </classes>
  </test>
  </suite>
  在Eclipse中選中該文件并以TestNG測試套件方式運(yùn)行。你將會(huì)在控制臺(tái)中看到以下輸出信息
  Test method executing on thread with id:11
  Test method executing on thread with id:10
  Test method executing on thread with id:9
  Test method executing on thread with id:11
  Test method executing on thread with id:11
  Test method executing on thread with id:10
  在這里,我們可以看出該測試方法被執(zhí)行了多次,而且它的執(zhí)行次數(shù)跟invocationCount所指定的次數(shù)相同。而且從輸出信息中,我們也可以很清晰地看到該測試方法每次執(zhí)行都是在不同的線程中完成的。當(dāng)我們需要按照某一固定次數(shù),在多線程環(huán)境下運(yùn)行某些測試方法時(shí),上述特性會(huì)很有幫助,因?yàn)樗苊饬宋覀儼颜麄(gè)測試套件都并行執(zhí)行多次的代價(jià)。

軟件測試工具 | 聯(lián)系我們 | 投訴建議 | 誠聘英才 | 申請使用列表 | 網(wǎng)站地圖
滬ICP備07036474 2003-2017 版權(quán)所有 上海澤眾軟件科技有限公司 Shanghai ZeZhong Software Co.,Ltd