有两个测试类,每个测试类都有一个测试方法,使用并行模式的数据提供器。
public class FirstNg {
@Test(dataProvider = "dp11", description="f one")
public void f11(Integer n, String s) throws InterruptedException {
System.out.println("DP FIR ----" + Thread.currentThread().getId() + "----" + System.currentTimeMillis());
Thread.sleep(4000);
}
@DataProvider(parallel = true)
public Object[][] dp11() {
return new Object[][] { new Object[] { 1, "a" }, new Object[] { 2, "b" }, new Object[] { 3, "c" },
new Object[] { 4, "d" }};
}
}
public class SecondNg {
@Test(dataProvider = "dp22", description="f two")
public void f22(Integer n, String s) throws InterruptedException {
System.out.println("DP SEC ----" + Thread.currentThread().getId() + "----" + System.currentTimeMillis());
Thread.sleep(4000);
}
@DataProvider(parallel = true)
public Object[][] dp22() {
return new Object[][] { new Object[] { 1, "a" }, new Object[] { 2, "b" }, new Object[] { 3, "c" },
new Object[] { 4, "d" }};
}
}
测试运行的持续时间使用在BeforeSuite和AterSuite中确定的时间计算。
案例1 - 没有任何线程并行设置运行。
<suite name="suite" data-provider-thread-count="2">
<test name="test">
<classes>
<class name="FirstNg"/>
<class name="SecondNg"/>
</classes>
</test>
</suite>
这给出了以下结果。
DP FIR ----12----1552410839748
DP FIR ----11----1552410839752
DP FIR ----12----1552410843753
DP FIR ----11----1552410843756
DP SEC ----13----1552410847763
DP SEC ----14----1552410847764
DP SEC ----13----1552410851767
DP SEC ----14----1552410851768
DURATION - 16.936 secs
前两行是属于FirstNg类的数据提供者的。这将以两对(等于data-provider-thread-count的值)重复,然后使用SecondNg类的数据提供者。
案例2 - 使用线程并行设置运行方法。
<suite name="Surefire suite" data-provider-thread-count="2" parallel="methods">
<test name="Surefire test">
<classes>
<class name="testngparallel.FirstNg"/>
<class name="testngparallel.SecondNg"/>
</classes>
</test>
</suite>
这给出了以下结果。
DP SEC ----14----1552412828961
DP FIR ----13----1552412828962
DP FIR ----16----1552412828964
DP SEC ----15----1552412828966
DP FIR ----13----1552412832972
DP FIR ----16----1552412832977
DP SEC ----15----1552412832979
DP SEC ----14----1552412832980
DURATION - 8.161 secs
前四行一起启动。两行属于FirstNg数据提供者,另外两行属于SecondNg。重复此操作直到所有数据提供程序的所有行都用完为止。
从这个讨论看来,它有2个池,一个用于数据提供者,另一个用于其他测试 - https://groups.google.com/forum/#!topic/testng-users/BKfSgHoAChU
添加parallel =“methods”设置可减少测试执行的时间。此外,测试序列也发生了变化,来自数据提供者的测试也被混淆了。两个设置之间有什么联系?
添加parallel =“methods”设置可减少测试执行的时间。此外,测试序列也发生了变化,来自数据提供者的测试也被混淆了。两个设置之间有什么联系?
基本上这两个设置控制不同的执行方面。所有测试方法都可以分为两类。
TestNG有两个特定的设置,以满足上述两个类别的需求
thread-count
- 在任何给定点控制有多少常规测试方法可以同时运行。data-provider-thread-count
- 在任何给定点控制,可以同时运行多少数据驱动的测试方法。当您启用这两个设置时(以及当您使用常规和数据驱动的测试方法时)会发生什么情况,TestNG会同时运行所有测试方法,如果存在本质上是数据驱动的测试方法,那么这些数据驱动迭代也是并行执行的。
就像你同时分离一堆线程一样,但是其中一个或多个线程在内部分离出额外的线程。
此设置为您提供了执行速度方面的最大吞吐量,但如果您有更大的值(通过添加这两个设置值获得),则可能会影响整体性能,因为现在JVM将开始执行更多上下文切换而不是安排线程并完成工作。
简单术语中线程数的经验法则为2N-1
(其中N
表示处理器中的核心数。因此,如果您有四核处理器,则最大线程数应为7)。这是一种计算线程数的过于简单的方法,但是知道这一点对我有帮助。
简而言之,parallel = true
对数据提供者的注释,允许对方法的每次迭代使用单独的线程池和测试数据,而不管并行方法/ class / tests / none。
当您将parallel = true
添加到数据提供者注释时,它将考虑使用data-provider-thread-count
(默认为10)提供大小的单独池。因此,当使用数据提供程序进行测试时,它将使用单独的线程池并行执行,即使您在套件配置中设置了parallel=none
也是如此。
Case parallel=none
和数据提供者parallel = false
或未设置:包含来自数据提供者的迭代的每个方法都将在同一个线程中运行。
DP FIR ----1----1552433313814
DP FIR ----1----1552433317824
DP FIR ----1----1552433321834
DP FIR ----1----1552433325839
Normal FIR2 ----1----1552433329848
DP SEC ----1----1552433333855
DP SEC ----1----1552433337859
DP SEC ----1----1552433341865
DP SEC ----1----1552433345871
Normal SEC2 ----1----1552433349876
Case parallel=none
和数据提供者parallel = true
:
所有方法都需要在相同的线程中按顺序执行接受数据驱动的方法。如果该方法是数据驱动的,那么当它转向时,当前的线程将使用单独的池来并行运行每个迭代,以防数据提供者parallel = true
。在下面的执行中,一个数据提供者设置为parallel = true
而另一个不设置。因此,您可以看到当前线程在“DP FIR”的单独池中执行迭代,并在“DP SEC”的当前线程中运行所有迭代。 (未提供data-provider-thread-count,因此默认为10)
DP FIR ----10----1552433554893
DP FIR ----12----1552433554893
DP FIR ----11----1552433554893
DP FIR ----13----1552433554894
Normal FIR2 ----1----1552433558907
DP SEC ----1----1552433562916
DP SEC ----1----1552433566923
DP SEC ----1----1552433570928
DP SEC ----1----1552433574933
Normal SEC2 ----1----1552433578938
<suite name="suite" >
<test name="test">
<classes>
<class name="FirstNg" />
<class name="SecondNg" />
</classes>
</test>
</suite>
public class FirstNg {
@Test(dataProvider = "dp11", description = "f one")
public void f11(Integer n, String s) throws InterruptedException {
System.out.println("DP FIR ----" + Thread.currentThread().getId() + "----" + System.currentTimeMillis());
Thread.sleep(4000);
}
@Test
public void f12() throws InterruptedException {
System.out.println("Normal FIR2 ----" + Thread.currentThread().getId() + "----" + System.currentTimeMillis());
Thread.sleep(4000);
}
@DataProvider(parallel = true)
//@DataProvider
public Object[][] dp11() {
return new Object[][] { new Object[] { 1, "a" }, new Object[] { 2, "b" }, new Object[] { 3, "c" },
new Object[] { 4, "d" } };
}
}
public class SecondNg {
@Test(dataProvider = "dp22", description="f two")
public void f22(Integer n, String s) throws InterruptedException {
System.out.println("DP SEC ----" + Thread.currentThread().getId() + "----" + System.currentTimeMillis());
Thread.sleep(4000);
}
@Test
public void f222() throws InterruptedException {
System.out.println("Normal SEC2 ----" + Thread.currentThread().getId() + "----" + System.currentTimeMillis());
Thread.sleep(4000);
}
//@DataProvider(parallel = true)
@DataProvider
public Object[][] dp22() {
return new Object[][] { new Object[] { 1, "a" }, new Object[] { 2, "b" }, new Object[] { 3, "c" },
new Object[] { 4, "d" }};
}
}
案例parallel=methods or classes
:
使用parallel=methods
它将开始并行执行,具体取决于thread-count
在xml配置中提供的大小池。再次如果方法是数据驱动的,当它转向时,分配的线程将在并行的单独池中运行每次迭代。否则,分配的线程按顺序运行每次迭代。
您可以看到分配给“DP FIR”的线程在“DP FIR”的单独池中执行迭代,但在“DP SEC”的指定线程中运行所有迭代。
DP FIR ----14----1552433989613
Normal FIR2 ----11----1552433989614
DP FIR ----17----1552433989613
DP SEC ----12----1552433989613
DP FIR ----16----1552433989613
DP FIR ----15----1552433989616
Normal SEC2 ----13----1552433989617
DP SEC ----12----1552433993625
DP SEC ----12----1552433997632
DP SEC ----12----1552434001640
案例parallel=methods or classes
和数据提供者parallel = false
或未设置:
当转向数据驱动方法时,每个迭代将在分配的线程中按顺序执行。