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

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.mzph.cn/news/173935.shtml

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

相关文章

警惕!AI正在“吞食”你的数据

视觉中国供图 □ 科普时报记者 陈 杰 AI大模型的热度&#xff0c;已然开始从产业向日常生活渗透&#xff0c;并引起不小的舆论旋涡。近日&#xff0c;网友指出国内某智能办软件有拿用户数据“投喂”AI之嫌&#xff0c;引发口水的同时&#xff0c;再度把公众对AI的关注转移到数…

使用paddledetection的记录

首先在这里使用的是是paddle--detection2.7的版本。 成功进行训练 目录&#xff1a; 目录 数据集准备 配置文件的修改 使用的是BML的平台工具&#xff1a; !python -m pip install paddlepaddle-gpu2.5 -i https://mirror.baidu.com/pypi/simple --user %cd /home/aistudio…

Rust语言入门教程(七) - 所有权系统

所有权系统是Rust敢于声称自己为一门内存安全语言的底气来源&#xff0c;也是让Rust成为一门与众不同的语言的所在之处。也正是因为这个特别的所有权系统&#xff0c;才使得编译器能够提前暴露代码中的错误&#xff0c;并给出我们必要且精准的错误提示。 所有权系统的三个规则…

Anaconda安装教程(超详细版)

目录 一、Anaconda简介 二、运行环境 三、安装Anaconda 四、手动配置环境变量&#xff08;重点&#xff09; 五、测试Anaconda环境是否配置成功 一、Anaconda简介 Anaconda&#xff0c;一个开源的Python发行版本&#xff0c;可用于管理Python及其相关包&#xff0c;包含了…

慕尼黑电子展采访全程 | Samtec管理层对话电子发烧友:虎家卓越服务

【摘要/前言】 今年的慕尼黑上海电子展上&#xff0c;Samtec大放异彩&#xff0c;特装展台一亮相就获得了大家的广泛关注&#xff0c;展台观众络绎不绝。 作为深耕连接器行业数十年的知名厂商以及Electronica的常客&#xff0c;Samtec毫无疑问地获得了大量媒体朋友的关注和报…

【数据结构】二叉树之链式结构

&#x1f525;博客主页&#xff1a; 小羊失眠啦. &#x1f3a5;系列专栏&#xff1a;《C语言》 《数据结构》 《Linux》《Cpolar》 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 文章目录 一、前置说明二、二叉树的遍历2.1 前序遍历2.2 中序遍历2.3 后序遍历2.4 层序遍历 三、…

如何在本地安装部署WinSCP,并实现公网远程本地服务器

可视化文件编辑与SSH传输神器WinSCP如何公网远程本地服务器 文章目录 可视化文件编辑与SSH传输神器WinSCP如何公网远程本地服务器1. 简介2. 软件下载安装&#xff1a;3. SSH链接服务器4. WinSCP使用公网TCP地址链接本地服务器5. WinSCP使用固定公网TCP地址访问服务器 1. 简介 …

送PDF书 | 豆瓣9.2分,超250万Python新手的选择!蟒蛇书入门到实践

在此疾速成长的科技元年&#xff0c;编程就像是许多人通往无限可能世界的门票。而在编程语言的明星阵容中&#xff0c;Python就像是那位独领风 骚的超级巨星&#xff0c; 以其简洁易懂的语法和强大的功能&#xff0c;脱颖而出&#xff0c;成为全球最炙手可热的编程语言之一。 …

Gitea和Jenkins安装

Gitea Gitea&#xff1a;https://dl.gitea.com/gitea/1.21.0/ Jenkins&#xff1a;https://www.jenkins.io/download/ 数据库配置 可以参考官方文档-https://docs.gitea.cn/1.20/installation/database-prep&#xff0c;这里以MySQL作为讲解 MySQL 在数据库实例上&#xf…

智能物流时代:快递物流信息订阅与推送API自动推送物流变更信息

引言 在当今数字化和智能化的时代&#xff0c;物流行业也在迅速演变&#xff0c;通过技术创新提高效率、提升服务质量。其中&#xff0c;快递物流信息订阅与推送API的自动推送功能成为推动物流领域发展的重要驱动力。本文将深入探讨这一趋势&#xff0c;并分析快递物流信息订阅…

