当前位置: 首页 > news >正文

pytest 并发执行用例(基于受限的测试资源)

概要

本文主要介绍了如何在测试资源(被测对象)受限的情况下,使用 pytest 进行并发测试以减少总体测试时间的方法和过程。

背景

在软件开发过程中,我们通常使用测试用例来持续保证软件的质量(例如,确保关键功能不被破坏,确保相关流程不会阻塞等)。从 CI/CD 的概念出发,要做到持续地保证软件质量,我们需要不间断地跑相关测试用例(例如,merge PR 之前、每日测试等),以保证软件持续处于高质量水平。

在这个过程中,随着总体代码量和功能的增加,我们的用例集也会不断膨胀。然而,当我们的测试集数量达到一个较大的数量时,跑一次完整的测试用例集会到达一个很恐怖的时间(例如,笔者所在的项目当前跑一遍完整测试用例的时间需要超过 3 天)。此时,将其嵌入流水线过程将变成一个不可接受的事情,利用其持续保证版本质量更是无从说起。

因此,在总体测试时间超过一个区间后,我们应当自然而然地会产生优化执行时间的想法,例如优化用例,减少大用例的执行时间等。我们这里主要介绍的是使用并发的方法减少总耗时——一般来说,这也是最立竿见影的方法。

在一般的软件测试项目中,被测应用程序(AUT, Application Under Test)一般不是测试的并发瓶颈。

例如,在 web 项目中,测试过程一般如下:

  1. 起一个 AUT(包括该 web 项目相关的数据库、后端等)
  2. 通过 http request、browser driver 等方式,访问 web 服务对应的端口并进行测试
  3. 所有测试完成后,关闭 AUT

注意到,在这个过程中,AUT 本身是支持并发的(毕竟你可不想你的网站只有一个用户可以访问),且其运行环境一般支持较高的并发访问需求。因此其进行整体测试的时间开销主要体现在固有开销上(例如,网络往返时间、io 时间、等待同步等),而不是受限于 AUT。

因此,如果你的开发场景如上,你可以肆无忌惮地并发进行测试——在搜索引擎上搜索 pytest-xdist 一般能让你很轻易地解决你的问题。然而,对于一些不幸的人,测试资源会比较受限,因此无法简单地使用通用方法解决问题。比如笔者就需要在这个场景下寻找一个解决方案。

笔者正在为一个测试框架做开发工作,其相关测试用例集主要遵循以下规则进行测试:

  1. 通过 netconf、ssh 或 http 等协议连接到待测设备(DUT, device under test)
  2. 通过不同协议的连接,对设备进行一系列表更并进行验证
  3. 测试完成后,继续测试下一个用例

在此场景中,DUT 是一台性能极其低下的网络设备(可以理解为路由器),修改其相关配置会限制影响流量的表现。因此,无论是从性能还是从功能上,该设备都不支持并发测试。

怎么办?加机器!既然一台机器无法支撑并发测试,那再加几台机器,将测试用例散列到各设备上不就行了?下面我们将进行进一步探索,总结出一个具体可行的方案。

解决方案

为了充分利用 pytest 生态,我们使用 pytest-xdist 实现并发功能,其相比于 pytest-parallel 对于 pytest-html allure-pytest 等周边生态的兼容性更好。已知 pytest-xdist 使用了多进程实现的并发操作,因此我们接下来的一切并发控制都基于多进程进行考虑(当然实际上也很容易切换到多线程生态)。

而实现在受限资源下进行测试的方法也很简单:我们只需要列出所有可用于测试的设备,然后在测试的时候自动选中基于哪台设备进行测试就好了。

其具体做法如下:

  1. 首先,我们将所有设备的信息写入到一个 json 文件中(或者数据库等任何你想要的地方都行)
  2. 然后,以并发的方式执行测试
  3. pytest.fixure 的方式为每个测试用例设置夹具,使其在运行前选中并锁定用例需要的设备
  4. 在选定的设备上执行用例内容
  5. 执行结束,释放设备锁以备下一个用例使用

当然,上面说的只是最理想的情况,实际工程应用中,还应考虑到更多问题:

  1. 如果存在不同型号的设备,有些设备可能缺失某种特性导致无法执行某些测试用例,应该如何正确选择设备?
  2. 如果一个测试用例需要同时连接到不同的机器上做验证(如交叉校验,双机备份等场景),应如何处理?
  3. 如果多个用例使用同一批资源,是否可能产生死锁问题?
    这些问题需要更加深入地理解当前项目的用例执行方式,并不能不加区分放到一起讨论,故我们在此不继续讨论。

资源

综上过程,笔者创建了一个简单的实现示例:focksor/notebook_demo__pytest_limited_concurrency。希望对你有帮助

http://www.dtcms.com/a/349931.html

相关文章:

  • imx6ull-驱动开发篇40——Linux RTC 驱动简介
  • 一道MySQL笔试题: 输出 100 以内质数
  • VIVO/OPPO手机,显示5G开关
  • 【SystemUI】锁屏来通知默认亮屏Wake模式
  • Mac 菜单栏多合一工具自荐:FancyTool
  • LeetCode算法日记 - Day 22: 提莫攻击、Z字形变换
  • 电影感人文街拍摆摊纪实摄影后期Lr调色教程,手机滤镜PS+Lightroom预设下载!
  • 从手术室到街头摄像头:多模态融合如何让AI“看得懂”万物?
  • 搭建ftp服务器(主动模式,被动模式)
  • Canvas 动态高度文本图片生成器
  • Linux 详谈Ext系列⽂件系统(一)
  • 嵌入式(ARM方向)面试常见问题及解答
  • 【ARM】MDK在debug模式下断点的类型
  • blazor 学习笔记--vscode debug
  • C++11(Linux/GCC)字节序工具
  • 2025年09月计算机二级Python选择题每日一练——第七期
  • 栈指针(Stack Pointer)是什么?
  • 设置密钥连接服务器
  • 【基础-单选】向服务器提交表单数据,以下哪种请求方式比较合适
  • Linux 离线安装lrzsz(rz、sz上传下载小插件)
  • 什么是高防服务器?如何进行防御?
  • UE5多人MOBA+GAS 54、用户登录和会话创建请求
  • 矩阵系统源代码开发,支持OEM贴牌
  • 深入解析ffmpeg.dll:电脑中的关键组件及其相关问题解决​
  • 【龙泽科技】汽车车身测量与校正仿真教学软件【赛欧+SHARK】
  • 8851定期复盘代码实现设计模式的于芬应用
  • 中国计算机学会(CCF)推荐学术会议-B(计算机图形学与多媒体):DCC 2026
  • 《信息检索与论文写作》实验报告一 EI数据库检索
  • Allegro约束管理器设置详细教程
  • JUC之volatile关键字