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

如何用多线程执行 unittest 测试用例实现方案

前言

使用python做过自动化测试的小伙伴,想必都知道unittest和pytest这两个单元测试框架,其中unittest是python的官方库,功能相对于pytest来要逊色不少,但是uniitest使用上手简单,也受到的很多的小伙伴喜爱。一直以来都有小伙伴在问我,pytest可以通过相关的插件来实现多线程执行测试用例,为什么unittest没有呢?unittest如何去实现多线程运行呢?那么今天就专门来给大家聊聊如何使用多线程去执行unittest!

一、unittest 测试用例的运行机制

在讲使用多线程去执行uniitest的测试用例之前,我们首先来分析一下,unittest中用例可以通过哪几种方式来执行。这个时候就得去看看unittest的源码了。

虽然 unittest 的底层代码是基于 C 语言实现的,源码中看不到详细的代码,但是我们可以发现 TestCase、TestSuite、TestRnner 三个类中都有 run 方法,而且 run 方法的作用的都是执行测试用例。

  • TestRunner 可以执行单条测试用例以及测试套件中所有的用例
  • TestSuite 是直接执行套件中所有的用例
  • Testcase 中的 run 方法是执行当前这条测试用例

其实不管是 TestRunner 还是 TestSuite 的 run 方法执行用例,最终还是调用了用例本身的 run 方法去执行的。用例执行的方法我们搞清楚了,那么接下来我们就可以采取相关的策略使用多线程来执行了。

二、多线程执行用例的实现思路

  • 思路一:创建多个测试套件,每个套件使用一个线程去执行报告
  • 优缺点:
  • 优点:同一个测试用例类中用例执行的先后顺序能够得到保障
  • 缺点:用例需要自己手动添加到套件,然后分配给各个线程,会出现用例数量分配不均,线程资源浪费,
  • 思路二:所有的用例收集到测试套件,使用多线程去执行套件的测试用例,
  • 优缺点:
  • 优点:多线程共享用例资源,能够充分利用多线程的资源
  • 缺点:用例执行的先后顺序不好控制

三、思路一:具体实现:

1、初步尝试


"""文件1:testcase.py"""import unittestclass TestRegister(unittest.TestCase):"""此处用例代码以省略"""class TestLogin(unittest.TestCase):"""此处用例代码以省略""""""文件2:run_case.py"""import unittest,threadingfrom case_test.test_case import TestLogin, TestRegister# 创建2个套件,每个套件使用一个线程去执行suite1 = unittest.defaultTestLoader.loadTestsFromTestCase(TestRegister)suite2 = unittest.defaultTestLoader.loadTestsFromTestCase(TestLogin)def work1():"""执行套件1"""unittest.TextTestRunner().run(suite1)def work2:"""执行套件2"""unittest.TextTestRunner().run(suite1)t1 = threading.Thread(target=work1)t2 = threading.Thread(target=work2)t1.start()t2.start()t1.join()t2.join()

运行上面的 run_case.py 就会发现两个线程可以同时执行测试用例,但是存在一个问题,用例执行完之后,每个线程得到的结果是独立的,无法整合到一起!于是进行了以下优化。

2、再次尝试:测试结果整合

前面我们在执行测试套件的时候,是通过 TestRunner 去执行的,TestRunner 的 run 方法的参数只能传入测试用例或者测试套件,而 unittest 中 TestSuite,和 TestCase 的 run 方法在调用的时候,可以接收一个叫做 TestResult 的对象。而用例执行的结果就是保存在这个 TestResult 对象中。我们如果要整个测试结果可以自己先创建一个 TestResult 对象,然后执行套件的时候传进入,最后两个套件执行得到的测试结果都会保存在这一个 TestResult 对象中。代码如下


# 创建一个结果保存对象res = unittest.TestResult()# 运行测试套件返回测试结果t1 = threading.Thread(target=suite1.run,kwargs={"result":res})t2 = threading.Thread(target=suite2.run, kwargs={"result": res})t1.start()t2.start()t1.join()t2.join()print(res)

运行上述代码,我们成功的使用多线程运行了测试用例,并且将测试用例执行的结果整合到了一起。

3、封装一个基于线程池来执行的函数

下面的代码封装用到了线程池的相关知识点,大家可以自行扩展


