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

news2025/1/19 14:13:41

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

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

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

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的值。

 总结:

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

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

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

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

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

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

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

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

相关文章

还不知道指针和引用的区别,一篇文章教会你

1、引用的概念 1.引用不是新定义一个变量&#xff0c;而是给已存在变量取了一个别名 2.编译器不会为引用变量开辟内存空间&#xff0c;它和它引用的变量共用同一块内存空间 比如:孙悟空&#xff0c;可以叫他孙悟空&#xff0c;也可以叫齐天大圣。本质他们就是一个人 2、引用的定…

CentOS 7 使用Fmt库

安装 fmt Git下载地址&#xff1a;https://github.com/fmtlib/fmt 步骤1&#xff1a;首先&#xff0c;你需要下载fmt的源代码。你可以从https://github.com/fmtlib/fmt或者源代码官方网站下载。并上传至/usr/local/source_code/ ​ 步骤2&#xff1a;下载完成后&#xff…

LINUX入门篇【8】----计算机组成原理以及OS知识的总结

前言&#xff1a; 从而本篇文章开始&#xff0c;我们将进入LINUX的进程篇&#xff0c;但学习进程之前&#xff0c;我们首先需要重新认识我们的计算机&#xff0c;并且正确认识到控制进程的OS&#xff0c;即操作系统是怎样在计算机运行的过程中起到作用的。下面就让我们一同去了…

第二十章:多线程

进程 线程的特点 1.进程是资源分配的最小单位&#xff0c;线程是最小的执行单位 2.一个进程可以有多个线程 3.线程共享进程资源 package twentyth;public class ThreadTest extends Thread {public void run() {for (int i 1; i < 10; i) {//继承重写方法System.out.p…

Thread的常用方法

一&#xff0c;常用方法 二&#xff0c;案例 父类&#xff1a; package ThreadLianXi;import ThreadLianXi.ZhiLeiA;public class Name {public static void main(String[] args)throws Exception{Thread t1 new ZhiLeiA("1号");//修改名字t1.setName("1号&quo…

文件夹批量改名技巧:高效整理文件,随机重命名文件夹

在日常生活中&#xff0c;经常要整理电脑上的文件和文件夹。其中&#xff0c;文件夹的命名是一个重要的环节&#xff0c;因为它可以帮助我们更好地组织和查找文件。有时候我们要对大量的文件夹进行重命名&#xff0c;这时就要使用一些技巧来提高效率。现在一起来看云炫文件管理…

【深度学习】卷积神经网络(CNN)

一、引子————边界检测 我们来看一个最简单的例子&#xff1a;“边界检测&#xff08;edge detection&#xff09;”&#xff0c;假设我们有这样的一张图片&#xff0c;大小88&#xff1a; 图片中的数字代表该位置的像素值&#xff0c;我们知道&#xff0c;像素值越大&#…

【Web】NodeJs相关例题wp

目录 ①[GKCTF 2020]ez三剑客-easynode ②[MoeCTF 2021]fake game ③[安洵杯 2020]Validator ④ [HZNUCTF 2023 final]eznode ⑤[CNSS] &#x1f3ed; EzPollution_pre ⑥[CNSS]✴️ EzPollution ①[GKCTF 2020]ez三剑客-easynode const express require(express); co…

基于STC12C5A60S2系列1T 8051单片机的液晶显示器LCD1602显示用户自定义字符应用

基于基于STC12C5A60S2系列1T 8051单片机的液晶显示器LCD1602显示两行常规字符应用 STC12C5A60S2系列1T 8051单片机管脚图STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式及配置STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式介绍液晶显示器LCD1602简单介绍通过液晶显…

从零开始的c语言日记day36——指针进阶

一、什么是指针: 指针的概念:1.指针就是个变量&#xff0c;用来存放地址&#xff0c;地址唯一标识一块内存空间。 ⒉指针的大小是固定的4/8个字节(32位平台/64位平台)。 指针是有类型&#xff0c;指针的类型决定了指针的-整数的步长&#xff0c;指针解引用操作的时候的权限。…