完美解决:vue.js:6 TypeError: Cannot read properties of undefined (reading ‘0‘)

Vue项目出现以下报错&#xff1a; 原因&#xff1a; 在渲染的时候&#xff0c;不满足某个条件而报错&#xff0c;或者某个属性丢失或后台没传过来导致 我这里出现的原因是后台给我传递过来的数组中&#xff0c;其中有一条少传了一个我在渲染时需要用的属性&#xff0c;没让后台…

如何使用Java支付宝沙箱环境并公网调用sdk创建支付单服

Java支付宝沙箱环境支付&#xff0c;SDK接口远程调试【内网穿透】 1.测试环境 MavenSpring bootJdk 1.8 2.本地配置 获取支付宝支付Java SDK,maven项目可以选择maven版本,普通java项目可以在GitHub下载,这里以maven为例 SDK下载地址&#xff1a;https://doc.open.alipay.com…

阻塞队列及简单实现,生产者消费者模型

文章目录 阻塞队列阻塞队列是什么生产者消费者模型阻塞队列的实现 阻塞队列 阻塞队列是什么 阻塞队列是一种特殊的队列. 也遵守 “先进先出” 的原则. 当队列满的时候, 继续入队列就会阻塞, 直到有其他线程从队列中取走元素当队列空的时候, 继续出队列也会阻塞, 直到有其他线…

有效实施的五条教学策略

作为老师&#xff0c;是否曾为如何提高教学质量而苦恼&#xff1f;也为如何引导学生而思考&#xff1f;如果你正面临这些困扰&#xff0c;那么这篇文章将对你有帮助。为你介绍五条教学策略&#xff0c;帮你实施教学&#xff0c;提高效果。 明确教学目标 你是否知道你的教学目标…

针对操作系统漏洞的反馈方法

一、针对操作系统漏洞的反馈方法 漏洞扫描指基于漏洞数据库&#xff0c;通过扫描等手段对指定的远程或者本地计算机系统的安全脆弱性进行检测&#xff0c;发现可利用漏洞的一种安全检测&#xff08;渗透攻击&#xff09;行为。在进行漏洞扫描后&#xff0c;需先确定哪些是业务…

Go 内置运算符

一、算数运算符 1、算数运算符使用 package mainimport ("fmt" )func main(){fmt.PrintIn("103",103) //10313fmt.PrintIn("10-3",10-3) //10-37fmt.PrintIn("10*3",10*3) //10*330//除法注意&#xff1a;如果运算的数都是…

视频后期效果制作工具Mocha Pro 2022 Plugins mac中文版软件介绍

Mocha Pro 2022 mac是一款专业的三维摄像机反求摩卡跟踪插件&#xff0c;同时也是一款视频后期效果制作工具&#xff0c;Mocha Pro 2022下载能够给数字媒体艺术家提供强大的、直观的和创新的追踪解决方案用简化的界面、加速的工作流程以及轻松追踪和操作镜头的强大性&#xff0…

js moment时间范围拿到中间间隔时间

2023.11.27今天我学习了如何对只返回的开始时间和结束时间做处理&#xff0c;比如后端返回了&#xff1a; [time:{start:202301,end:202310}] 我们需要把中间的间隔渲染出来。 [202301,202302,202303,202304,202305,202306,202307,202308,202309,202310] 利用moment的add进…

Linux下使用Docker部署MinIO存储服务实现远程上传

&#x1f4d1;前言 本文主要是Linux下通过Docker部署MinIO存储服务实现远程上传的文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是青衿&#x1f947; ☁️博客首页&#xff1a;CSDN主页放风讲故事 &#…

【AD9371 AD9375 概要总结】A ...

目录 工作原理发射器 TRANSMITTER&#xff08;Tx&#xff09;接收器 RECEIVER &#xff08;Rx&#xff09;观测接收器 OBSERVATION RECEIVER &#xff08;ORx&#xff09;嗅探接收器 SNIFFER RECEIVER&#xff08;SnRx&#xff09;时钟输入 CLOCK INPUTSYNTHESIZERS合成RF PLL射…