"""============================Author:测试师-万里Time:2020/5/26 10:00E-mail:123456789@qq.comCompany:五百万里信息技术有限公司============================"""import unittestfrom concurrent.futures.thread import ThreadPoolExecutorfrom test_case import TestLogin, TestRegisterdef run_test(suites, thread_count=1):"""多线程执行用例的方法:param suite: list -->包含多个套件的列表[TestSuite,TestSuite]:param thread_count: int ---->执行的线程数量,默认为1:return: TestResult--->测试结果"""res = unittest.TestResult()# 创建一个线程池,执行测试用例with ThreadPoolExecutor(max_workers=thread_count) as ts:for suite in suites:# 将套件的执行提交到线程池中ts.submit(suite .run, result=res)return resif __name__ == '__main__':# 创建两个套件suite1 = unittest.defaultTestLoader.loadTestsFromTestCase(TestRegister)suite2 = unittest.defaultTestLoader.loadTestsFromTestCase(TestLogin)# 将套件放到列表中suite = [suite1, suite2]# 给根据套件的数量,每个套件创建一个线程去执行res = run_test(suite=suite, thread_count=len(suite))# 打印测试结果print(res)

四、思路二、代码封装

思路一实现了之后,思路二再来实现就会非常简单了,封装的代码如下:


"""============================Author:测试师-万里Time:2020/5/26 10:00E-mail:123456789@qq.comCompany:五百万里信息技术有限公司============================"""import unittestfrom concurrent.futures.thread import ThreadPoolExecutorfrom case_test.test_case import TestLogin, TestRegisterdef run_test(suite, thread_count=1):"""多线程执行用例的方法:param suite: 测试套件:param thread_count: int ---->执行的线程数量,默认为1:return: TestResult--->测试结果"""res = unittest.TestResult()# 创建一个线程池,执行测试用例with ThreadPoolExecutor(max_workers=thread_count) as ts:for case in suite:# 将用例的执行任务提交到线程池中ts.submit(case.run, result=res)return resif __name__ == '__main__':# 创建两个套件suite1 = unittest.defaultTestLoader.loadTestsFromTestCase(TestRegister)# 给根据套件的数量,每个套件创建一个线程去执行res = run_test(suite=suite1, thread_count=3)# 打印测试结果print(res)

关于多线程执行 unittest 就给大家分享到这里!看到这里可能有些小伙伴会问,多线程执行如何生成测试报告呢?目前 unittest 生成测试报告使用的几个开源的库,比如 BeautifulReport,HTMLTestRunner 都不支持多线程。不过要想实现的话也不难,对这些模块运行用例的方法进行重写就可以实现。

关于多线程执行 unittest 就给大家分享到这里!看到这里可能有些小伙伴会问,多线程执行如何生成测试报告呢?

那么接下来就这大家介绍一下如何使用 unittestreport 多线程运行用例,并生产测试报告

五、unittestreport 多线程执行用例

使用 unittestreport 来多线程执行用例非常简单,只需要在执行用例时加一个参数 thread_count,指定执行的线程即可。案例如下:


from unittestreport import TestRunner# 加载套件suite = unittest.defaultTestLoader.discover(CASE_DIR)# 执行用例runner = TestRunner(suite,filename=conf.get('report', "filename"),report_dir=REPORT_DIR,title='测试报告',tester='万里',desc="万里执行测试生产的报告",templates=1)# 指定三个线程运行测试用例runner.run(thread_count=3)

关于 unittest 多线程执行测试用例 就给大家分享到这里了!喜欢的可以关注我哟,关注我每天给大家带来不同的惊喜。

最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!

相关文章:

如何用多线程执行 unittest 测试用例实现方案

前言 使用python做过自动化测试的小伙伴,想必都知道unittest和pytest这两个单元测试框架,其中unittest是python的官方库,功能相对于pytest来要逊色不少,但是uniitest使用上手简单,也受到的很多的小伙伴喜爱。一直以来都…...

Ascend310 EP模式下容器内进行推理测试

EP模式下容器内进行推理测试 本文的软硬件环境如下: 机器:x86台式机一台 OS: 5.4.0-26-generic Ubuntu20.04 LTS 推理卡:DLAP200-HP-2(凌华基于atlas200模块打造的两模块推理卡) 1. 推理卡固件和驱动安…...

(el-Transfer)操作(不使用 ts):Element-plus 中 Select 组件动态设置 options 值需求的解决过程

