并行模式下的数据提供者与线程并行"methods"设置的关系
Relationship between dataprovider in parallel mode and thread parallel "methods" setting
有两个测试 class,每个测试都有一个在并行模式下使用 datatprovider 的测试方法。
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 的数据提供者 class。这是两个对重复的(等于 data-provider-thread-count 的值),然后使用 SecondNg class 的数据提供者。
案例 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 = true
到数据提供程序注释,允许使用单独的线程池为方法的每次迭代使用测试数据,而不管并行 method/class/tests/none。
当您将 parallel = true
添加到数据提供者注释时,它会考虑使用 data-provider-thread-count
(默认为 10)提供大小的单独池。因此,当使用数据提供程序进行测试时,它将使用单独的线程池并行执行,即使您在套件配置中设置了 parallel=none
。
案例 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
案例 parallel=none
和数据提供者 parallel = true
:
所有方法都需要在同一个线程中按顺序执行接受数据驱动的方法。如果该方法是数据驱动的,当轮到它时,当前线程将使用单独的池来运行每个并行迭代,以防数据提供者parallel = true
。在下面的执行中,一个数据提供者设置为 parallel = true
而另一个没有。因此,您可以看到当前线程在单独的池中为 "DP FIR" 执行迭代,并在当前线程中为 "DP SEC" 执行所有迭代 运行。 (未提供数据提供者线程数,因此默认为 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
:
With parallel=methods
它将开始并行执行,具体取决于 xml 配置中 thread-count
提供的池大小。同样,如果该方法是数据驱动的,则轮到它时,分配的线程将 运行 并行单独池中的每个迭代。否则按顺序分配线程 运行 每次迭代。
您可以看到分配给 "DP FIR" 的线程在 "DP FIR" 的单独池中执行迭代,但 运行 在 "DP SEC".[=30 的分配线程中执行所有迭代=]
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
或未设置:
当轮到数据驱动方法时,每次迭代将在分配的线程中按顺序执行。
Adding the parallel="methods" setting, reduces the time of the test
execution. Also the sequence of tests are changed, tests from both the
dataprovider are mixed up. What is the connection between the two
settings?
基本上这两个设置控制不同的执行方面。
所有测试方法都可以分为两类。
- 常规测试方法
- 由数据提供者支持的测试方法。
TestNG通过
有两个特定的设置来满足上述两个类别的需求
thread-count
- 它控制在任何给定点有多少常规测试方法可以同时 运行。
data-provider-thread-count
- 在任何给定点控制,有多少数据驱动测试方法可以同时 运行。
当您同时启用这两个设置时(以及当您混合使用常规测试方法和数据驱动测试方法时)会发生什么,TestNG 运行 同时使用所有测试方法,如果有测试本质上是数据驱动的方法,那些数据驱动的迭代也是并行执行的。
这就像你并发地分离出一堆线程,但其中一个或多个线程在内部分离出额外的线程。
此设置在执行速度方面为您提供最大吞吐量,但如果您有更大的值(通过添加这两个设置值获得),您可能会影响整体性能,因为现在 JVM 将开始执行更多上下文切换而不是调度线程并完成工作。
简单来说,线程数的经验法则为 2N-1
(其中 N
表示处理器中的核心数。因此,如果您有四核处理器,您的最大线程数应为 7)。这是一种过于简单的计算线程数的方法,但意识到这一点对我有所帮助。
有两个测试 class,每个测试都有一个在并行模式下使用 datatprovider 的测试方法。
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 的数据提供者 class。这是两个对重复的(等于 data-provider-thread-count 的值),然后使用 SecondNg class 的数据提供者。
案例 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 = true
到数据提供程序注释,允许使用单独的线程池为方法的每次迭代使用测试数据,而不管并行 method/class/tests/none。
当您将 parallel = true
添加到数据提供者注释时,它会考虑使用 data-provider-thread-count
(默认为 10)提供大小的单独池。因此,当使用数据提供程序进行测试时,它将使用单独的线程池并行执行,即使您在套件配置中设置了 parallel=none
。
案例 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
案例 parallel=none
和数据提供者 parallel = true
:
所有方法都需要在同一个线程中按顺序执行接受数据驱动的方法。如果该方法是数据驱动的,当轮到它时,当前线程将使用单独的池来运行每个并行迭代,以防数据提供者parallel = true
。在下面的执行中,一个数据提供者设置为 parallel = true
而另一个没有。因此,您可以看到当前线程在单独的池中为 "DP FIR" 执行迭代,并在当前线程中为 "DP SEC" 执行所有迭代 运行。 (未提供数据提供者线程数,因此默认为 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
:
With parallel=methods
它将开始并行执行,具体取决于 xml 配置中 thread-count
提供的池大小。同样,如果该方法是数据驱动的,则轮到它时,分配的线程将 运行 并行单独池中的每个迭代。否则按顺序分配线程 运行 每次迭代。
您可以看到分配给 "DP FIR" 的线程在 "DP FIR" 的单独池中执行迭代,但 运行 在 "DP SEC".[=30 的分配线程中执行所有迭代=]
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
或未设置:
当轮到数据驱动方法时,每次迭代将在分配的线程中按顺序执行。
Adding the parallel="methods" setting, reduces the time of the test execution. Also the sequence of tests are changed, tests from both the dataprovider are mixed up. What is the connection between the two settings?
基本上这两个设置控制不同的执行方面。 所有测试方法都可以分为两类。
- 常规测试方法
- 由数据提供者支持的测试方法。
TestNG通过
有两个特定的设置来满足上述两个类别的需求thread-count
- 它控制在任何给定点有多少常规测试方法可以同时 运行。data-provider-thread-count
- 在任何给定点控制,有多少数据驱动测试方法可以同时 运行。
当您同时启用这两个设置时(以及当您混合使用常规测试方法和数据驱动测试方法时)会发生什么,TestNG 运行 同时使用所有测试方法,如果有测试本质上是数据驱动的方法,那些数据驱动的迭代也是并行执行的。
这就像你并发地分离出一堆线程,但其中一个或多个线程在内部分离出额外的线程。
此设置在执行速度方面为您提供最大吞吐量,但如果您有更大的值(通过添加这两个设置值获得),您可能会影响整体性能,因为现在 JVM 将开始执行更多上下文切换而不是调度线程并完成工作。
简单来说,线程数的经验法则为 2N-1
(其中 N
表示处理器中的核心数。因此,如果您有四核处理器,您的最大线程数应为 7)。这是一种过于简单的计算线程数的方法,但意识到这一点对我有所帮助。