本系列所有代碼 https://github.com/zhangting85/simpleWebtest
本文將介紹一個Java+TestNG+Maven+Selenium的web自動化測試腳本環(huán)境下selenium和testNG的多線程并發(fā)測試的實現(xiàn),并提供全部代碼。
?
這里我的多線程的執(zhí)行測試用例,目的首先是為了提高測試執(zhí)行速度,然后是為做分布式測試提供技術(shù)基礎(chǔ)。
?
testNG自帶了多線程機制,那么為什么要我們還要自己寫一些代碼呢?
因為selenium 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時,要獲取一個可用的WebDriver對象來執(zhí)行測試,此時調(diào)用DriverManger.getDriver()方法來取得。
當(dāng)當(dāng)前進程未綁定driver時,創(chuàng)建一個driver,如果已綁定driver,則直接返回。所謂給當(dāng)前進程綁定一個driver,使用的是 ThreadDriver.set(driver) 。
1 /** 2 * 如果當(dāng)前進程沒有綁定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并且是并行的。但是這個是運行不通過的。因為WebDriver不是線程安全的。 17 * 稍后我會再修復(fù)這個。。。暫時先這樣吧。 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進去哦 37 } 38 return data.iterator(); 39 40 }
?
當(dāng)dataprovider設(shè)置了parallel參數(shù)為true時,測試即會并發(fā)執(zhí)行。這里的真實并發(fā)數(shù)受到CPU內(nèi)核數(shù)限制。
具體代碼詳見我的github
?
另外,使用了這些代碼將webdriver和現(xiàn)成綁定,并使用testng提供的多線程功能后,這個測試框架下的測試用例變得可以簡單得移植到selenium grid上,實現(xiàn)分布式測試。只需要再改動一下啟動driver的代碼。
下期再見。
selenium從入門到應(yīng)用 - 8,selenium+testNG實現(xiàn)多線程的并發(fā)測試
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
