Pytest系列(16)- 分布式测试插件之pytest-xdist的详细使用
前言
- 平常我们功能测试用例非常多时,比如有1千条用例,假设每个用例执行需要1分钟,如果单个测试人员执行需要1000分钟才能跑完
- 当项目非常紧急时,会需要协调多个测试资源来把任务分成两部分,于是执行时间缩短一半,如果有10个小伙伴,那么执行时间就会变成十分之一,大大节省了测试时间
- 为了节省项目测试时间,10个测试同时并行测试,这就是一种分布式场景
- 同样道理,当我们自动化测试用例非常多的时候, 一条条按顺序执行会非常慢,pytest-xdist的出现就是为了让自动化测试用例可以分布式执行,从而节省自动化测试时间
- pytest-xdist是属于进程级别的并发
分布式执行用例的设计原则(重中之重的重点)
- 用例之间是独立的,用例之间没有依赖关系,用例可以完全独立运行【独立运行】
- 用例执行没有顺序,随机顺序都能正常执行【随机执行】
- 每个用例都能重复运行,运行结果不会影响其他用例【不影响其他用例】
插件安装
pip3 install pytest-xdist -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com
pytest-xdist通过一些独特的测试执行模式扩展了pytest
- 测试运行并行化:如果有多个CPU或主机,则可以将它们用于组合的测试运行。 这样可以加快开发速度或使用远程计算机的特殊资源。
- --looponfail:在子进程中重复运行测试。 每次运行之后,pytest都会等到项目中的文件更改后再运行之前失败的测试。 重复此过程,直到所有测试通过,然后再次执行完整运行。
- 跨平台覆盖:您可以指定不同的Python解释程序或不同的平台,并在所有这些平台上并行运行测试。
快速入门
这是运行代码的包结构
14xdist是项目文件夹名称 │ conftest.py │ test_1.py │ __init__.py │ ├─test_51job │ │ conftest.py │ │ test_case1.py │ │ __init__.py │ ├─test_toutiao │ │ test_case2.py │ ├─test_weibo │ │ conftest.py │ │ test_case3.py │ │ __init__.py │
具体代码
最外层的conftest.py
# 外层conftest.py@pytest.fixture(scope="session")
def login():print("====登录功能,返回账号,token===")name = "testyy"token = "npoi213bn4"yield name, tokenprint("====退出登录!!!====")
最外层的test_1.py
import pytest@pytest.mark.parametrize("n", list(range(5)))
def test_get_info(login, n):sleep(1)name, token = loginprint("***基础用例:获取用户个人信息***", n)print(f"用户名:{name}, token:{token}")
test_51job包下的conftest.py
import pytest@pytest.fixture(scope="module")
def open_51(login):name, token = loginprint(f"###用户 {name} 打开51job网站###")
test_51job包下的test_case1.py
from time import sleepimport pytest@pytest.mark.parametrize("n", list(range(5)))
def test_case2_01(open_51, n):sleep(1)print("51job,列出所有职位用例", n)@pytest.mark.parametrize("n", list(range(5)))
def test_case2_02(open_51, n):sleep(1)print("51job,找出所有python岗位", n)
test_toutiao包下的test_case2.py
from time import sleepimport pytest@pytest.mark.parametrize("n", list(range(5)))
def test_no_fixture(login, n):sleep(1)print("==没有__init__测试用例,我进入头条了==", login)
test_weibo包下的conftest.py
import pytest@pytest.fixture(scope="function")
def open_weibo(login):name, token = loginprint(f"&&& 用户 {name} 返回微博首页 &&&")
test_weibo包下的test_case3.py
from time import sleepimport pytest@pytest.mark.parametrize("n", list(range(5)))
class TestWeibo:def test_case1_01(self, open_weibo, n):sleep(1)print("查看微博热搜", n)def test_case1_02(self, open_weibo, n):sleep(1)print("查看微博范冰冰", n)
不使用分布式测试的命令和所需执行时间
pytest -s
![]()
可以看到,执行一条用例大概1s(因为每个用例都加了 sleep(1) ),一共30条用例,总共运行30s;那么如果有1000条用例,执行时间就真的是1000s
使用分布式测试的命令和所需执行时间
pytest -s -n auto

知识点
- 可以看到,最终运行时间只需要6s,我的电脑是真6核,假12核
- -n auto:可以自动检测到系统的CPU核数;从测试结果来看,检测到的是逻辑处理器的数量,即假12核
- 使用auto等于利用了所有CPU来跑用例,此时CPU占用率会特别高
可以指定需要多少个CPU来跑用例
pytest -s -n 2