opencv-直方图均衡化

直方图均衡化是一种用于增强图像对比度的图像处理技术。它通过调整图像的灰度级别分布&#xff0c;使得图像中各个灰度级别的像素分布更均匀&#xff0c;从而提高图像的对比度。 在OpenCV中&#xff0c;你可以使用cv2.equalizeHist()函数来进行直方图均衡化。 以下是一个简单…

Altium Designer 相同模块的布局布线复用-AD

1、利用交互式布线&#xff0c;将两个相同模块的元器件在PCB上分块显示。 在原理图中&#xff0c;框选某一模块电路、按快捷键 TS 切换到PCB编辑界面、工具>器件摆放>在矩形区域内排列&#xff08;可将模块中的器件都集中放置到矩形框内&#xff09;。2、为模块电路添加 …

缓存雪崩、击穿、穿透_解决方案

文章目录 缓存雪崩、击穿、穿透1.缓存雪崩造成缓存雪崩解决缓存雪崩 2. 缓存击穿造成缓存击穿解决缓存击穿 3.缓存穿透造成缓存穿透解决缓存穿透 缓存雪崩、击穿、穿透 一般用户数据存储于磁盘&#xff0c;读写速度慢。 使用redis作为缓存&#xff0c;相当于数据缓存在内存&a…

笔记59:序列到序列学习Seq2seq

本地笔记地址&#xff1a;D:\work_file\&#xff08;4&#xff09;DeepLearning_Learning\03_个人笔记\3.循环神经网络\第9章&#xff1a;动手学深度学习~现代循环神经网络 a a a a a a a a a a a a a a a

HTML实现简易计算器

随便写的&#xff0c;可能有bug&#xff0c;可以在评论区指出哈。 HTML代码&#xff1a; <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>AI简易计算器</title> </head> <body> <table id"c…

JMeter集结点的使用场景以及如何使用?

JMeter是一个开源的负载测试工具&#xff0c;它被广泛用于测试应用程序、Web服务和网络协议等的性能。在JMeter中&#xff0c;集结点&#xff08;JMeter Cluster&#xff09;是一种分布式测试环境&#xff0c;它允许多个JMeter实例同时工作来模拟高并发负载。 使用集结点的场景…

jQuery的学习(一篇文章齐全)

目录 Day29 jQuery 1、jQuery介绍 2、jQuery的选择器 2.1、直接查找 2.2、导航查找 3、jQuery的绑定事件 案例1&#xff1a;绑定取消事件 案例2&#xff1a;模拟事件触发 4、jQuery的操作标签 tab切换案例jQuery版本&#xff1a; 案例1&#xff1a; 案例2&#xff…

virtualbox 扩展磁盘后在win10 虚拟机看不到新扩展的空间

造成标题中问题的原因是&#xff0c;扩展的是win10.vdi 的空间&#xff0c;虚拟机使用使用的下边那个以uuid命名的空间&#xff0c;将这个磁盘的虚拟分配空间也调整到150G . 然后在win10的磁盘管理里就可以看到新加的空间了。之后再点相应的盘进行扩展卷操作即可。

“云浮云福保”暖心回归! 保障升级价格不变,医保个账可为全家缴费!

11月22日&#xff0c;2024年“云浮云福保”项目启动会在广东省云浮市迎宾馆成功举办。记者在会上获悉&#xff0c;“云浮云福保”是在云浮市医疗保障局、云浮市金融工作局、国家金融监督管理总局云浮监管分局指导下&#xff0c;的指导下&#xff0c;由中国人民财产保险股份有限…

12-25v转3.3v高清水下钓鱼摄像头电源供电芯片方案

高清水下钓鱼摄像头电源芯片方案&#xff1a;12-25V转3.3V&#xff0c;支持超宽电压输入范围和30米长线视频放大 在水下钓鱼摄像头设计中&#xff0c;为了实现高清画质和稳定的电源供应&#xff0c;需要一款能够将12-25V转换为3.3V输出的高效电源芯片。这款电源芯片不仅支持高…