本系列所有代碼 https://github.com/zhangting85/simpleWebtest
本文將介紹一個Java+TestNG+Maven+Selenium的web自動化測試腳本環(huán)境下selenium和testNG的多線程并發(fā)測試的實(shí)現(xiàn),并提供全部代碼。
?
這里我的多線程的執(zhí)行測試用例,目的首先是為了提高測試執(zhí)行速度,然后是為做分布式測試提供技術(shù)基礎(chǔ)。
?
testNG自帶了多線程機(jī)制,那么為什么要我們還要自己寫一些代碼呢?
因?yàn)閟elenium webdriver本身不是線程安全的。比如說,我直接在一個testNG的case里新建兩個webdriver,再做操作,他們就會沖突。然后其中一個會死掉。
如果我們直接用testNG的多線程,也會遇到類似的問題。
這里,我用thread local來解決線程安全問題:
?
在DriverManager類中,
ThreadLocal的泛型變量的聲明如下:
1
/**
2
* 每個DriverManager只管理一個driver,所以他是static的,但是我引入ThreadLocal來處理多線程
3
* shares the same web driver and use thread local to handle the multi-thread
4
*/
5
public
static
ThreadLocal<WebDriver> ThreadDriver=
new
ThreadLocal<WebDriver>() ;
之后是執(zhí)行case時(shí),要獲取一個可用的WebDriver對象來執(zhí)行測試,此時(shí)調(diào)用DriverManger.getDriver()方法來取得。
當(dāng)當(dāng)前進(jìn)程未綁定driver時(shí),創(chuàng)建一個driver,如果已綁定driver,則直接返回。所謂給當(dāng)前進(jìn)程綁定一個driver,使用的是 ThreadDriver.set(driver) 。
1
/**
2
* 如果當(dāng)前進(jìn)程沒有綁定driver,創(chuàng)建一個然后綁定上,如果已經(jīng)有了就直接返回
3
* create a driver for this thread if not exist. or return it directly
4
*/
5
public
static
WebDriver getDriver(){
6
WebDriver driver=
DriverManager.ThreadDriver.get();
7
if
(driver==
null
){
8
if
(browserType.equals("firefox"
)){
9
driver =
new
EventFiringWebDriver(
new
FirefoxDriver()).register(
new
LogEventListener());
10
ThreadDriver.set(driver);
11
//
找東西前等三秒wait 3 second for every find by
12
DriverManager.getDriver().manage().timeouts().implicitlyWait(3
, TimeUnit.SECONDS);
13
}
14
//
有需求的同學(xué)自己在這里添加IE等瀏覽器的支持
15
//
you can add ie/chrome or other driver here
16
}
17
return
driver;
18
}
?
這樣添加完之后,我們的webdriver已經(jīng)變成了線程安全的。
之后就可以執(zhí)行并發(fā)的測試,這里用了testng的dataprovider的多線程功能:
1
/**
2
* JD首頁上搜索一個商品 主要介紹定位某個商品名稱的N種寫法
3
* 這里用了DataProvider
4
* (不會用DataProvier不要說自己懂testNG)
5
*/
6
@Test(dataProvider="product_to_search"
)
7
public
void
searchProduct(String keyword)
throws
InterruptedException {
8
log.info("keyword="+
keyword);
9
String actual_procut_name=
new
JDHomepage().init().searchHeader.search(keyword).getProductNameByIndexMethodTwo(1
);
10
log.info("actual_procut_name="+
actual_procut_name);
11
assert
(actual_procut_name.contains(keyword));
12
log.info("--------------------------------"
);
13
}
14
15
/**
16
* 用了DataProvider并且是并行的。但是這個是運(yùn)行不通過的。因?yàn)閃ebDriver不是線程安全的。
17
* 稍后我會再修復(fù)這個。。。暫時(shí)先這樣吧。
18
*
19
* 2014-4-20:更新了DriverManager,現(xiàn)在這個框架里的WebDriver是線程安全的了,所以這個腳本就可以并行執(zhí)行4個測試數(shù)據(jù)了。
20
* 詳見DriverManager類
21
*
22
*/
23
@DataProvider(name="product_to_search",parallel =
true
)
24
public
Iterator<Object[]>
createData1() {
25
//
一個Array
26
String[] astringarray={"巧克力","餅","糕","蛋"
};
27
//
轉(zhuǎn)成一個String的List
28
List<String> lines=
Arrays.asList(astringarray);
29
30
//
一個Object的空的List
31
List<Object[]> data =
new
ArrayList<Object[]>
();
32
33
//
往空List里放東西,然后返回
34
for
(String line :lines )
35
{
36
data.add(
new
Object[]{line});
//
加了一個FirefoxDriver進(jìn)去哦
37
}
38
return
data.iterator();
39
40
}
?
當(dāng)dataprovider設(shè)置了parallel參數(shù)為true時(shí),測試即會并發(fā)執(zhí)行。這里的真實(shí)并發(fā)數(shù)受到CPU內(nèi)核數(shù)限制。
具體代碼詳見我的github
?
另外,使用了這些代碼將webdriver和現(xiàn)成綁定,并使用testng提供的多線程功能后,這個測試框架下的測試用例變得可以簡單得移植到selenium grid上,實(shí)現(xiàn)分布式測試。只需要再改動一下啟動driver的代碼。
下期再見。
selenium從入門到應(yīng)用 - 8,selenium+testNG實(shí)現(xiàn)多線程的并發(fā)測試
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

