分析:如何多线程运行测试用例

news2024/12/22 11:55:00

这是时常被问到的问题,尤其是UI自动化的运行,过程非常耗时,所以,所以多线程不失为一种首先想到的解决方案。

多线程是针对的测试用例,所以和selenium没有直接关系,我们要关心的是单元测试框架。

unittest

首先,应该说明的是unittest本身是不支持多线程的。当然,如果你学过Python的threading模块,也未必不行。不过我在stackoverflow 找了半天,大多是介绍unittest 测试多线程模块,并非是unittest本身如何多线程运行用例。

“我如何学习葵花宝典” 和 “我如何验证 张三 学会了葵花宝典”是两回事,而我显然要解决的问题是前者。

又重新百度,结果就找了答案。核心借助 tomorrow3 的测试库,再配合HTMLTestRunner 生成测试报告。

GitHub - SeldomQA/XTestRunner: Modern style test report based on unittest framework.
GitHub - dflupu/tomorrow3: An implementation of the tomorrow package for python >= 3.0

  • 测试用例

测试用例如下,你可以复制多份测试。

# test_a.py
import time
import unittest
from selenium import webdriver


class Test1(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        cls.driver = webdriver.Chrome()

    def test_01(self):
        self.driver.get("https://www.bing.com/?mkt=zh-CN")
        elem = self.driver.find_element_by_id("sb_form_q")
        elem.send_keys("多线程")
        elem.submit()
        time.sleep(2)
        self.assertIn("多线程", self.driver.title)

    @classmethod
    def tearDownClass(cls):
        cls.driver.quit()


if __name__ == "__main__":
    unittest.main()
  • 运行文件

核心在tomorrow3提供的threads装饰器,用于装饰测试运行方法。

import unittest
import os
from TestRunner import HTMLTestRunner
from tomorrow3 import threads

# 定义目录
BASE_DIR = os.path.dirname(os.path.realpath(__file__))
TEST_DIR = os.path.join(BASE_DIR, "test_dir")
REPORT_DIR = os.path.join(BASE_DIR, "test_report")


def test_suits():
    """
    加载所有的测试用例
    """
    discover = unittest.defaultTestLoader.discover(
        TEST_DIR,
        pattern="test_*.py"
    )
    return discover


@threads(2)  # !!!核心!!!! 设置线程数
def run_case(all_case, nth=0):
    """
    执行所有的用例, 并把结果写入测试报告
    """
    report_abspath = os.path.join(REPORT_DIR, f"result{nth}.html")
    with open(report_abspath, "wb+") as file:
        runner = HTMLTestRunner(stream=file, title='多线程测试报告')
        # 调用test_suits函数返回值
        runner.run(all_case)


if __name__ == "__main__":
    cases = test_suits()
    # 循环启动线程
    for i, j in zip(cases, range(len(list(cases)))):
        run_case(i, nth=j)  # 执行用例,生成报告

总结:

确实可以(根据设置的线程数)同时开启两个浏览器运行,同时带来了两个问题。

  1. 程序会根据线程数,生成多份测试报告,每个测试报告统计当前线程所运行的测试结果。
  2. 如果去掉nth参数,设置为一个报告,那么第二个线程运行的结果不能正确展示的一张报告上。
  3. 至少每个线程中的用例要保证有浏览器的启动/关闭。

第3点,你可能不理解,我举个例子,小时候见过妈妈/奶奶缝衣服。假设一件衣服拿一根针来缝制,缝衣服最麻烦就是穿针引线,针眼很小,每次都要费半天功夫,小孩子眼神好,我时常被叫去穿针引线。那为了节约时间怎么办,我当然是把线弄的长长的,最好是一根针线可以缝制多件衣服。

在Selenium 中,定义的浏览器驱动driver,每一条用例都定义一次驱动,伴随而来的就每个用例都开启/关闭一次浏览器,这当然是非常耗时的,为了缩短这个时间,我们最好是启动一次浏览器把所有用例都跑完才关闭。

那么问题来了,当我们使用多线程之后,相当于多个人同时缝制衣服,共用一根针线肯定不行啊。至少需要每人一根针线吧!而且缝制衣服的人是变化的,为了赶时间就多两个人(多开两个线程),用例比较少就少几个人(少启两个线程),为了适应这种变化,那么最好一件衣配置一根针线,每件衣服是最小单位,一个人必须要独立的把一件衣服缝好。

为了使用多线程,我们就必须每条用例开启/关闭一次浏览器,这其实是另一种时间的浪费,为了弥补这里的浪费,你必须把线程开得足够多才行。

最后,你必须再配置一位统计员,去统计每个人缝制衣服的数量,合计到一个报告中。

pytest

多线程运行用例在 pytest 中就相对容易太多了,pytest-xdist 插件就可以完成这件事情。

GitHub - pytest-dev/pytest-xdist: pytest plugin for distributed testing and loop-on-failures testing modes.

  • 测试用例

测试用例如下,你可以复制多份测试。

# test_a.py
import time
from selenium import webdriver


def test_01():
    driver = webdriver.Chrome()
    driver.get("http://www.baidu.com")
    elem = driver.find_element_by_id("kw")
    elem.send_keys("unittest")
    elem.submit()
    time.sleep(2)
    assert driver.title == "unittest_百度搜索"
    driver.quit()


def test_02():
    driver = webdriver.Chrome()
    driver.get("http://www.baidu.com")
    elem = driver.find_element_by_id("kw")
    elem.send_keys("python")
    elem.submit()
    time.sleep(2)
    assert driver.title == "python_百度搜索"
    driver.quit()

  • 运行文件

核心就是安装 pytest-xdist 插件,通过-n参数设置线程数即可。

import os
import pytest

# 定义目录
BASE_DIR = os.path.dirname(os.path.realpath(__file__))
TEST_DIR = os.path.join(BASE_DIR, "test_dir")
REPORT_DIR = os.path.join(BASE_DIR, "test_report")


if __name__ == '__main__':
    report_file = os.path.join(REPORT_DIR, "result.html")
    pytest.main([
        "-n", "2",  # !!核心!!!设置2个线程
        "-v", "-s", TEST_DIR,
        "--html=" + report_file,
        ])

总结:

相对于unittest,在pytest实现多线程非常简单,最终线线程的测试结果也可以很好在一个测试报告中展示。

  1. 存在的问题,正如我上面讨论的,你必须为每个用例设置开启/关闭。除了额外消耗启动时间外,如果想统一配置用例通过哪个浏览器执行也会比较麻烦。
  2. 你的每一条用例应该保持绝对独立,不能出现这条用例依赖上条用例的执行结果。因为,这两条用例可能会分配由不同的线程执行。
  3. 正如上一条的原因,你不能控制用例的执行顺序。

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

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

相关文章

生态伙伴 | 华秋硬创联合湾加速,共同加速企业发展

01 大赛介绍 中国硬件创新创客大赛始于2015年,由深圳华秋电子有限公司主办,至今已经成功举办八届,赛事范围覆盖华南、华东、华北三大地区,超10个省市区域。 大赛影响了超过45万工程师群体,吸引了35000多名硬创先锋报…

云可观测性技术的应用领域及价值有哪些?

随着云计算的迅速发展,云可观测性技术成为了越来越重要的一项技术。它可以帮助企业实时监测、分析和优化其在云环境中运行的应用程序和系统,那云可观测性技术的应用领域及价值有哪些? 一、应用性能监测与优化 云可观测性技术使得企业能够实时…

(字符串) 844. 比较含退格的字符串——【Leetcode每日一题】

❓844. 比较含退格的字符串 难度:简单 给定 s 和 t 两个字符串,当它们分别被输入到空白的文本编辑器后,如果两者相等,返回 true 。# 代表退格字符。 注意:如果对空文本输入退格字符,文本继续为空。 示例…

【SpringBoot】整合Elasticsearch 快速入门操作索引

官网操作文档:Elasticsearch Clients | Elastic 踩坑太多了。。。这里表明一下Spring Boot2.4以上版本可能会出现问题,所以我降到了2.2.1.RELEASE。对于现在2023年6月而言,Es版本已经到了8.8,而SpringBoot版本已经到了3.x版…

【实战】Python爬虫之代理使用详解

在Python爬虫中,代理的使用非常常见。代理的主要作用是隐藏客户端的真实IP地址,从而实现更高的网络访问速度和更好的访问隐私保护。下面我们将通过Python爬虫的实例,带你详细了解Python爬虫中代理的使用方法。 目录 ## 1. 代理原理和作用 …

多维度员工信息整合查询——红海云员工信息数字化管理实用指南(中)

红海云员工全生命周期数字化管理平台从信息源头开始管控员工数据质量,在员工数据的采集、更新、审核环节采用多种方式保障员工信息的准确性、完整性、时效性和一致性,为企业搭建坚实可靠的人力资源管理数字化基座。但在有了准确可靠的员工数据基础后&…

APP测试应该从哪些方面入手?其实就这几点

前言 还在苦恼怎么去测APP吗? 一定要记住这几个方向,然后流程化的去执行,一来严谨规范,二来不会有遗漏。 1、需求检查: 在需求评审的时候展现你的业务能力啦!不过还是得口下留情哟。(PM心里瑟…

GitOps指南

GitOps基于CICD和IaC,以一致的方式管理代码和部署,是DevOps最佳实践之一。本文完整介绍了GitOps的理念和实践,并介绍了Weave Cloud的GitOps模型和工具,从整体上提供了实践GitOps的路径和方案。原文:Guide To GitOps[1]…

C++中的一些小技巧,numeric_limits、static_cast、reinterpret_cast方法内存验证

1、获取指定类型的最大值和最小值 在准备求一堆double数据中的最大值最小值的时候,常规做法是预估这堆数据的最大最小值,然后进行比较求,在重构别人代码的时候发现,可以准确知道double类型最大值或者最小值,获取方法如…

Apikit 自学日记:分享 API 文档

开启/关闭在线分享 您可以在线分享项目给团队以外的人,其他人可以通过分享链接在线查看API文档并且进行API测试。通过这种方式查看API文档不需要注册账号,用户可方便查看接口文档和测试接口。 在项目内,点击进入项目管理菜单,选择…

银河麒麟部署达梦8数据库开发者版本详细教程

我的系统信息如下: 系统架构:X86架构 系统信息:银河麒麟(V10) CPU:interl E5 官方安装文档:安装及卸载 | 达梦技术文档 (dameng.com) 数据库下载: 下载地址:产品下载…

【深度学习】2-5 神经网络-批处理

批处理(Batch Processing)是指在深度学习中每次迭代更新模型参数时同时处理多个样本的方式。 批处理时要注意对应维度的元素个数要一致 关于之前手写数字识别的例子: 用图表示,可以发现,多维数组的对应维度的元素个数…

体验DIY物联网浏览器(谷歌内核兼容性好支持H264视频播放)

一、功能及快捷键说明(说明32位兼容64位,版本往下看) 功能及快捷键图说明,不可多得的浏览器,支持右键自定义菜单... 二、下载安装包 2.1 版本 100.0.230 (支持H264版本)介绍 cefsharp物联网浏览器-支持H264(100.0.230)_cefsharp h264_久爱物联网的博客-CSDN博客 …

《论文阅读》用于情感分析的融合预训练表情符号特征增强

《论文阅读》用于情感分析的融合预训练表情符号特征增强 前言简介模型构架实验结果总结前言 你是否也对于理解论文存在困惑? 你是否也像我之前搜索论文解读,得到只是中文翻译的解读后感到失望? 小白如何从零读懂论文?和我一起来探索吧! 今天为大家带来的是《Fusion Pr…

SonarScanner扫描本地项目代码

一、Windows系统扫描 下载SonarScanner 去SonarQube官网下载相应系统的SonarScanner 点这里跳转 设置环境变量 下载好试个压缩文件,解压到你想存放的位置,设置环境变量 新增变量名:SONAR_SCANNER_HOME,值:你解压Sona…

ansible知识

在物理机查看环境,[kioskfoundation0 ~]$ cat /etc/rht 先清空当前环境,[kioskfoundation0 ~]$ rht-clearcourse 0 再切换rh294环境,[kioskfoundation0 ~]$ rht-setcourse rh294 验证环境是否切换成功,[kioskfoundation0 ~]$ cat…

2023年6月DAMA-CDGA/CDGP数据治理工程师认证找这家

DAMA认证为数据管理专业人士提供职业目标晋升规划,彰显了职业发展里程碑及发展阶梯定义,帮助数据管理从业人士获得企业数字化转型战略下的必备职业能力,促进开展工作实践应用及实际问题解决,形成企业所需的新数字经济下的核心职业…

清北「学渣」创业心路:AI 新时代已来,不参与对不起自己

内容一览:近日,HyperAI 超神经有幸接触到 SegmentFault AIGC Hackathon 2023 北京站二等奖获得者 OAISIS 团队,与他们畅聊了本次参赛的心路历程以及比赛之外团队的工作和生活。交谈中,三位年轻人显露出的自信、沉着、从容令人印象…

自动识别字幕

抖音官方出品的视频剪辑工具,国内版本和网易见外工作台一样,智能生成字幕功能只能识别中文和英文两种语言。 但是剪映国际版就支持英语、日语、韩语、葡萄牙语、俄语、印度尼西亚语、西班牙语还有德语总共八种语言。 剪映国际版字幕小助手 地址&#x…

【Android开发基础】传感器(方向传感器、加速度传感器)

文章目录 一、引言二、设计1、指南针(方向传感器)(1)效果(2)UI设计(3)功能设计 2、摇一摇(加速度传感器)(1)效果(2&#x…