本文注重自動化測試用例并行方案的設(shè)計,忽略了具體代碼實現(xiàn)的細節(jié)。代碼實現(xiàn)細節(jié)大家利用網(wǎng)絡(luò)資源可以輕松搜索到相關(guān)內(nèi)容!

方案概述
目前業(yè)界主流提升測試效率的方案如下:
自動化測試腳本并行運行;
在多終端同時跑腳本;
編寫自定義類庫解決自動化api無法提供的功能或者對工具提供的api進行二次封裝,核心就是增強腳本健壯性;
自動化腳本執(zhí)行完畢后,自動發(fā)送測試報告給相關(guān)責(zé)任人,使其第一時間了解自動化測試結(jié)果;
方案如下圖所示:

腳本穩(wěn)定
編寫自定義類庫解決自動化api無法提供的功能或者對工具提供的api進行二次封裝。主要解決的問題包括:動態(tài)元素識別、頁面加載延遲、網(wǎng)絡(luò)延遲、腳本失敗重試??傊M量避免因為自動化測試腳本的質(zhì)量問題導(dǎo)致自動化測試執(zhí)行失敗。這就需要自動化腳本編寫人員有很強的編碼功底。
多端并行
web端,本質(zhì)通過使用Selenium Grid實現(xiàn):

移動端,本質(zhì)通過啟動多個Appium Server,每個Appium server連接一個設(shè)備??梢栽谕慌_機器上啟動多個Appium Server(每個server有不同的端口)??梢允褂肧elenium Gird控制appium server。

腳本并行
有了多端并行運行的技術(shù)方案,那么下一個問題就是讓我們的測試用例并發(fā)的在多端中運行。我們這里以Java的TestNG測試框架為例作為講解。TestNG在處理用例并發(fā)方面是非常方便的。
TestNG有多種并發(fā)方式支持,主要包括:方法的并發(fā),class級的并發(fā),和test級的并發(fā),它們的區(qū)別如下:
tests級別:不同test tag下的用例可以在不同的線程執(zhí)行,相同test tag下的用例只能在同一個線程中執(zhí)行。
classs級別:不同class tag下的用例可以在不同的線程執(zhí)行,相同class tag下的用例只能在同一個線程中執(zhí)行。
methods級別:所有用例都可以在不同的線程去執(zhí)行。
xml文件中配置如下
<suitename="Testng Parallel Test"parallel="tests"thread-count="5">
<suitename="Testng Parallel Test"parallel="classes"thread-count="5">
<suitename="Testng Parallel Test"parallel="methods"thread-count="5">
<suitename="My suite"?parallel="instances"?thread-count="5">
實踐中,很多時候我們在測試類中通過dependOnMethods/dependOnGroups方式,給很多測試方法的執(zhí)行添加了依賴,以達到期望的執(zhí)行順序。TestNG能在多線程情況下依然遵循既定的用例執(zhí)行順序去執(zhí)行。有些時候,我們需要對一個測試用例,比如一個http接口,執(zhí)行并發(fā)測試,即一個接口的反復(fù)調(diào)用。在
@Test標(biāo)簽中指定threadPoolSize和invocationCount可以實現(xiàn)該需求。
例如:@Test(threadPoolSize=5,invocationCount=10)
其中threadPoolSize表明用于調(diào)用該方法的線程池容量,該例就是同時起5個線程并行執(zhí)行該方法;invocationCount表示該方法總計需要被執(zhí)行的次數(shù)。該例子中5個線程同時執(zhí)行,當(dāng)總計執(zhí)行次數(shù)達到10次時停止。
實例如下:
寫兩個類?ThreadCase1和ThreadCase1
public?class ThreadCase1 {
?@Test
public?void m1()throws InterruptedException {
???????????? Thread.sleep(1000);
????????????? System.out.println("*****"+Thread.currentThread().getId());
?????????????? assertTrue(true);
?????? ? }
?@Test
public?void m2()throws InterruptedException {
???????????? Thread.sleep(1000);
????????????? System.out.println("*****"+Thread.currentThread().getId());
????????????? assertTrue(false);
?????? ? }
?@Test
public?void m3() throws InterruptedException {
???????????? Thread.sleep(1000);
???????????? System.out.println("*****"+Thread.currentThread().getId());
??????????? assertTrue(true);
?????? ? }
}
public?class ThreadCase2 {
?????? ?@Test
???????? public?void m1()throws InterruptedException {
??????????????? Thread.sleep(1000);
??????????????? System.out.println("*****"+Thread.currentThread().getId());
?????????????? assertTrue(true);
?????? ? }
?@Test
public?void m2() throws InterruptedException {
????????????? Thread.sleep(1000);
?????????????? System.out.println("*****"+Thread.currentThread().getId());
?????????????? assertTrue(false);
?????? ? }
?@Test
public?void m3() throws InterruptedException {
?????????? Thread.sleep(1000);
?????????? System.out.println("*****"+Thread.currentThread().getId());
?????????? assertTrue(true);
?????? ? }
}
在配置文件中指定parallel為class,thread-count值為2
<!DOCTYPE?suite?SYSTEM?"https://testng.org/testng-1.0.dtd">
"TestngParallel Test"parallel="classes "thread-count="2">
"case1">
?<classes>
"com.my.test5.ThreadCase1"/>
"com.my.test5.ThreadCase2"/>
?</classes>
?</test>
</suite>
查看運行結(jié)果:3292ms完成測試,如果不使用多線程則至少需要6s
原創(chuàng)不易,如果文章幫到了你,歡迎轉(zhuǎn)發(fā),讓更多的朋友受益!