pytest系列——pytest-xdist插件之多进程运行测试用例|| pytest-parallel插件之多线程运行测试用例

news2024/10/5 14:26:33

pytest之多进程运行测试用例(pytest-xdist)

前言

  • 平常我们功能测试用例非常多时,比如有1千条用例,假设每个用例执行需要1分钟,如果单个测试人员执行需要1000分钟才能跑完
  • 当项目非常紧急时,会需要协调多个测试资源来把任务分成两部分,于是执行时间缩短一半,如果有10个小伙伴,那么执行时间就会变成十分之一,大大节省了测试时间
  • 为了节省项目测试时间,10个测试同时并行测试,这就是一种分布式场景

分布式执行用例的原则:

  • 用例之间是独立的,没有依赖关系,完全可以独立运行
  • 用例执行没有顺序要求,随机顺序都能正常执行
  • 每个用例都能重复运行,运行结果不会影响其他用例
背景:

我们日常的工作当中进行自动化测试编写的测试用例会非常多,测试用例一个一个的执行所需要花费的时间会很长,你想象一下如果开发改动一块代码,我们需要回归一下,这时候执行一下自动化用例需要花费一小时或者好几个小时的时间,这是我们无法容忍的。

为了解决这个问题,我们采用pytest的插件pytest-xdist来进行多进程的并发执行测试用例,大大的缩短测试用例的执行时间,提高效率

并发运行测试用例:

1、安装pytest-xdist

<span style="color:#111111"><span style="background-color:#ffffff"><code class="language-mipsasm">pip <span style="color:#0000ff">install </span>pytest-xdist
</code></span></span>

2、多进程并发执行测试用例:不支持多线程

<span style="color:#111111"><span style="background-color:#ffffff"><code class="language-bash">pytest test_add.py -n NUM    <span style="color:#008000"># NUM表示并发的进程数</span>
</code></span></span>

参数配置

-n=* :*代表进程数

解释:

①多cpu并行执行用例,直接加个-n参数即可,后面num参数就是并行数量,比如num设置为3
-n auto : 自动侦测系统里的CPU数目
-n num : 指定运行测试的处理器进程数

3、举例:

项目结构如下:

image

代码:

<span style="color:#111111"><span style="background-color:#ffffff"><code class="language-python"><span style="color:#008000"># file_name: test_a.py</span>

<span style="color:#0000ff">import</span> pytest
<span style="color:#0000ff">import</span> time


<span style="color:#0000ff">def</span> <span style="color:#a31515">test_a_01</span>():
    <span style="color:#0000ff">print</span>(<span style="color:#a31515">"----------------->>> test_a_01"</span>)
    time.sleep(<span style="color:#880000">1</span>)
    <span style="color:#0000ff">assert</span> <span style="color:#880000">1</span>


<span style="color:#0000ff">def</span> <span style="color:#a31515">test_a_02</span>():
    <span style="color:#0000ff">print</span>(<span style="color:#a31515">"----------------->>> test_a_02"</span>)
    time.sleep(<span style="color:#880000">1</span>)
    <span style="color:#0000ff">assert</span> <span style="color:#880000">1</span>


<span style="color:#0000ff">def</span> <span style="color:#a31515">test_a_03</span>():
    <span style="color:#0000ff">print</span>(<span style="color:#a31515">"----------------->>> test_a_03"</span>)
    time.sleep(<span style="color:#880000">1</span>)
    <span style="color:#0000ff">assert</span> <span style="color:#880000">1</span>


<span style="color:#0000ff">def</span> <span style="color:#a31515">test_a_04</span>():
    <span style="color:#0000ff">print</span>(<span style="color:#a31515">"----------------->>> test_a_04"</span>)
    time.sleep(<span style="color:#880000">1</span>)
    <span style="color:#0000ff">assert</span> <span style="color:#880000">1</span>


<span style="color:#0000ff">if</span> __name__ == <span style="color:#a31515">'__main__'</span>:
    pytest.main([<span style="color:#a31515">"-s"</span>, <span style="color:#a31515">"test_a.py"</span>])
</code></span></span>
<span style="color:#111111"><span style="background-color:#ffffff"><code class="language-python"><span style="color:#008000"># file_name: test_b.py</span>


<span style="color:#0000ff">import</span> pytest
<span style="color:#0000ff">import</span> time