Ⅰ、Element-plus 提供的Select选择器组件与想要目标情况的对比&#xff1a; 1、Element-plus 提供Select组件情况&#xff1a; 其一、Element-ui 自提供的Select代码情况为(示例的代码)&#xff1a; // Element-plus 提供的组件代码: <template><div class"f…...

Java基础之Math与Array类与System

文章目录 一、Math.random&#xff08;&#xff09;二、Arrays.binarySearch()三、asList&#xff08;&#xff09;四、System tip&#xff1a;以下是正文部分 一、Math.random&#xff08;&#xff09; a < num < b int num (int)(Math.random() * (b - a 1)) a二、…...

警告:Hydration attribute mismatch on Note: this mismatch is check-only.(水合不匹配)

vue3Nuxt3运行代码是提示如下警告 [Vue warn]: Hydration attribute mismatch on <ul id​"sub_menu_5_$$_sub1-popup" class​"ant-menu ant-menu-sub ant-menu-inline" data-menu-list​"true" style​"display:​none;​">​…...

【机器学习】CART决策树算法的核心思想及其大数据时代银行贷款参考案例——机器认知外界的重要算法

目录 引言 概述 CART决策树的特点 核心思想 减少不确定性的指标 基尼系数&#xff08;Gini Index&#xff09; 分类错误率 熵 银行实例 背景 数据准备 模型构建 模型评估与优化 应用与结果 代码示例 ✈✈✈✈引言✈✈✈✈ CART算法既可以用于分类问题&#xff0…...

编程软件是由什么编程的

编程软件是由什么编程的 在数字化的世界里&#xff0c;编程软件作为构建数字生态的基石&#xff0c;其背后所蕴含的奥秘往往令人感到困惑。那么&#xff0c;这些编程软件究竟是由什么编程的呢&#xff1f;这背后隐藏着怎样的逻辑与技术&#xff1f;接下来&#xff0c;我们将从…...

如何查看自己本地ip

1.winR 2.cmd 3.ipconfig...

高考分数限制下,选好专业还是选好学校?

高考分数限制下&#xff0c;选好专业还是选好学校&#xff1f; 高考作为每年一度的盛大考试&#xff0c;不仅关乎学生们的未来&#xff0c;更承载了家庭的期望。2004年高考刚刚结束&#xff0c;许多考生和家长已经开始为填报志愿而焦虑。选好学校和专业&#xff0c;直接关系到…...

Django学习(2)项目实战

1、环境及简介 前端开发&#xff1a;HTML、CSS、JavaScript 后端开发&#xff1a;Java、PHP、Python、GO 数据库&#xff1a;MySQL、MSSQL、Oracle、Redis 安装Django pip install Django 或 下载.whl后 pip install D&#xff1a;\xxx.whl 创建Django项目 File--New Projec…...

pdf格式转成jpg图片,pdf格式如何转jpg

pdf转图片的方法&#xff0c;对于许多人来说可能是一个稍显陌生的操作。然而&#xff0c;在日常生活和工作中&#xff0c;我们有时确实需要将pdf文件转换为图片格式&#xff0c;以便于在特定的场合或平台上进行分享、展示或编辑。以下&#xff0c;我们将详细介绍一个pdf转成图片…...

Java的三个接口Comparable,Comparator,Cloneable(浅拷贝与深拷贝)

Comparable 当我们要进行对象的比较的时候&#xff0c;我们是不能直接用>、< 这些符号直接进行比较的。 由于这是引用类型变量也是自定义类型变量&#xff0c;直接进行比较的时候&#xff0c;我们是通过对象的地址进行比较的&#xff0c;我们可以使用、! 进行两个对象的…...

pytorch学习笔记7

getitem在进行索引取值的时候自动调用,也是一个魔法方法,就像列表索引取值那样,一个意思 import torchvision from torch.utils.data import DataLoaderdata_transformtorchvision.transforms.Compose([torchvision.transforms.ToTensor()] ) test_datatorchvision.datasets.C…...

LeetCode热题3.无重复的最长字串

前言: 经过前序的一系列数据结构和算法学习后&#xff0c;开始用leetCode热题练练手。 . - 力扣&#xff08;LeetCode&#xff09; 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的最长子串的长度。 示例 1: 输入: s "abcabcbb" 输出: 3 解释: 因为…...

