本系列所有代码 https://github.com/zhangting85/simpleWebtest
本文将介绍一个Java+TestNG+Maven+Selenium的web自动化测试脚本环境下selenium和testNG的多线程并发测试的实现,并提供全部代码。
这里我的多线程的执行测试用例,目的首先是为了提高测试执行速度,然后是为做分布式测试提供技术基础。
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>() ;
之后是执行case时,要获取一个可用的WebDriver对象来执行测试,此时调用DriverManger.getDriver()方法来取得。
当当前进程未绑定driver时,创建一个driver,如果已绑定driver,则直接返回。所谓给当前进程绑定一个driver,使用的是 ThreadDriver.set(driver) 。
1
/**
2
* 如果当前进程没有绑定driver,创建一个然后绑定上,如果已经有了就直接返回
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
//
有需求的同学自己在这里添加IE等浏览器的支持
15
//
you can add ie/chrome or other driver here
16
}
17
return
driver;
18
}
这样添加完之后,我们的webdriver已经变成了线程安全的。
之后就可以执行并发的测试,这里用了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
* 稍后我会再修复这个。。。暂时先这样吧。
18
*
19
* 2014-4-20:更新了DriverManager,现在这个框架里的WebDriver是线程安全的了,所以这个脚本就可以并行执行4个测试数据了。
20
* 详见DriverManager类
21
*
22
*/
23
@DataProvider(name="product_to_search",parallel =
true
)
24
public
Iterator<Object[]>
createData1() {
25
//
一个Array
26
String[] astringarray={"巧克力","饼","糕","蛋"
};
27
//
转成一个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
}
当dataprovider设置了parallel参数为true时,测试即会并发执行。这里的真实并发数受到CPU内核数限制。
具体代码详见我的github
另外,使用了这些代码将webdriver和现成绑定,并使用testng提供的多线程功能后,这个测试框架下的测试用例变得可以简单得移植到selenium grid上,实现分布式测试。只需要再改动一下启动driver的代码。
下期再见。