<span style="color:#0000ff">def</span> <span style="color:#a31515">test_b_01</span>():
    <span style="color:#0000ff">print</span>(<span style="color:#a31515">"----------------->>> test_b_01"</span>)
    time.sleep(<span style="color:#880000">1</span>)
    <span style="color:#0000ff">assert</span> <span style="color:#880000">1</span>


<span style="color:#0000ff">def</span> <span style="color:#a31515">test_b_02</span>():
    <span style="color:#0000ff">print</span>(<span style="color:#a31515">"----------------->>> test_b_02"</span>)
    time.sleep(<span style="color:#880000">1</span>)
    <span style="color:#0000ff">assert</span> <span style="color:#880000">1</span>


<span style="color:#0000ff">def</span> <span style="color:#a31515">test_b_03</span>():
    <span style="color:#0000ff">print</span>(<span style="color:#a31515">"----------------->>> test_b_03"</span>)
    time.sleep(<span style="color:#880000">1</span>)
    <span style="color:#0000ff">assert</span> <span style="color:#880000">1</span>


<span style="color:#0000ff">def</span> <span style="color:#a31515">test_b_04</span>():
    <span style="color:#0000ff">print</span>(<span style="color:#a31515">"----------------->>> test_b_04"</span>)
    time.sleep(<span style="color:#880000">1</span>)
    <span style="color:#0000ff">assert</span> <span style="color:#880000">1</span>


<span style="color:#0000ff">if</span> __name__ == <span style="color:#a31515">'__main__'</span>:
    pytest.main([<span style="color:#a31515">"-s"</span>, <span style="color:#a31515">"test_b.py"</span>])
</code></span></span>

①正常运行以上代码,耗时:8.09s

image

②设置并行运行数量为4,耗时:3.48s,大大的缩短了测试用例的执行时间。

image

pytest-xdist分布式测试的原理

前言

1、xdist的分布式类似于一主多从的结构,master机负责下发命令,控制slave机;slave机根据master机的命令执行特定测试任务。

2、在xdist中,主是master,从是workers。

大致原理

1、xdist会产生一个或多个workers,workers都通过master来控制。

2、每个worker负责执行完整的测试用例集,然后按照master的要求运行测试,而master机不执行测试任务。

pytest-xdist分布式测试的流程

第一步:创建worker

1、master会在总测试会话(test session)开始前产生一个或多个worker。

2、master和worker之间是通过execnet和网关来通信的。

3、实际编译执行测试代码的worker可能是本地机器也可能是远程机器。

第二步:收集测试项用例

1、每个worker类似一个迷你型的pytest执行器。

2、worker会执行一个完整的test collection过程。【收集所有测试用例的过程】

3、然后把测试用例的ids返回给master。【ids表示收集到的测试用例路径】

4、master是不会执行任何测试用例集的。
注意:分布式测试(pytest-xdist)方式执行测试时不会输出测试用例中的print内容,因为主机并不执行测试用例,pycharm相当于一个master。

第三步:master检测workers收集到的测试用例集

1、master接收到所有worker收集的测试用例集之后,master会进行一些完整性检查,以确保所有worker都收集到一样的测试用例集(包括顺序)。

2、如果检查通过,会将测试用例的ids列表转换成简单的索引列表,每个索引对应一个测试用例的在原来测试集中的位置。

3、这个方案可行的原因是:所有的节点都保存着相同的测试用例集。

4、并且使用这种方式可以节省带宽,因为master只需要告知workers需要执行的测试用例对应的索引,而不用告知完整的测试用例信息。

第四步:测试用例分发

--dist-mode选项

each:master将完整的测试索引列表分发到每个worker。

load:master将大约25%的测试用例以轮询的方式分发到各个worker,剩余的测试用例则会等待workers执行完测试用例以后再分发

注意:可以使用pytest_xdist_make_scheduler 这个hook来实现自定义测试分发逻辑。

第五步:测试用例的执行

1、workers 重写了 pytest_runtestloop :pytest的默认实现是循环执行所有在test session这个对象里面收集到的测试用例。

2、但是在xdist里, workers实际上是等待master为其发送需要执行的测试用例。

3、当worker收到测试任务, 就顺序执行 pytest_runtest_protocol 。

4、值得注意的一个细节是:workers 必须始终保持至少一个测试用例在的任务队列里, 以兼容 pytest_runtest_protocol(item, nextitem) hook的参数要求,为了将 nextitem传给hook。

5、worker会在执行最后一个测试项前等待master的更多指令。

6、如果它收到了更多测试项, 那么就可以安全的执行 pytest_runtest_protocol ,因为这时nextitem参数已经可以确定。

