分析:如何多线程运行测试用例

这是时常被问到的问题,尤其是UI自动化的运行,过程非常耗时,所以,所以多线程不失为一种首先想到的解决方案。

多线程是针对的测试用例,所以和selenium没有直接关系,我们要关心的是单元测试框架。

unittest

首先,应该说明的是unittest本身是不支持多线程的。当然,如果你学过Python的threading模块,也未必不行。不过我在stackoverflow 找了半天,大多是介绍unittest 测试多线程模块,并非是unittest本身如何多线程运行用例。

“我如何学习葵花宝典” 和 “我如何验证 张三 学会了葵花宝典”是两回事,而我显然要解决的问题是前者。

又重新百度,结果就找了答案。核心借助 tomorrow3 的测试库,再配合HTMLTestRunner 生成测试报告。

GitHub - SeldomQA/XTestRunner: Modern style test report based on unittest framework.
GitHub - dflupu/tomorrow3: An implementation of the tomorrow package for python >= 3.0

  • 测试用例

测试用例如下,你可以复制多份测试。

# test_a.py
import time
import unittest
from selenium import webdriverclass Test1(unittest.TestCase):@classmethoddef setUpClass(cls):cls.driver = webdriver.Chrome()def test_01(self):self.driver.get("https://www.bing.com/?mkt=zh-CN")elem = self.driver.find_element_by_id("sb_form_q")elem.send_keys("多线程")elem.submit()time.sleep(2)self.assertIn("多线程", self.driver.title)@classmethoddef tearDownClass(cls):cls.driver.quit()if __name__ == "__main__":unittest.main()
  • 运行文件

核心在tomorrow3提供的threads装饰器,用于装饰测试运行方法。

import unittest
import os
from TestRunner import HTMLTestRunner
from tomorrow3 import threads# 定义目录
BASE_DIR = os.path.dirname(os.path.realpath(__file__))
TEST_DIR = os.path.join(BASE_DIR, "test_dir")
REPORT_DIR = os.path.join(BASE_DIR, "test_report")def test_suits():"""加载所有的测试用例"""discover = unittest.defaultTestLoader.discover(TEST_DIR,pattern="test_*.py")return discover@threads(2)  # !!!核心!!!! 设置线程数
def run_case(all_case, nth=0):"""执行所有的用例, 并把结果写入测试报告"""report_abspath = os.path.join(REPORT_DIR, f"result{nth}.html")with open(report_abspath, "wb+") as file:runner = HTMLTestRunner(stream=file, title='多线程测试报告')# 调用test_suits函数返回值runner.run(all_case)if __name__ == "__main__":cases = test_suits()# 循环启动线程for i, j in zip(cases, range(len(list(cases)))):run_case(i, nth=j)  # 执行用例,生成报告
总结:

确实可以(根据设置的线程数)同时开启两个浏览器运行,同时带来了两个问题。

  1. 程序会根据线程数,生成多份测试报告,每个测试报告统计当前线程所运行的测试结果。
  2. 如果去掉nth参数,设置为一个报告,那么第二个线程运行的结果不能正确展示的一张报告上。
  3. 至少每个线程中的用例要保证有浏览器的启动/关闭。

第3点,你可能不理解,我举个例子,小时候见过妈妈/奶奶缝衣服。假设一件衣服拿一根针来缝制,缝衣服最麻烦就是穿针引线,针眼很小,每次都要费半天功夫,小孩子眼神好,我时常被叫去穿针引线。那为了节约时间怎么办,我当然是把线弄的长长的,最好是一根针线可以缝制多件衣服。

在Selenium 中,定义的浏览器驱动driver,每一条用例都定义一次驱动,伴随而来的就每个用例都开启/关闭一次浏览器,这当然是非常耗时的,为了缩短这个时间,我们最好是启动一次浏览器把所有用例都跑完才关闭。

那么问题来了,当我们使用多线程之后,相当于多个人同时缝制衣服,共用一根针线肯定不行啊。至少需要每人一根针线吧!而且缝制衣服的人是变化的,为了赶时间就多两个人(多开两个线程),用例比较少就少几个人(少启两个线程),为了适应这种变化,那么最好一件衣配置一根针线,每件衣服是最小单位,一个人必须要独立的把一件衣服缝好。

为了使用多线程,我们就必须每条用例开启/关闭一次浏览器,这其实是另一种时间的浪费,为了弥补这里的浪费,你必须把线程开得足够多才行。

最后,你必须再配置一位统计员,去统计每个人缝制衣服的数量,合计到一个报告中。

