TestNG并行测试
并行(多线程)技术在软件术语里被定义为软件、操作系统或者程序可以并行地执行另外一段程序中多个部分或者子组件的能力。TestNG允许我们以并行(多线程)的方式来执行测试。这就意味着基于TestNG测试组件的配置,多个线程可以被同时启动然后分别执行各自的测试方法。相对于传统的单线程执行测试的方式,这种多线程方式拥有很大的优势,主要是它可以减少测试运行时间,并且可以验证某段代码在多线程环境中运行的正确性。
目录
- 并行执行测试的优势
- 如何并行地执行测试方法
- 如何并行地执行测试类
- 如何并行地执行同一测试套件内的各个测试组件
- 如何配置需要在多线程环境中执行的测试方法
并行执行测试的优势
并行(多线程)执行测试可以给用户带来很多好处,主要包括以下两点:
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> |
在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所指定的次数相同。而且从输出信息中,我们也可以很清晰地看到该测试方法每次执行都是在不同的线程中完成的。当我们需要按照某一固定次数,在多线程环境下运行某些测试方法时,上述特性会很有帮助,因为它避免了我们把整个测试套件都并行执行多次的代价。
原文:http://www.importnew.com/14508.html
TestNG并行测试的更多相关文章
- Maven捆绑TestNG实现测试自动化执行、部署和调度
一. 需求介绍 自动化测试,尤其是接口测试时,要写大量的测试用例,这些测试用例我们当然首选使用TesteNG编写,用例数量大,还涉及各种依赖包之类的问题,因此用Maven管理也是最方便最易实现的. 面 ...
- TestNG 搭建测试框架 自动化测试
框架层级及基本组件: 参考:https://www.cnblogs.com/jier888/p/8998724.html Java作为开发语言 Maven管理项目及Jar包 Testng作为测试 ...
- 使用 TestNG 并发测试 ;
使用TestNG对IE /Chrome/firefox 进行兼容性并发测试 : package testNGTest; import org.openqa.selenium.By; import or ...
- U3D协程Coroutine之WWW与Update()的并行测试
using System.Collections; using UnityEditor; using UnityEngine; using UnityEngine.UI; /************* ...
- TestNG之测试执行后没有生成默认测试报告(IDEA)
使用IDEA+TestNG进行测试,没有生成 测试报告,是因为没有勾选监听器使用默认报告,具体操作如下: “Run” -> "Edit Configurations" -&g ...
- appium多机并行测试
在实际应用中需要对多个机型并行测试,节省时间 多机测试的思路 启动多个appium server与多台机器交互(android和ios均可) 注意:一定要使用node安装appium的命令行,使用 ...
- testng入门教程10 TestNG参数化测试
在TestNG的另一个有趣的功能是参数测试.在大多数情况下,你会遇到这样一个场景,业务逻辑需要一个巨大的不同数量的测试.参数测试,允许开发人员运行同样的测试,一遍又一遍使用不同的值. TestNG让你 ...
- testng入门教程9 TestNG依赖测试
有时候,你可能需要在一个特定的顺序调用方法在测试案例,或你想分享一些数据和方法之间的状态.TestNG支持这种依赖测试方法之间的显式依赖它支持声明. TestNG允许指定依赖,无论与否: 使用属性de ...
- testng入门教程8 TestNG异常测试
TestNG跟踪异常处理代码提供了一个选项.可以测试是否需要代码抛出异常或不抛出. @Test注释expectedExceptions 参数一起使用.现在,让我们来看看@Test(expectedEx ...
随机推荐
- MySQL所学所思所想
MySQL更改线上配置方案思想:原则上,需要备机.备份工作准备到位,有参数调优配置方案.有配置回退方案.有应急切换备机方案.以上方案评审无问题,然后可以和客户约定实施的时间.服务中断时间,先向客户侧申 ...
- 【Linux笔记(001) 】-- centos7 系统目录结构与文件
一.目录结构与用途: /boot:系统引导文件.内核 /bin:用户的基本命令 /dev:设备文件 /etc:配置文件 /home:用户目录 /root:root用户目录 /sbin:管理类的基本命令 ...
- 二、js的控制语句
二.流程控制语句 ECMA-262规定了一组流程控制语句.语句定义了ECMAScript中的主要语法,语句通常由一个或者多个关键字来完成给定的任务.诸如:判断.循环.退出等. 语句的定义 在E ...
- 使用SoapUI工具做get请求和post请求接口测试
祝大家节日快乐啦. 之前写过的一篇帖子已经介绍了SoapUI工具的基本使用,所以在此不再重复讲解关于建工程.建测试套件.添加用例等操作,可查看该篇文章详解:http://www.cnblogs.com ...
- 再起航,我的学习笔记之JavaScript设计模式28(委托模式)
## 委托模式 ### 概念介绍 **委托模式(Entrust): **多个对象接收并处理同一请求,他们将请求委托给另一个对象统一处理请求. ### 利用委托优化循环 如果我们有一个需求需要让用户点击 ...
- 【JAVA零基础入门系列】Day5 Java中的运算符
运算符,顾名思义就是用于运算的符号,比如最简单的+-*/,这些运算符可以用来进行数学运算,举个最简单的栗子: 已知长方形的长为3cm,高为4cm,求长方形的面积. 好,我们先新建一个项目,命名为Rec ...
- C#中回车出发事件(+收藏)
本文给大家介绍如何在c# winform中实现回车事件和回车键触发按钮的完美写法 我们常常要在c# winform中实现回车(enter)提交功能,这样比手动按按钮触发更快. 要完成回车按按钮功能,只 ...
- JavaScript 版数据结构与算法(二)队列
今天,我们要讲的是数据结构与算法中的队列. 队列简介 队列是什么?队列是一种先进先出(FIFO)的数据结构.队列有什么用呢?队列通常用来描述算法或生活中的一些先进先出的场景,比如: 在图的广度优先遍历 ...
- SQL Server 锁机制 悲观锁 乐观锁 实测解析
先引入一些概念,直接Copy其他Blogs中的,我就不单独写了. 一.为什么会有锁 多个用户同时对数据库的并发操作时会带来以下数据不一致的问题: 1.丢失更新 A,B两个用户读同一数据并进行修改,其中 ...
- Linux-jdk1.7-tomcat7 简易安装
一.jdk 安装 安装包:jdk-7u80-linux-x64.tar.gz 2 解压 [root@localhost package]# tar -zxvf jdk-7u80-linux-x64.t ...