testNG(三) 并发
不同级别的并发
通常,在TestNG的执行中,测试的级别由上至下可以分为suite -> test -> class -> method,箭头的左边元素跟右边元素的关系是一对多的包含关系。
这里的test指的是testng.xml中的test tag,而不是测试类里的一个 @Test。测试类里的一个 @Test实际上对应这里的method。
suite
一般情况下,一个testng.xml只包含一个suite。如果想起多个线程执行不同的suite,官方给出的方法是:通过命令行的方式来指定线程池的容量(设置suitethreadpoolsize )。
java org.testng.TestNG -suitethreadpoolsize 3 testng1.xml testng2.xml testng3.xml
即可通过三个线程来分别执行testng1.xml、testng2.xml、testng3.xml。
test, class, method
test,class,method级别的并发,可以通过在testng.xml中的suite tag下设置(thread-count),如:
<suite name="Testng Parallel Test" parallel="tests" thread-count="5"> <suite name="Testng Parallel Test" parallel="classes" thread-count="5"> <suite name="Testng Parallel Test" parallel="methods" thread-count="5">
它们的共同点都是最多起5个线程去同时执行不同的用例。区别如下:
-
tests级别:这个suite中的所有test tag共享一个线程池(5个线程),不同test tag下的用例可以在不同的线程执行,相同test tag下的用例只能在同一个线程中执行。
-
classs级别:这个suite中的所有class tag共享一个线程池(5个线程),不同class tag下的用例可以在不同的线程执行,相同class tag下的用例只能在同一个线程中执行。
-
methods级别:这个suite中的所有用例共享一个线程池(5个线程),所有用例都可以在不同的线程去执行。
不同dataprovider的并发
在@DataProvider中添加parallel=true。
默认情况下,dp并行执行的线程池容量为10,如果要更改并发的数量,也可以在suite tag下指定参数data-provider-thread-count:
<suite name="Testng Parallel Test" parallel="methods" thread-count="5" data-provider-thread-count="20" >
同一个方法的并发
@Test标签中指定threadPoolSize和invocationCount。
@Test(enabled=true, dataProvider="testdp", threadPoolSize=5, invocationCount=10)
其中
threadPoolSize表明用于调用该方法的线程池容量,该例就是同时起5个线程并行执行该方法;
invocationCount表示该方法总计需要被执行的次数。该例子中5个线程同时执行,当总计执行次数达到10次时,停止。
注意:该线程池与dp的并发线程池是两个独立的线程池。这里的线程池是用于起多个method,而每个method的测试数据由dp提供,如果这边dp里有3组数据,那么实际上10次执行,每次都会调3次接口,这个接口被调用的总次数是10*3=30次。threadPoolSize指定的5个线程中,每个线程单独去调method时,用到的dp如果也是支持并发执行的话,会创建一个新的线程池(dpThreadPool)来并发执行测试数据。
示例代码如下:
public class TestClass1 { @Test(enabled=true, dataProvider="testdp", threadPoolSize=2, invocationCount=5) public void test(String dpNumber) throws InterruptedException{ System.out.println("Current Thread Id: " + Thread.currentThread().getId() + ". Dataprovider number: "+ dpNumber); Thread.sleep(5000); } @DataProvider(name = "testdp", parallel = true) public static Object[][]testdp(){ return new Object[][]{ {"1"}, {"2"} }; } }
测试结果:
[ThreadUtil] Starting executor timeOut:0ms workers:5 threadPoolSize:2 Current Thread Id: 14. Dataprovider number: 2 Current Thread Id: 15. Dataprovider number: 2 Current Thread Id: 12. Dataprovider number: 1 Current Thread Id: 13. Dataprovider number: 1 Current Thread Id: 16. Dataprovider number: 1 Current Thread Id: 18. Dataprovider number: 1 Current Thread Id: 17. Dataprovider number: 2 Current Thread Id: 19. Dataprovider number: 2 Current Thread Id: 21. Dataprovider number: 2 Current Thread Id: 20. Dataprovider number: 1