pytest

多线程运行用例在 pytest 中就相对容易太多了,pytest-xdist 插件就可以完成这件事情。

GitHub - pytest-dev/pytest-xdist: pytest plugin for distributed testing and loop-on-failures testing modes.

  • 测试用例

测试用例如下,你可以复制多份测试。

# test_a.py
import time
from selenium import webdriverdef test_01():driver = webdriver.Chrome()driver.get("http://www.baidu.com")elem = driver.find_element_by_id("kw")elem.send_keys("unittest")elem.submit()time.sleep(2)assert driver.title == "unittest_百度搜索"driver.quit()def test_02():driver = webdriver.Chrome()driver.get("http://www.baidu.com")elem = driver.find_element_by_id("kw")elem.send_keys("python")elem.submit()time.sleep(2)assert driver.title == "python_百度搜索"driver.quit()
  • 运行文件

核心就是安装 pytest-xdist 插件,通过-n参数设置线程数即可。

import os
import pytest# 定义目录
BASE_DIR = os.path.dirname(os.path.realpath(__file__))
TEST_DIR = os.path.join(BASE_DIR, "test_dir")
REPORT_DIR = os.path.join(BASE_DIR, "test_report")if __name__ == '__main__':report_file = os.path.join(REPORT_DIR, "result.html")pytest.main(["-n", "2",  # !!核心!!!设置2个线程"-v", "-s", TEST_DIR,"--html=" + report_file,])
总结:

相对于unittest,在pytest实现多线程非常简单,最终线线程的测试结果也可以很好在一个测试报告中展示。

  1. 存在的问题,正如我上面讨论的,你必须为每个用例设置开启/关闭。除了额外消耗启动时间外,如果想统一配置用例通过哪个浏览器执行也会比较麻烦。
  2. 你的每一条用例应该保持绝对独立,不能出现这条用例依赖上条用例的执行结果。因为,这两条用例可能会分配由不同的线程执行。
  3. 正如上一条的原因,你不能控制用例的执行顺序。

最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/181823.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【电路笔记】-谐波

谐波 文章目录 谐波1、概述2、频谱分析3、已知信号4、未知信号5、总结 周期性信号并不总是完美的正弦模式,例如我们之前有关 正弦波的文章之一中介绍的那样。 有时,信号确实可以是简单正弦波的叠加,它们被称为复杂波形。 在本文中&#xff0…

CodeWhisperer 的使用心得

文章作者:小SS 亚马逊云科技开发者社区为开发者们提供全球的开发技术资源。这里有技术文档、开发案例、技术专栏、培训视频、活动与竞赛等。帮助中国开发者对接世界最前沿技术,观点,和项目,并将中国优秀开发者或技术推荐给全球云社…

uniapp 解决H5跨域的问题

uniapp 解决h5跨域问题 manifest.json manifest.json文件中,点击“源码视图”,在此对象的最后添加以下代码: "h5" : {"devServer" : {"port" : 8080, //端口号"disableHostCheck" : true,"proxy" :…

1.1 HTML4

一. 前言 1. 两位先驱 艾伦麦席森图灵 二战时期,破译了德军的战争编码一英格玛。让二战提前2年结束,拯救了上千万人的生命。设立图灵奖,被后人誉为:人工智能之父。 约翰冯诺依曼 制订了现代计算机标准一一冯诺依曼体系结构。提出:计算机要…

【代码】【5 二叉树】d3

关键字: 非叶子结点数、k层叶子结点数、层次遍历、找双亲结点、找度为1、叶子结点数

树莓派4无法进入桌面模式(启动后出现彩色画面,然后一直黑屏,但是可以正常启动和ssh)

本文记录了这段比较坎坷的探索之路,由于你的问题不一定是我最终解决方案的,可能是前面探索路上试过的,所以建议按顺序看排除前置问题。 双十一又买了个树莓派 4B,插上之前树莓派 4B 的 TF 卡直接就能使用(毕竟是一样规…

Node.js 中解析 HTML 的方法介绍

在 Web 开发中,解析 HTML 是一个常见的任务,特别是当我们需要从网页中提取数据或操作 DOM 时。掌握 Node.js 中解析 HTML 的各种方式,可以大大提高我们提取和处理网页数据的效率。本文将介绍如何在 Node.js 中解析 HTML。 基本概念 HTML 解析…

golang实现极简todolist

ToDoList 最近跟着qimi老师做了一个ToDoList,我做的GitHub地址贴在这里,但由于前端出了点问题,所以都是用postman进行测试 原项目地址 部分功能展示 删除代办 查找代办 下面给出思路 思路 其实这是一个很简单的增删改查的实现&#xff…

Flutter vs 前端 杂谈:SliverAppBar、手动实现Appbar、前端Html+JS怎么实现滚动变化型Appbar - 比较

Flutter vs 前端 杂谈 SliverAppBar的弹性背景的显隐效果使用HtmlJS怎么实现 作者:李俊才 (jcLee95):https://blog.csdn.net/qq_28550263 邮箱 :291148484163.com 本文地址:https://blog.csdn.net/qq_28550…

kafka动态认证 自定义认证 安全认证-亲测成功

kafka动态认证 自定义认证 安全认证-亲测成功 背景 Kafka默认是没有安全机制的,一直在裸奔。用户认证功能,是一个成熟组件不可或缺的功能。在0.9版本以前kafka是没有用户认证模块的(或者说只有SSL),好在kafka0.9版本…

【C/C++】虚函数表

class Animal { public:virtual void speak(){cout << "动物在说话" << endl;} };class Cat :public Animal { public://重写 函数返回值类型 函数名 参数列表 完全相同void speak(){cout << "小猫在说话" << endl;} };void DoSpe…

Linux下yum源配置实战

一、Linux下软件包的管理 1、软件安装方式 ① RPM包管理&#xff08;需要单独解决依赖问题&#xff09; ② YUM包管理&#xff08;需要有网络及YUM仓库的支持&#xff0c;会自动从互联网下载软件&#xff0c;自动解决依赖&#xff09; ③ 源码安装&#xff08;安装过程比较…

GEE数据集——2019、2020、2021、2022和2023年全球固定宽带和移动(蜂窝)网络性能Shapefile 格式数据集

全球固定宽带和移动&#xff08;蜂窝&#xff09;网络性能 全球固定宽带和移动&#xff08;蜂窝&#xff09;网络性能&#xff0c;分配给缩放级别 16 网络墨卡托图块&#xff08;赤道处约 610.8 米 x 610.8 米&#xff09;。数据以 Shapefile 格式和 Apache Parquet 格式提供&…

3.线性神经网络-3GPT版

#pic_center R 1 R_1 R1​ R 2 R^2 R2 目录 知识框架No.1 线性回归基础优化算法一、线性回归1、买房案例2、买房模型简化3、线性模型4、神经网络5、损失函数6、训练数据7、参数学习8、显示解9、总结 二、 基础优化算法1、梯度下降2、学习率3、小批量随机梯度下降4、批量大小5、…

项目实战:通过axios加载水果库存系统的首页数据

1、创建静态页面 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><link rel"stylesheet" href"style/index.css"><script src"script/axios.mi…

版本控制系统-SVN

SVN Apache Subversion 通常被缩写成 SVN&#xff0c;是一个开放源代码的版本控制系统。 官网&#xff1a;https://subversion.apache.org 资料&#xff1a;https://svnbook.red-bean.com、https://www.runoob.com/svn/svn-tutorial.html 下载&#xff1a;https://sourceforg…

5.数据表基本操作

目录 1.创建数据表 创建数据表的语法格式&#xff1a; 查看当前数据库的表&#xff1a; 主键 1.单字段主键 (1)在定义列的同时指定主键&#xff0c;语法规则如下&#xff1a; (2)在定义完所有列之后指定主键。 2.多字段联合主键 外键&#xff1a; 非空约束&#xff1…

周报4_YMK

FlashAttention 硬件知识 以 A100 (40GB HBM) 为例&#xff0c;下面显示其内存层次结构的粗略图。SRAM内存分布在108个流式多处理器(SMs)上&#xff0c;每个处理器192KB。片上SRAM比HBM快得多&#xff0c;但比HBM小得多&#xff0c;在计算方面&#xff0c;使用Tensor Core的B…

【漏洞复现】Aapache_Tomcat_AJP协议_文件包含漏洞(CVE-2020-1938)

感谢互联网提供分享知识与智慧&#xff0c;在法治的社会里&#xff0c;请遵守有关法律法规 文章目录 1.1、漏洞描述1.2、漏洞等级1.3、影响版本1.4、漏洞复现1、基础环境2、漏洞扫描3、漏洞验证 说明内容漏洞编号CVE-2020-1938漏洞名称Aapache_Tomcat_AJP文件包含漏洞漏洞评级高…

thinkPHP5怎么打开页面调试,查看网页运行时间

开启trace 在config.php中找到 ‘app_trace’ > false, 修改为&#xff1a; ‘app_trace’ > true,