本文注重自動(dòng)化測(cè)試用例并行方案的設(shè)計(jì)而账,忽略了具體代碼實(shí)現(xiàn)的細(xì)節(jié)。代碼實(shí)現(xiàn)細(xì)節(jié)大家利用網(wǎng)絡(luò)資源可以輕松搜索到相關(guān)內(nèi)容婉商!
方案概述
目前業(yè)界主流提升測(cè)試效率的方案如下:
自動(dòng)化測(cè)試腳本并行運(yùn)行苞也;
在多終端同時(shí)跑腳本级野;
編寫自定義類庫(kù)解決自動(dòng)化api無(wú)法提供的功能或者對(duì)工具提供的api進(jìn)行二次封裝繁莹,核心就是增強(qiáng)腳本健壯性檩互;
自動(dòng)化腳本執(zhí)行完畢后,自動(dòng)發(fā)送測(cè)試報(bào)告給相關(guān)責(zé)任人咨演,使其第一時(shí)間了解自動(dòng)化測(cè)試結(jié)果闸昨;
方案如下圖所示:
腳本穩(wěn)定
編寫自定義類庫(kù)解決自動(dòng)化api無(wú)法提供的功能或者對(duì)工具提供的api進(jìn)行二次封裝。主要解決的問(wèn)題包括:動(dòng)態(tài)元素識(shí)別薄风、頁(yè)面加載延遲饵较、網(wǎng)絡(luò)延遲、腳本失敗重試遭赂⊙撸總之盡量避免因?yàn)樽詣?dòng)化測(cè)試腳本的質(zhì)量問(wèn)題導(dǎo)致自動(dòng)化測(cè)試執(zhí)行失敗。這就需要自動(dòng)化腳本編寫人員有很強(qiáng)的編碼功底撇他。
多端并行
web端茄猫,本質(zhì)通過(guò)使用Selenium Grid實(shí)現(xiàn):
移動(dòng)端,本質(zhì)通過(guò)啟動(dòng)多個(gè)Appium Server逆粹,每個(gè)Appium server連接一個(gè)設(shè)備募疮。可以在同一臺(tái)機(jī)器上啟動(dòng)多個(gè)Appium Server(每個(gè)server有不同的端口)僻弹。可以使用Selenium Gird控制appium server他嚷。
腳本并行
有了多端并行運(yùn)行的技術(shù)方案蹋绽,那么下一個(gè)問(wèn)題就是讓我們的測(cè)試用例并發(fā)的在多端中運(yùn)行芭毙。我們這里以Java的TestNG測(cè)試框架為例作為講解。TestNG在處理用例并發(fā)方面是非常方便的卸耘。
TestNG有多種并發(fā)方式支持退敦,主要包括:方法的并發(fā),class級(jí)的并發(fā)蚣抗,和test級(jí)的并發(fā)侈百,它們的區(qū)別如下:
tests級(jí)別:不同test tag下的用例可以在不同的線程執(zhí)行,相同test tag下的用例只能在同一個(gè)線程中執(zhí)行翰铡。
classs級(jí)別:不同class tag下的用例可以在不同的線程執(zhí)行钝域,相同class tag下的用例只能在同一個(gè)線程中執(zhí)行。
methods級(jí)別:所有用例都可以在不同的線程去執(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">
實(shí)踐中例证,很多時(shí)候我們?cè)跍y(cè)試類中通過(guò)dependOnMethods/dependOnGroups方式,給很多測(cè)試方法的執(zhí)行添加了依賴迷捧,以達(dá)到期望的執(zhí)行順序织咧。TestNG能在多線程情況下依然遵循既定的用例執(zhí)行順序去執(zhí)行。有些時(shí)候漠秋,我們需要對(duì)一個(gè)測(cè)試用例笙蒙,比如一個(gè)http接口,執(zhí)行并發(fā)測(cè)試庆锦,即一個(gè)接口的反復(fù)調(diào)用手趣。在
@Test標(biāo)簽中指定threadPoolSize和invocationCount可以實(shí)現(xiàn)該需求。
例如:@Test(threadPoolSize=5,invocationCount=10)
其中threadPoolSize表明用于調(diào)用該方法的線程池容量肥荔,該例就是同時(shí)起5個(gè)線程并行執(zhí)行該方法绿渣;invocationCount表示該方法總計(jì)需要被執(zhí)行的次數(shù)。該例子中5個(gè)線程同時(shí)執(zhí)行燕耿,當(dāng)總計(jì)執(zhí)行次數(shù)達(dá)到10次時(shí)停止中符。
實(shí)例如下:
寫兩個(gè)類?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>
查看運(yùn)行結(jié)果:3292ms完成測(cè)試誉帅,如果不使用多線程則至少需要6s
原創(chuàng)不易淀散,如果文章幫到了你,歡迎轉(zhuǎn)發(fā)蚜锨,讓更多的朋友受益档插!