Python武器库开发-武器库篇之SQL注入扫描器(五十九)

Python武器库开发-武器库篇之SQL注入扫描器(五十九) SQL注入漏洞简介以及危害 SQL注入漏洞是一种常见的Web应用程序漏洞&#xff0c;攻击者可以利用该漏洞在应用程序的数据库中执行恶意的SQL查询或指令。这可能导致数据泄露、数据损坏、应用程序崩溃或未经授权的访问。 SQL注…...

图说设计模式:单例模式

更多C学习笔记&#xff0c;关注 wx公众号&#xff1a;cpp读书笔记 5. 单例模式 单例模式 模式动机模式定义模式结构时序图代码分析模式分析实例优点缺点适用环境模式应用模式扩展总结 5.1. 模式动机 对于系统中的某些类来说&#xff0c;只有一个实例很重要&#xff0c;例如…...

探索设计模式——单例模式详解

前言&#xff1a;设计模式的作用主要是为了——利用设计方式的重用来自动地提高代码的重新利用、提高代码的灵活性、节省时间&#xff0c; 提高开发效率、低耦合&#xff0c;封装特性显著&#xff0c; 接口预留有利于扩展。 设计模式的种类有很多种&#xff0c;本篇内容主要讲解…...

建筑垃圾/城市固废倾倒转移乱象:EasyCVR+AI智能视频监控方案助力城市环保监管

近日有新闻记者报道&#xff0c;中央生态环境保护督察组在上海、浙江、江西、湖北、湖南、重庆、云南7省市督察发现&#xff0c;一些地方建筑垃圾处置工作存在明显短板&#xff0c;乱堆乱倒问题时有发生&#xff0c;比如&#xff0c;江西湘东区在杨家田地块违规设置弃土场&…...

C的I/O操作

目录 引言 一、文件与目录操作 1. 打开与关闭文件 2. 文件读写操作 3. 文件定位与错误处理 二、字符流与字节流 1. 字符流处理 2. 字节流处理 三、序列化与反序列化 1. 序列化 2. 反序列化 四、新的I/O&#xff08;NIO&#xff09; 表格总结 文件与目录操作 字符…...

Android Audio实战——声道信息回调(五)

在前面的 AudioTrack 构造中,我们传入了音频的声道信息,这一节我们就来详细介绍一下声道的配置信息。 一、声道介绍 音频中的声道配置从单声道到双声道(立体声)、再到多声道系统(如5.1和7.1),代表了声音录制和回放技术的发展,旨在提供越来越丰富和沉浸式的听觉体验。 …...

K8S认证|CKS题库+答案| 11. AppArmor

目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作&#xff1a; 1&#xff09;、切换集群 2&#xff09;、切换节点 3&#xff09;、切换到 apparmor 的目录 4&#xff09;、执行 apparmor 策略模块 5&#xff09;、修改 pod 文件 6&#xff09;、…...

Zustand 状态管理库:极简而强大的解决方案

Zustand 是一个轻量级、快速和可扩展的状态管理库&#xff0c;特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

ServerTrust 并非唯一

NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)

🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...

大学生职业发展与就业创业指导教学评价

这里是引用 作为软工2203/2204班的学生&#xff0c;我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要&#xff0c;而您认真负责的教学态度&#xff0c;让课程的每一部分都充满了实用价值。 尤其让我…...

C++八股 —— 单例模式

文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全&#xff08;Thread Safety&#xff09; 线程安全是指在多线程环境下&#xff0c;某个函数、类或代码片段能够被多个线程同时调用时&#xff0c;仍能保证数据的一致性和逻辑的正确性&#xf…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

USB Over IP专用硬件的5个特点

USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中&#xff0c;从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备&#xff08;如专用硬件设备&#xff09;&#xff0c;从而消除了直接物理连接的需要。USB over IP的…...

浪潮交换机配置track检测实现高速公路收费网络主备切换NQA

浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求&#xff0c;本次涉及的主要是收费汇聚交换机的配置&#xff0c;浪潮网络设备在高速项目很少&#xff0c;通…...

LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》

这段 Python 代码是一个完整的 知识库数据库操作模块&#xff0c;用于对本地知识库系统中的知识库进行增删改查&#xff08;CRUD&#xff09;操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 &#x1f4d8; 一、整体功能概述 该模块…...