7、如果它收到一个 "shutdown"信号, 那么就将 nextitem 参数设为 None, 然后执行 pytest_runtest_protocol

第六步:测试用例再分发(--dist-mode=load)

1、当workers开始/结束执行时,会把测试结果返回给master,这样其他pytest hook比如: pytest_runtest_protocol就可以正常执行

2、master在worker执行完一个测试后,基于测试执行时长以及每个work剩余测试用例综合决定是否向这个worker发送更多的测试用例

第七步:测试结束

1、当master没有更多执行测试任务时,它会发送一个“shutdown”信号给所有worker。

2、当worker将剩余测试用例执行完后退出进程。

3、master等待所有worker全部退出。

4、然而此时仍需要处理诸如 pytest_runtest_logreport 等事件。

pytest实现多线程运行测试用例(pytest-parallel)

安装

<span style="color:#111111"><span style="background-color:#ffffff"><code class="language-mipsasm">pip <span style="color:#0000ff">install </span>pytest-parallel
</code></span></span>

常用参数配置

① --workers=n :多进程运行需要加此参数, n是进程数。默认为1

② --tests-per-worker=n :多线程需要添加此参数,n是线程数

如果两个参数都配置了,就是进程并行;每个进程最多n个线程,总线程数:进程数*线程数

【注意】

①在windows上进程数永远为1。

②需要使用 if name == “main” :,在dos中运行会报错(即在命令行窗口运行测试用例会报错)

示例:

pytest test.py --workers 3 :3个进程运行
pytest test.py --tests-per-worker 4 :4个线程运行
pytest test.py --workers 2 --tests-per-worker 4 :2个进程并行,且每个进程最多4个线程运行,即总共最多8个线程运行。

<span style="color:#111111"><span style="background-color:#ffffff"><code class="language-python"><span style="color:#0000ff">import</span> pytest


<span style="color:#0000ff">def</span> <span style="color:#a31515">test_03</span>():
    <span style="color:#0000ff">print</span>(<span style="color:#a31515">'测试用例3操作'</span>)


<span style="color:#0000ff">def</span> <span style="color:#a31515">test_04</span>():
    <span style="color:#0000ff">print</span>(<span style="color:#a31515">'测试用例4操作'</span>)


<span style="color:#0000ff">if</span> __name__ == <span style="color:#a31515">"__main__"</span>:
    pytest.main([<span style="color:#a31515">"-s"</span>, <span style="color:#a31515">"test_b.py"</span>, <span style="color:#a31515">'--workers=2'</span>, <span style="color:#a31515">'--tests-per-worker=4'</span>])
</code></span></span>

pytest-parallel与pytest-xdist对比说明

① pytest-parallel 比 pytst-xdist 相对好用,功能支持多。

② pytst-xdist 不支持多线程;

pytest-parallel 支持python3.6及以上版本,所以如果想做多进程并发在linux或者mac上做,在Windows上不起作用(Workers=1),如果做多线程linux/mac/windows平台都支持,进程数为workers的值。

 自动化测试相关教程推荐:

2023最新自动化测试自学教程新手小白26天入门最详细教程,目前已有300多人通过学习这套教程入职大厂!!_哔哩哔哩_bilibili

2023最新合集Python自动化测试开发框架【全栈/实战/教程】合集精华,学完年薪40W+_哔哩哔哩_bilibili

测试开发相关教程推荐

2023全网最牛,字节测试开发大佬现场教学,从零开始教你成为年薪百万的测试开发工程师_哔哩哔哩_bilibili

postman/jmeter/fiddler测试工具类教程推荐

讲的最详细JMeter接口测试/接口自动化测试项目实战合集教程,学jmeter接口测试一套教程就够了!!_哔哩哔哩_bilibili

2023自学fiddler抓包,请一定要看完【如何1天学会fiddler抓包】的全网最详细视频教程!!_哔哩哔哩_bilibili

2023全网封神,B站讲的最详细的Postman接口测试实战教学,小白都能学会_哔哩哔哩_bilibili

  总结:

 光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。

如果对你有帮助的话,点个赞收个藏,给作者一个鼓励。也方便你下次能够快速查找。

如有不懂还要咨询下方小卡片,博主也希望和志同道合的测试人员一起学习进步

在适当的年龄,选择适当的岗位,尽量去发挥好自己的优势。

我的自动化测试开发之路,一路走来都离不每个阶段的计划,因为自己喜欢规划和总结,