pytest-xdist是可以和pytest-html很好的相结合
pytest -s -n auto --html=report.html --self-contained-html
pytest-xdist按照一定的顺序执行
pytest-xdist默认是无序执行的,可以通过 --dist 参数来控制顺序
--dist=loadscope
- 将按照同一个模块module下的函数和同一个测试类class下的方法来分组,然后将每个测试组发给可以执行的worker,确保同一个组的测试用例在同一个进程中执行
- 目前无法自定义分组,按类class分组优先于按模块module分组
--dist=loadfile
按照同一个文件名来分组,然后将每个测试组发给可以执行的worker,确保同一个组的测试用例在同一个进程中执行
如何让scope=session的fixture在test session中仅仅执行一次
pytest-xdist是让每个worker进程执行属于自己的测试用例集下的所有测试用例
这意味着在不同进程中,不同的测试用例可能会调用同一个scope范围级别较高(例如session)的fixture,该fixture则会被执行多次,这不符合scope=session的预期
如何解决?
虽然pytest-xdist没有内置的支持来确保会话范围的夹具仅执行一次,但是可以通过使用锁定文件进行进程间通信来实现。
小栗子
- 下面的示例只需要执行一次login(因为它是只需要执行一次来定义配置选项,等等)
- 当第一次请求这个fixture时,则会利用FileLock仅产生一次fixture数据
- 当其他进程再次请求这个fixture时,则会从文件中读取数据
import pytest
from filelock import FileLock@pytest.fixture(scope="session")
def login():print("====登录功能,返回账号,token===")with FileLock("session.lock"):name = "testyy"token = "npoi213bn4"# web ui自动化# 声明一个driver,再返回# 接口自动化# 发起一个登录请求,将token返回都可以这样写yield name, tokenprint("====退出登录!!!====")
这可能是B站最详细的pytest自动化测试框架教程,整整100小时,全程实战!!!
相关文章:
Pytest系列(16)- 分布式测试插件之pytest-xdist的详细使用
前言 平常我们功能测试用例非常多时,比如有1千条用例,假设每个用例执行需要1分钟,如果单个测试人员执行需要1000分钟才能跑完当项目非常紧急时,会需要协调多个测试资源来把任务分成两部分,于是执行时间缩短一半&#…...
基于JavaWeb的网上销售系统设计与实现
项目描述 临近学期结束,还是毕业设计,你还在做java程序网络编程,期末作业,老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。这里根据疫情当下,你想解决的问…...
wpf添加Halcon的窗口控件报错:下列控件已成功添加到工具箱中,但未在活动设计器中启用
报错截图如下: 注意一下新建工程的时候选择wpf应用而不是wpf应用程序。 添加成功的控件:...
antv/x6 自定义html节点并且支持动态更新节点内容
antv/x6 自定义html节点 效果图定义一个连接桩公共方法注册图形节点创建html节点动态更新节点内容 效果图 定义一个连接桩公共方法 const ports {groups: {top: {position: top,attrs: {circle: {r: 4,magnet: true,stroke: #cf1322,strokeWidth: 1,fill: #fff,style: {visib…...
设计模式之命令模式
阅读建议 嗨,伙计!刷到这篇文章咱们就是有缘人,在阅读这篇文章前我有一些建议: 本篇文章大概4000多字,阅读时间长可能需要4-5分钟,请结合示例耐心读完,绝对有收获。设计模式属于程序的设计思…...
Linux学习笔记--高级
Shell概述 1,shell概述 是一个c语言编写的脚本语言,是linux和用户的桥梁,用户输入命令交给shell处理。shell,将相应的操作传递给内核(kernel),内核把处理的结果输出给用户 1.1Shell解释器有哪…...
在Java中操作Redis
Redis中如何的去存放一个Java对象? 直接存放Json类型即可,因为我们Json类型最终就是一个String类型。 Redis的Java客户端 Redis的常用命令是我们操作Redis的基础,那么我们在Java程序当中如何来操作Redis呢? 要想基于Java语言…...
【服务器】fiber协程模块
fiber协程模块 以下是从sylar服务器中学的,对其的复习; sylar的fiber协程模块是基于ucontext_t实现非对称协程 函数只有两个行为:调用与返回。一旦函数返回后,它在栈上所拥有的状态将被销毁。协程相比函数多了两个动作…...
SparkML
SparkML SparkML_lr_train :读取py处理后的train表用于训练,将训练模型保存好。 SparkML_lr_predict :读取训练好的模型,读取py处理后的test表用于预测。将预测结果写入normal_data中,根据id修改stream_is_normal的值。…...
实时定位与路径优化:跑腿App系统开发中的地理信息技术
本文将介绍如何使用地理信息技术实现实时定位和路径优化功能,以提高跑腿服务的效率。 实时定位 用户位置获取 # 示例:获取用户的实时位置 def get_user_location(user_id):# 使用GPS或网络定位技术获取用户的地理坐标# 返回经度和纬度信息return lon…...
Tomcat的HTTP Connector
https://tomcat.apache.org/tomcat-10.1-doc/config/http.html 一个Connector代表一个接收请求、返回响应的端点(endpoint)。 HTTP Connector 元素代表一个支持HTTP/1.1的Connector组件。一个这样的组件在服务端一个指定的TCP端口上监听连接。一个Serv…...
将Pytorch搭建的ViT模型转为onnx模型
本文尝试将pytorch搭建的ViT模型转为onnx模型。 首先将博主上一篇文章中搭建的模型ViT Vision Transformer超详细解析,网络构建,可视化,数据预处理,全流程实例教程-CSDN博客转存为.pth torch.save(model, my_vit_model.pth) 然…...
图神经网络(GNN)性能优化方案汇总,附37个配套算法模型和代码
图神经网络的表达能力对其性能和应用范围有着重要的影响,是GNN研究的核心问题和发展方向。增强表达能力是扩展GNN应用范围、提高性能的关键所在。 目前GNN的表达能力受特征表示和拓扑结构这两个因素的影响,其中GNN在学习和保持图拓扑方面的缺陷是限制表…...
国科大移动互联网考试资料(2023+2020+2018真题+答案)
老师王文杰。真题附加2022部分...
ModStart系统安全规范建议
1 不要使用弱密码 很多人为了系统管理方便(或者是懒),经常会设置类似 123456、admin 这样的管理密码,这样的密码很容易被暴力软件扫描出来。 2 不要使用默认配置 默认的软件系统设置、默认的系统端口、默认的网站设置在发生漏洞…...
【漏洞复现】Django_debug page_XSS漏洞(CVE-2017-12794)
感谢互联网提供分享知识与智慧,在法治的社会里,请遵守有关法律法规 文章目录 1.1、漏洞描述1.2、漏洞等级1.3、影响版本1.4、漏洞复现1、基础环境2、漏洞分析3、漏洞验证 说明内容漏洞编号CVE-2017-12794漏洞名称Django_debug page_XSS漏洞漏洞评级影响范…...
Redis性能调优:深度剖析与示例解析
标题:Redis性能调优:深度剖析与示例解析 引言 Redis是一款强大的开源内存数据库,广泛应用于高性能系统。然而,为了充分发挥Redis的性能,需要进行合理的性能调优。本博客将深入介绍Redis性能调优的策略和示例…...
oracle查询前几条数据的方法
在Oralce中实现select top N:由于Oracle不支持select top 语句,所以在oracle中经常是用order by 跟rownum的组合来实现select top n的查询。 方法1: SELECT * FROM (SELECT * FROM EMP ORDER BY SAL DESC) WHERE ROWNUM < 5 --抽取处记录…...
c#弹性和瞬态故障处理库Polly
1. 重试(Retry) Policy .Handle<Exception>() //指定需要重试的异常类型 .Retry(2,(ex,count,context)> { //指定发生异常重试的次数Console.WriteLine($ "重试次数{count},异常{ex.Message}" ); }) …...
20231107-前端学习炫酷菜单效果和折叠侧边栏
炫酷菜单效果 代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>炫酷菜单效果</title><…...
通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...
从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路
进入2025年以来,尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断,但全球市场热度依然高涨,入局者持续增加。 以国内市场为例,天眼查专业版数据显示,截至5月底,我国现存在业、存续状态的机器人相关企…...
【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习
禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...
Android第十三次面试总结(四大 组件基础)
Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成,用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机: onCreate() 调用时机:Activity 首次创建时调用。…...
Mysql8 忘记密码重置,以及问题解决
1.使用免密登录 找到配置MySQL文件,我的文件路径是/etc/mysql/my.cnf,有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...
WPF八大法则:告别模态窗口卡顿
⚙️ 核心问题:阻塞式模态窗口的缺陷 原始代码中ShowDialog()会阻塞UI线程,导致后续逻辑无法执行: var result modalWindow.ShowDialog(); // 线程阻塞 ProcessResult(result); // 必须等待窗口关闭根本问题:…...
抽象类和接口(全)
一、抽象类 1.概念:如果⼀个类中没有包含⾜够的信息来描绘⼀个具体的对象,这样的类就是抽象类。 像是没有实际⼯作的⽅法,我们可以把它设计成⼀个抽象⽅法,包含抽象⽅法的类我们称为抽象类。 2.语法 在Java中,⼀个类如果被 abs…...
6.9-QT模拟计算器
源码: 头文件: widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QMouseEvent>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECTpublic:Widget(QWidget *parent nullptr);…...
文件上传漏洞防御全攻略
要全面防范文件上传漏洞,需构建多层防御体系,结合技术验证、存储隔离与权限控制: 🔒 一、基础防护层 前端校验(仅辅助) 通过JavaScript限制文件后缀名(白名单)和大小,提…...
用神经网络读懂你的“心情”:揭秘情绪识别系统背后的AI魔法
用神经网络读懂你的“心情”:揭秘情绪识别系统背后的AI魔法 大家好,我是Echo_Wish。最近刷短视频、看直播,有没有发现,越来越多的应用都开始“懂你”了——它们能感知你的情绪,推荐更合适的内容,甚至帮客服识别用户情绪,提升服务体验。这背后,神经网络在悄悄发力,撑起…...
