testng多线程并行执行测试
testng多线程并行执行测试
testng多线程并行执行测试
并行(多线程)技术在软件术语里被定义为软件、操作系统或者程序可以并行地执行另外一段程序中多个部分或者子组件的能力。TestNG允许我们以并行(多线程)的方式来执行测试。这就意味着基于TestNG测试组件的配置,多个线程可以被同时启动然后分别执行各自的测试方法。相对于传统的单线程执行测试的方式,这种多线程方式拥有很大的优势,主要是它可以减少测试运行时间,并且可以验证某段代码在多线程环境中运行的正确性。
invocationCount----表示执行的次数
threadPoolSize-----表示线程池的内线程的个数
timeOut-------超时时间-毫秒
目录
- 并行执行测试的优势
- 如何并行地执行测试方法
- 如何并行地执行测试类
- 如何并行地执行同一测试套件内的各个测试组件
- 如何配置需要在多线程环境中执行的测试方法
并行执行测试的优势
并行(多线程)执行测试可以给用户带来很多好处,主要包括以下两点:
1)减少了执行时间:并行测试也就意味着多个测试可以在同一时间被同时执行,从而减少了整体测试所花费的时间。
2)允许多个线程并行地测试同一个测试组件:有了这个特性,我们就能够写出相应的测试用例来验证应用程序中包含多线程部分的代码的正确性。
以上特性被广泛地应用在QA领域的自动化功能测试方面。通过简单的配置,QA人员就可以很轻松地使得他们的测试用例在多个浏览器或者操作系统中并行地执行。
TestNG提供了三种不同类型的配置方案来实现并行测试。
如何并行地执行测试方法
TestNG为我们提供了多种方式来实现并行测试,其中一种就是每一个独立的线程分别执行各自的测试方法。这种方式能够显著地减少测试执行时间,这是因为当有越多的测试方法被并行执行时,总体测试消耗时间将会越少。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
package com.howtodoinjava.parallelism;import org.testng.annotations.AfterMethod;import org.testng.annotations.BeforeMethod;import org.testng.annotations.Test;public class ParallelMethodTest{ @BeforeMethod public void beforeMethod() { long id = Thread.currentThread().getId(); System.out.println("Before test-method. Thread id is: " + id); } @Test public void testMethodsOne() { long id = Thread.currentThread().getId(); System.out.println("Simple test-method One. Thread id is: " + id); } @Test public void testMethodsTwo() { long id = Thread.currentThread().getId(); System.out.println("Simple test-method Two. Thread id is: " + id); } @AfterMethod public void afterMethod() { long id = Thread.currentThread().getId(); System.out.println("After test-method. Thread id is: " + id); }} |
上述测试类包含了两个测试方法,每个测试方法在执行时都会在控制台中打印出一条信息。每个测试方法以及它们各自的beforeMehod、afterMethod方法都会通过Thread.currentThread.getId()这段代码打印出执行该测试方法的线程的ID。
在项目中新建一个名为methods-test-testng.xml的文件并将下述代码写入该文件中。
|
1
2
3
4
5
6
7
|
<suite name="Test-method Suite" parallel="methods" thread-count="2" > <test name="Test-method test" group-by-instances="true"> <classes> <class name="com.howtodoinjava.parallelism.ParallelMethodTest" /> </classes> </test></suite> |
在Eclipse中选中该文件并且以TestNG测试套件方式运行它。你将会在控制台中看到以下输出信息:
|
1
2
3
4
5
6
|
Before test-method. Thread id is: 10Before test-method. Thread id is: 9Simple test-method Two. Thread id is: 10Simple test-method One. Thread id is: 9After test-method. Thread id is: 10After test-method. Thread id is: 9 |
注意:上述截图中的ThreadId可能与你本地控制台中输出的ThreadId不同,这是因为ThreadId的值是在程序运行时由JVM动态指派的。
从上述测试结果中我们可以很清晰地看出:上述两个测试方法以及各自相应的beforeMethod和afterMethod方法是在两个独立的线程中执行的。我们可以通过在控制台中输出的ThreadId来证明这一点。
如何并行地执行测试类
在下个例子中,我们会说明如何并行地执行测试类:同一个测试组件(test execution)中的各个测试类将会在独立的线程中并行地执行。
ParallelClassesTestOne.java
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
public class ParallelClassesTestOne{ @BeforeClass public void beforeClass() { long id = Thread.currentThread().getId(); System.out.println("Before test-class. Thread id is: " + id); } @Test public void testMethodOne() { long id = Thread.currentThread().getId(); System.out.println("Sample test-method One. Thread id is: " + id); } @Test public void testMethodTwo() { long id = Thread.currentThread().getId(); System.out.println("Sample test-method Two. Thread id is: " + id); } @AfterClass public void afterClass() { long id = Thread.currentThread().getId(); System.out.println("After test-class. Thread id is: " + id); }} |
ParallelClassesTestTwo.java
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
public class ParallelClassesTestTwo{ @BeforeClass public void beforeClass() { long id = Thread.currentThread().getId(); System.out.println("Before test-class. Thread id is: " + id); } @Test public void testMethodOne() { long id = Thread.currentThread().getId(); System.out.println("Sample test-method One. Thread id is: " + id); } @Test public void testMethodTwo() { long id = Thread.currentThread().getId(); System.out.println("Sample test-method Two. Thread id is: " + id); } @AfterClass public void afterClass() { long id = Thread.currentThread().getId(); System.out.println("After test-class. Thread id is: " + id); }} |
在项目中新建一个名为classes-test-testng.xml的文件并将下述代码写入该文件中:
|
1
2
3
4
5
6
7
8
|
<suite name="Test-class Suite" parallel="classes" thread-count="2" > <test name="Test-class test" > <classes> <class name="com.howtodoinjava.parallelism.ParallelClassesTestOne" /> <class name="com.howtodoinjava.parallelism.ParallelClassesTestTwo" /> </classes> </test></suite> |
或者可以在测试用例的每一个被测的方法的注释@Test后面加上具体的线程信息如下:(只是举例并没有参与实际的eclipse运行)
@Test(threadPoolSize = 2, invocationCount = 10, timeOut = 1000)
@BeforeClass(threadPoolSize = 2, invocationCount = 10, timeOut = 1000)
public void beforeClass() {
long id = Thread.currentThread().getId();
System.out.println("Before test-class. Thread id is: " + id);
} @Test(threadPoolSize = 2, invocationCount = 10, timeOut = 1000)
public void testMethodOne() {
long id = Thread.currentThread().getId();
System.out.println("Sample test-method One. Thread id is: " + id);
} @Test(threadPoolSize = 2, invocationCount = 10, timeOut = 1000)
public void testMethodTwo() {
long id = Thread.currentThread().getId();
System.out.println("Sample test-method Two. Thread id is: " + id);
} @AfterClass(threadPoolSize = 2, invocationCount = 10, timeOut = 1000)
public void afterClass() {
long id = Thread.currentThread().getId();
System.out.println("After test-class. Thread id is: " + id);
}
在Eclipse中选中该文件并且以TestNG测试套件方式运行它。你将会在控制台中看到以下输出信息:
|
1
2
3
4
5
6
7
8
|
Before test-class. Thread id is: 10Before test-class. Thread id is: 9Sample test-method One. Thread id is: 9Sample test-method One. Thread id is: 10Sample test-method Two. Thread id is: 10After test-class. Thread id is: 10Sample test-method Two. Thread id is: 9After test-class. Thread id is: 9 |
从上述测试结果中我们可以很清晰地看出:上述两个测试类以及各自相应的beforeClass和afterClass方法是在独立的两个线程中执行的。我们可以通过在控制台中输出的ThreadId来证明这一点。
如何并行地执行同一测试套件内的各个测试组件
接下来我们会一起学习如何并行地执行同一个测试套件内的各个测试组件,即各个测试组件会分别在独立的线程中执行。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
package com.howtodoinjava.parallelism;import org.testng.annotations.AfterClass;import org.testng.annotations.AfterTest;import org.testng.annotations.BeforeClass;import org.testng.annotations.BeforeTest;import org.testng.annotations.Parameters;import org.testng.annotations.Test;public class ParallelSuiteTest{ String testName = ""; @BeforeTest @Parameters({ "test-name" }) public void beforeTest(String testName) { this.testName = testName; long id = Thread.currentThread().getId(); System.out.println("Before test " + testName + ". Thread id is: " + id); } @BeforeClass public void beforeClass() { long id = Thread.currentThread().getId(); System.out.println("Before test-class " + testName + ". Thread id is: " + id); } @Test public void testMethodOne() { long id = Thread.currentThread().getId(); System.out.println("Sample test-method " + testName + ". Thread id is: " + id); } @AfterClass public void afterClass() { long id = Thread.currentThread().getId(); System.out.println("After test-method " + testName + ". Thread id is: " + id); } @AfterTest public void afterTest() { long id = Thread.currentThread().getId(); System.out.println("After test " + testName + ". Thread id is: " + id); }} |
在项目中新建一个名为suite-test-testng.xml的文件并将以下代码写入该文件中:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<suite name="Test-class Suite" parallel="tests" thread-count="2"> <test name="Test-class test 1"> <parameter name="test-name" value="test-method One" /> <classes> <class name="com.howtodoinjava.parallelism.ParallelSuiteTest" /> </classes> </test> <test name="Test-class test 2"> <parameter name="test-name" value="test-method One" /> <classes> <class name="com.howtodoinjava.parallelism.ParallelSuiteTest" /> </classes> </test></suite> |
在Eclipse中选中该文件并且以TestNG测试套件方式运行它。你将会在控制台中看到以下输出信息:
|
1
2
3
4
5
6
7
8
9
10
|
Before test Test One. Thread id is: 9Before test Test Two. Thread id is: 10Before test-class Test One. Thread id is: 9Before test-class Test Two. Thread id is: 10Sample test-method Test One. Thread id is: 9Sample test-method Test Two. Thread id is: 10After test-method Test Two. Thread id is: 10After test-method Test One. Thread id is: 9After test Test One. Thread id is: 9After test Test Two. Thread id is: 10 |
从上述测试结果中我们可以很清晰地看出:上述两个测试组件是在独立的两个线程中分别执行的。我们可以通过在控制台中输出的ThreadId来证明这一点。
如何配置一个需要在多线程环境中执行的测试方法
之前我们讨论了如何并行(多线程)地执行测试方法,测试类以及测试组件。TestNG同时也提供了一种灵活的方式来配置需要在多线程环境下运行的测试方法:只要在该测试方法的@Test注解上配置一些信息,我们就能启用多线程模式。
|
1
2
3
4
5
6
7
8
9
|
public class IndependentTest{ @Test(threadPoolSize = 3, invocationCount = 6, timeOut = 1000) public void testMethod() { Long id = Thread.currentThread().getId(); System.out.println("Test method executing on thread with id: " + id); }} |
上述测试方法是通过在@Test注解中配置threadPoolSize这个属性来进入多线程模式的。threadPoolSize被设为3,这就说明了该测试方法将会在三个不同的线程中同时执行。剩余两个属性:invocationCount配置的是该测试方法应被执行的总次数,timeOut配置的是每次执行该测试方法所耗费时间的阈值,超过阈值则测试失败。
在项目中新建一个名为independent-test-testng.xml的文件,并写入下述代码:
|
1
2
3
4
5
6
7
|
<suite name="Independent test Suite" > <test name="Independent test"> <classes> <class name="com.howtodoinjava.parallelism.IndependentTest" /> </classes> </test></suite> |
在Eclipse中选中该文件并以TestNG测试套件方式运行。你将会在控制台中看到以下输出信息
|
1
2
3
4
5
6
|
Test method executing on thread with id: 11Test method executing on thread with id: 10Test method executing on thread with id: 9Test method executing on thread with id: 11Test method executing on thread with id: 11Test method executing on thread with id: 10 |
在这里,我们可以看出该测试方法被执行了多次,而且它的执行次数跟invocationCount所指定的次数相同。而且从输出信息中,我们也可以很清晰地看到该测试方法每次执行都是在不同的线程中完成的。当我们需要按照某一固定次数,在多线程环境下运行某些测试方法时,上述特性会很有帮助,因为它避免了我们把整个测试套件都并行执行多次的代价。
test,class,method级别的并发,可以通过在testng.xml中的suite tag下设置,区别如下:
tests级别:不同test tag下的用例可以在不同的线程执行,相同test tag下的用例只能在同一个线程中执行。
classs级别:不同class tag下的用例可以在不同的线程执行,相同class tag下的用例只能在同一个线程中执行。
methods级别:所有用例都可以在不同的线程去执行。
testng多线程并行执行测试的更多相关文章
- 使用testng多线程来测试成交编号重复的问题
1.首先编写一个测试用的 function CREATE OR REPLACE FUNCTION getDealmainNo_test(dealdate IN varchar2, productcod ...
- Selenium & Webdriver 远程测试和多线程并发测试
Selenium & Webdriver 远程测试和多线程并发测试 Selenium Webdriver自动化测试,初学者可以使用selenium ide录制脚本,然后生成java程序导入ec ...
- 学习使用TestNG进行数据驱动测试
转自: https://mp.weixin.qq.com/s/8Bd8LEhiC2pu2VMcyNMGlQ 学习使用TestNG进行数据驱动测试 赵吃饭 51Testing软件测试网 前天 学习使 ...
- Java接口多线程并发测试 (一)
本文为作者原创,禁止转载,违者必究法律责任!!! 本文为作者原创,禁止转载,违者必究法律责任!!! Java接口多线程并发测试 一,首先写一个接口post 请求代码: import org.apach ...
- testNG之异常测试
@Test(expectedExceptions = ) 在测试的时候,某些用例的输入条件,预期结果是代码抛出异常,那么这个时候就需要testNG的异常测试,先看一段会抛出异常的代码 exceptio ...
- TestNG多线程测试-注解方式实现
用@Test(invocationCount = x,threadPoolSize = y)声明,invocationCount表示执行次数,threadPoolSize表示线程池大小. packag ...
- TestNG 多线程测试
TestNG以注解的方式实现多线程测试 import org.testng.annotations.Test; public class TreadDemo { // invocationCount ...
- 利用Testng注释实现多线程并发测试
Testng 是一款非常优秀的测试框架,真正从测试角度出发,为测试所想.在测试过程中我们经常会遇到对某一个场景做并发请求,主要想了解该程序在并发时是否会有异常或者没考虑到的其他情况,这时往往不是要做性 ...
- TestNG多线程测试-用xml文件实现
MultiThreadOnXml类: package com.janson.multiThread; import org.testng.annotations.Test; public class ...
随机推荐
- python2.0_day18_django_ORM
Django_ORMday15\16我们学到的ORM都是最基本的增删改查.下面我们稍作升级,学习下高级点的增删改查.先创建一个新的APP项目 python3. manage.py startapp b ...
- python2.0_s12_day9_协程&多线程和cpu,磁盘io之间的关系
事件驱动和异步io有什么直接关系. 当我们访问一个网页,不考虑网络问题.我们人类不觉得网页慢. 但是实际中对计算机来说还是慢.那慢在哪里.io io操作是整个网络操作中最慢的.比如你打开网页要是有2秒 ...
- java日志之slf4j与logback简单使用
最近在开发遇到日志是使用slf4j与logback.xml的配置,所以就记录下来了. 1.导入这几个jar包: Logback 分为三个模块:logback-core,logback-classic, ...
- ASP代码审计学习笔记 -2.XSS跨站脚本
XSS漏洞: 漏洞代码: <% xss=request("xss") response.write(xss) %> 漏洞利用: 漏洞修复: Server.HTMLEnc ...
- 第二篇:一个经典的比喻( 关于TCP连接API )
前言 编程是对现实世界的模拟,网络通信自然也是对现实世界通信的模拟.可以将网络通信中使用的各种API和对现实世界中的各种通信设备进行通讯的操作进行对比以加深理解. 对比 socket() 函数 vs ...
- C++11新特性之0——移动语义、移动构造函数和右值引用
C++引用现在分为左值引用(能取得其地址)和 右值引用(不能取得其地址).其实很好理解,左值引用中的左值一般指的是出现在等号左边的值(带名称的变量,带*号的指针等一类的数据),程序能对这样的左值进行引 ...
- php学习二:表达式
1. 可变变量$$ 在php中,可变变量可以用$$来表示, 代码如下: $name = "zhangSan"; $$name = "liSi"; //相当于$ ...
- PHP MySQL Insert Into
INSERT INTO 语句用于向数据库表中插入新记录. 向数据库表插入数据 INSERT INTO 语句用于向数据库表添加新记录. 语法 INSERT INTO table_name VALUES ...
- Android 查看每个应用的最大可用内存
http://blog.csdn.net/vshuang/article/details/39647167 Android 内存管理 &Memory Leak & OOM 分析 ...
- 《转载》struts旅程《1》
struts简介 Struts是Apache软件基金会(ASF)赞助的一个开源项目.它最初是jakarta项目中的一个子项目,并在2004年3月成为ASF的顶级项目.它通过采用JavaServlet/ ...