测试开发视频教程、学习笔记领取传送门!!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

让CHAT简单说明下软件工程师的工作性质

问CHAT&#xff1a;软件工程师的工作性质是什么&#xff1f; CHAT回复&#xff1a;软件工程师的工作性质主要包括以下几点&#xff1a; 1. 解决问题&#xff1a;软件工程师的很大一部分工作就是解决问题&#xff0c;这可能是来自客户的特定需求&#xff0c;也可能是软件开发过…

kali安装内网穿透工具并实现ssh远程连接

文章目录 1. 启动kali ssh 服务2. kali 安装cpolar 内网穿透3. 配置kali ssh公网地址4. 远程连接5. 固定连接SSH公网地址6. SSH固定地址连接测试 简单几步通过[cpolar 内网穿透](cpolar官网-安全的内网穿透工具 | 无需公网ip | 远程访问 | 搭建网站)软件实现ssh远程连接kali 1…

如何用CHAT配置linux的远程连接?

问CHAT&#xff1a;配置linux的远程连接 1.下载ssh 2.启动ssh服务 3.查看ssh服务状态 4.设置ssh服务开机自启动 5.设置windows的cmd下ssh 6.通过cmd的ssh命令远程到linux linux的ip:10.8.9.23 用户名:Li CHAT回复&#xff1a;以下是为配置Linux的远程连接的步骤说明&#xff1a…

一文读懂 | AI技术如何驱动企业供应链智能化,赋能企业降本增效?

近年以来&#xff0c;随着互联网技术的发展&#xff0c;AI的创新研究加速。随着大数据、云计算、物联网等信息技术的发展&#xff0c;以深度神经网络为代表的AI技术迅速发展&#xff0c;图像分类、语音识别、知识问答、无人驾驶等AI技术实现了从“不能用、不好用”到“可以用”…

利用广度优先或模拟解决米诺骨牌

本周推荐阅读 C二分算法&#xff1a;得到子序列的最少操作次数 题目 n 张多米诺骨牌排成一行&#xff0c;将每张多米诺骨牌垂直竖立。在开始时&#xff0c;同时把一些多米诺骨牌向左或向右推。 每过一秒&#xff0c;倒向左边的多米诺骨牌会推动其左侧相邻的多米诺骨牌。同样…

分享:身份证阅读器在ARM Linux系统调用libwlt2bmp.so解码库实现身份证头像解码

头像解码库&#xff1a;libwlt2bmp.so 照片文件名&#xff1a;photo.bmp 原始身份证相片数据&#xff1a;574C66007E00320000F........&#xff08;此处省略&#xff09; 调用身份证阅读器Linux开发包&#xff0c;然后调用libwlt2bmp.so解码库文件&#xff0c;传入身份证原始…

谭巍主任贴心分享:想要HPV尽快转阴必吃的五种水果

HPV感染是常见的生殖道病毒感染&#xff0c;它可能导致宫颈癌等严重疾病。对于HPV感染者来说&#xff0c;转阴是预防和治疗的关键。北京劲松HPV诊疗中心主任谭巍认为除了接受正规的治疗和注意生活方式的调整外&#xff0c;饮食也是促进HPV快速转阴的重要方面。 一、苹果 苹果…

在思岚A1上复现gmapping

文章目录 软硬件条件laser_scan_matcher通过源码安装rplidar_ros通过源码安装设置参数启动效果预览 软硬件条件 软件&#xff1a;Ubuntu 20.04&#xff0c;ROS noetic 硬件&#xff1a;RPLidar A1. laser_scan_matcher通过源码安装 mkdir -p ~/catkin_ws/src cd ~/catkin_w…

特斯拉开源 Roadster 文件随便用;微软 Copilot AI 技术开放或不对大陆开放丨 RTE 开发者日报 Vol.92

开发者朋友们大家好&#xff1a; 这里是 「RTE 开发者日报」 &#xff0c;每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE &#xff08;Real Time Engagement&#xff09; 领域内「有话题的 新闻 」、「有态度的 观点 」、「有意思的 数据 」、「有思考的 文…

【数字化转型方法论读书笔记】-数据中台落地实施之法

让数据中台真正落地是实现数字化转型的重中之重。企业做好数据治理、体系建设及人才配备等前期工作后&#xff0c;接下来要做的是数据中台实施落地的关键。 企业首先要掌握数据中台建设的三大核心要素&#xff1a;选对数据建设方式、厘清建设思路、避开数据中台建设误区&#…

Banana Pi最新的路由器板BPI-R4上市销售,基于MediaTek MT7988A

Banana Pi 发布了一款新的路由器板 Banana Pi BPI-R4&#xff0c;基于配备四核 Arm CPU 的 MediaTek MT7988A SoC。该板不仅仅是Raspberry Pi 的另一个替代品&#xff0c;而且是用于家庭网络和自动化的设备。 Banana Pi BPI-R4 的外形尺寸比单板计算机更像网络设备。对于那些希…

ubuntu22.04识别CH340的问题汇总

一、目的 自己的电脑装的是双系统&#xff0c;ubuntu22.04安装了很久好久没有&#xff08;WSL2确实解决了频繁依赖linux的问题&#xff09;。昨天尝试搞一下STM32MP135的系统搭建&#xff0c;开始启用ubuntu22.04。但是遇到了很多问题&#xff0c;其中一个问题就是CH340的驱动…

【JavaScript】3.2 JavaScript性能优化

文章目录 1. 避免全局查找2. 避免不必要的属性查找3. 使用快速的JavaScript方法4. 避免不必要的DOM操作5. 使用Web Workers进行后台处理总结 性能优化是任何编程语言的重要组成部分&#xff0c;JavaScript也不例外。在这个章节中&#xff0c;我们将探讨如何优化JavaScript代码&…

【JavaEE】Java中的多线程 (Thread类)

作者主页&#xff1a;paper jie_博客 本文作者&#xff1a;大家好&#xff0c;我是paper jie&#xff0c;感谢你阅读本文&#xff0c;欢迎一建三连哦。 本文录入于《JavaEE》专栏&#xff0c;本专栏是针对于大学生&#xff0c;编程小白精心打造的。笔者用重金(时间和精力)打造&…

c语言,输入整数n(行数,本例为4),按照如下规则打印数字图片 1 5 9 13 2 6 10 14 3 7 11 15 4 8 12 16

c语言&#xff0c;输入整数n(行数&#xff0c;本例为4&#xff09;&#xff0c;按照如下规则打印数字图片 1 5 9 13 2 6 10 14 3 7 11 15 4 8 12 16 以下是使用C语言编写的程序&#xff0c;根据输入的行数打印数字图片的规则&#xff1a; #include <stdio.h>int main() …

深度学习大数据物流平台 python 计算机竞赛

文章目录 0 前言1 课题背景2 物流大数据平台的架构与设计3 智能车货匹配推荐算法的实现**1\. 问题陈述****2\. 算法模型**3\. 模型构建总览 **4 司机标签体系的搭建及算法****1\. 冷启动**2\. LSTM多标签模型算法 5 货运价格预测6 总结7 部分核心代码8 最后 0 前言 &#x1f5…

Spinnaker 基于 docker registry 触发部署

docker registry 触发部署 Spinnaker可以通过Docker镜像的变化来触发部署&#xff0c;这种方法允许你在Docker镜像发生变化时自动启动新的部署流程。 示例原理如下图所示&#xff1a; 以下是如何在Spinnaker中实现基于Docker Registry触发部署的配置流程。最终实现的效果如下…

3D ACIS Modeler和HOOPS Visualize助力鲁班软件打造BIM数字化平台

鲁班软件成立于2001年&#xff0c;始终致力于BIM技术研发和推广&#xff0c;为建筑产业相关企业提供基于BIM技术的数字解决方案&#xff0c;专注打造能够支撑建筑企业集团发展的BIM数字化平台鲁班工程管理数字平台(Luban Builder)&#xff0c;以及可承载园区级或城市级的BIM、C…

NX二次开发UF_CURVE_create_arc_3tangent 函数介绍

文章作者&#xff1a;里海 来源网站&#xff1a;https://blog.csdn.net/WangPaiFeiXingYuan UF_CURVE_create_arc_3tangent Defined in: uf_curve.h int UF_CURVE_create_arc_3tangent(tag_t tangent_object1, tag_t tangent_object2, tag_t tangent_object3, UF_CURVE_help_…

Sass基础知识详细讲解【附带表图】

文章目录 前言使用 SassRack / Rails / Merb插件缓存选项语法选择编码 Sass CSS扩展Sass 注释输出 Sass 脚本Sass -规则和指令Sass 控制指令和表达式 Sass 混入指令Sass 功能指令命名约定Sass 输出样式:nested:expanded:compact:compressedSass 扩展缓存存储自定义导入 后言 前…