干货 | 一文搞定 pytest 自动化测试框架(二)

简介: 干货 | 一文搞定 pytest 自动化测试框架(二)

1080×501 27.2 KB


在上一篇文章中分享了 pytest 的基本用法,本文进一步介绍 pytest 的其他实用特性和进阶技巧。

pytest fixtures

pytest 中可以使用 @pytest.fixture 装饰器来装饰一个方法,被装饰方法的方法名可以作为一个参数传入到测试方法中。可以使用这种方式来完成测试之前的初始化,也可以返回数据给测试函数。

通常使用 setup 和 teardown 来进行资源的初始化。如果有这样一个场景,测试用例 1 需要依赖登录功能,测试用例 2 不需要登录功能,测试用例 3 需要登录功能。这种场景 setup,teardown 无法实现,可以使用 pytest fixture 功能,在方法前面加个 @pytest.fixture 装饰器,加了这个装饰器的方法可以以参数的形式传入到方法里面执行。

例如在登录的方法,加上 @pytest.fixture 这个装饰器后,将这个用例方法名以参数的形式传到方法里,这个方法就会先执行这个登录方法,再去执行自身的用例步骤,如果没有传入这个登录方法,就不执行登录操作,直接执行已有的步骤。

创建一个文件名为“test_fixture.py”,代码如下:

在上面的代码中,测试用例 test_case1 和 test_case3 分别增加了 login 方法名作为参数,pytest 会发现并调用 @pytest.fixture 标记的 login 功能,运行测试结果如下:

从上面的结果可以看出,test_case1 和 test_case3 运行之前执行了 login 方法,test_case2 没有执行这个方法。

fixture 里面有一个参数 scope,通过 scope 可以控制 fixture 的作用范围,根据作用范围大小划分:session> module> class> function,具体作用范围如下:

  • function 函数或者方法级别都会被调用
  • class 类级别调用一次
  • module 模块级别调用一次
  • session 是多个文件调用一次(可以跨.py文件调用,每个.py文件就是module)
    例如整个模块有多条测试用例,需要在全部用例执行之前打开浏览器,全部执行完之后去关闭浏览器,打开和关闭操作只执行一次,如果每次都重新执行打开操作,会非常占用系统资源。这种场景除了setup_module,teardown_module 可以实现,还可以通过设置模块级别的 fixture 装饰器(@pytest.fixture(scope=“module”))来实现。
    scope=‘module’
    fixture 参数 scope=‘module’,module 作用是整个模块都会生效。
    创建文件名为 test_fixture_scope.py,代码如下:
    代码解析:
    @pytest.fixture() 如果不写参数,参数默认 scope=‘function’。当 scope=‘module’ 时,在当前 .py 脚本里面所有的用例开始前只执行一次。scope 巧妙与 yield 组合使用,相当于 setup 和 teardown 方法。还可以使用 @pytest.mark.usefixtures 装饰器,传入前置函数名作为参数。
    运行结果如下:
    从上面运行结果可以看出,scope=“module” 与 yield 结合,相当于 setup_module 和 teardown_module 方法。整个模块运行之前调用了 open()方法中 yield 前面的打印输出“打开浏览器”,整个运行之后调用了 yield 后面的打印语句“执行 teardown !”与“关闭浏览器”。yield 来唤醒 teardown 的执行,如果用例出现异常,不影响 yield 后面的 teardown 执行。可以使用 @pytest.mark.usefixtures 装饰器来进行方法的传入。
    fixture scope 为 session 级别是可以跨 .py 模块调用的,也就是当我们有多个 .py 文件的用例时,如果多个用例只需调用一次 fixture,可以将 scope=‘session’,并且写到 conftest.py 文件里。写到 conftest.py 文件可以全局调用这里面的方法。使用的时候不需要导入 conftest.py 这个文件。使用 conftest.py 的规则:
    1.conftest.py 这个文件名是固定的,不可以更改。
    2.conftest.py 与运行用例在同一个包下,并且该包中有 init.py 文件
    3.使用的时候不需要导入 conftest.py,pytest 会自动识别到这个文件
    4.放到项目的根目录下可以全局调用,放到某个 package 下,就在这个 package 内有效。
    案例
    在运行整个项目下的所有的用例,只执行一次打开浏览器。执行完所有的用例之后再执行关闭浏览器,可以在这个项目下创建一个 conftest.py 文件,将打开浏览器操作的方法放在这个文件下,并添加一个装饰器 @pytest.fixture(scope=“session”),就能够实现整个项目所有测试用例的浏览器复用,案例目录结构如下:

    创建目录 test_scope,并在目录下创建三个文件 conftest.py,test_scope1.py 和 test_scope2.py。
    conftest.py 文件定义了公共方法,pytest 会自动读取 conftest.py 定义的方法,代码如下:
    创建 test_scope1.py 文件,代码如下:
    创建文件“test_scope2.py”,代码如下:
    打开 cmd,进入目录 test_scope/,执行如下命令:
    或者
    执行结果如下:
    执行过程中 pytest 会自动识别当前目录的 conftest.py,不需要导入直接引用里面的方法配置。应用到整个目录下的所有调用这里面的方法中执行。conftest.py 与运行的用例要在同一个 pakage 下,并且这个包下有 init.py 文件
    如果每条测试用例都需要添加 fixture 功能,则需要在每一要用例方法里面传入这个fixture的名字,这里就可以在装饰器里面添加一个参数 autouse=‘true’,它会自动应用到所有的测试方法中,只是这里没有办法返回值给测试用例。
    使用方法,在方法前面加上装饰器,如下:
    @pytest.fixture 里设置 autouse 参数值为 true(默认 false),每个测试函数都会自动调用这个前置函数。
    创建文件名为“test_autouse.py”,代码如下:
    执行上面这个测试文件,结果如下:
    从上面的运行结果可以看出,在方法 myfixture() 上面添加了装饰器 @pytest.fixture(autouse=“true”),测试用例无须传入这个 fixture 的名字,它会自动在每条用例之前执行这个 fixture。
    测试过程中需要大量的测试数据,如果每条测试数据都编写一条测试用例,用例数量将是非常宠大的。一般我们在测试过程中会将测试用到的数据以参数的形式传入到测试用例中,并为每条测试数据生成一个测试结果数据。
    这时候可以使用 fixture 的参数化功能,在 fixture 方法加上装饰器 @pytest.fixture(params=[1,2,3]),就会传入三个数据 1、2、3,分别将这三个数据传入到用例当中。这里可以传入的数据是个列表。传入的数据需要使用一个固定的参数名 request 来接收。
    创建文件名为“test_params.py”,代码如下:
    运行结果如下:
    从运行结果可以看出,对于 params 里面的每个值,fixture 都会去调用执行一次,使用 request.param 来接受用例参数化的数据,并且为每一个测试数据生成一个测试结果。在测试工作中使用这种参数化的方式,会减少大量的代码量,并且便于阅读与维护。
    假如项目中有测试用例 1000 条,一条测试用例需要执行 1 分钟,一个测试人员需要 1000 分钟才能完成一轮回归测试。通常我们会用人力成本换取时间成本,加几个人一起执行,时间就会缩短。如果 10 人一起执行只需要 100 分钟,这就是一种并行测试,分布式的场景。
    pytest-xdist 是 pytest 分布式执行插件,可以多个 CPU 或主机执行,这款插件允许用户将测试并发执行(进程级并发),插件是动态决定测试用例执行顺序的,为了保证各个测试能在各个独立线程里正确的执行,应该保证测试用例的独立性(这也符合测试用例设计的最佳实践)。
    安装
    多个 CPU 并行执行用例,需要在 pytest 后面添加 -n 参数,如果参数为 auto,会自动检测系统的 CPU 数目。如果参数为数字,则指定运行测试的处理器进程数。
    案例
    某个项目有 200 条测试用例,每条测试用例之间没有关联关系,互不影响。这 200 条测试用例需要在 1 小时之内测试完成,可以加个-n参数,使用多 CPU 并行测试。运行方法:
    进入到项目目录下,执行 pytest 可以将项目目录下所有测试用例识别出来并且运行,加上 -n 参数,可以指定 4 个 CPU 并发执行。大量的测试用例并发执行提速非常明显。
    测试报告通常在项目中尤为重要,报告可以体现测试人员的工作量,开发人员可以从测试报告中了解缺陷的情况,因此测试报告在测试过程中的地位至关重要,测试报告为纠正软件存在的质量问题提供依据,为软件验收和交付打下基础。测试报告根据内容的侧重点,可以分为 “版本测试报告” 和 “总结测试报告”。执行完 pytest 测试用例,可以使用 pytest-HTML 插件生成 HTML 格式的测试报告。
    安装
    执行方法
    结合 pytest-xdist 使用
    生成测试报告
    如下图:

    1080×522 93 KB

    生成的测试报告最终是 HTML 格式,报告内容包括标题、运行时间、环境、汇总结果以及用例的通过个数、跳过个数、失败个数、错误个数,期望失败个数、不期望通过个数、重新运行个数、以及错误的详细展示信息。报告会生成在运行脚本的同一路径,需要指定路径添加–html=path/to/html/report.html 这个参数配置报告的路径。如果不添加 --self-contained-html 这个参数,生成报告的 CSS 文件是独立的,分享的时候容易千万数据丢失。
    编写代码时,我们经常会做出一些假设,断言就是用于在代码中捕捉这些假设。断言表示为一些布尔表达式,测试人员通常会加一些断言来断定中间过程的正确性。断言支持显示最常见的子表达式的值,包括调用,属性,比较以及二元和一元运算符。Python使用 assert(断言)用于判断一个表达式,在表达式条件为 false 的时候触发异常。
    使用方法:
    案例如下:
    如果没有断言,没有办法判定用例中每一个测试步骤结果的正确性。在项目中适当的使用断言,来对代码的结构、属性、功能、安全性等场景检查与验证。
    以上,更多 Python 测试开发实战进阶技能,推荐学习《Python 测试开发实战进阶》课程。
    【相关阅读】
  • Python 测试开发实战进阶,挑战阿里P6+,年薪50W+!
  • 干货 | 一文搞定 pytest 自动化测试框架(一)
  • 测试面经 | 半年薪资翻倍逆袭大厂,这位“上错车”的测试媛不简单!
  • 干货 | 一文搞定 Linux 常用高频命令
  • 测试面经 | 从螺丝钉到大厂测试开发,三点学习心得与面试经验

原文链接

更多技术文章

相关文章
|
6天前
|
存储 Java 关系型数据库
“代码界的魔法师:揭秘Micronaut框架下如何用测试驱动开发将简单图书管理系统变成性能怪兽!
【9月更文挑战第6天】Micronaut框架凭借其轻量级和高性能特性,在Java应用开发中备受青睐。本文通过一个图书管理系统的案例,介绍了在Micronaut下从单元测试到集成测试的全流程。首先,我们使用`@MicronautTest`注解编写了一个简单的`BookService`单元测试,验证添加图书功能;接着,通过集成测试验证了`BookService`与数据库的交互。整个过程展示了Micronaut强大的依赖注入和测试支持,使测试编写变得更加高效和简单。
22 4
|
9天前
|
IDE 测试技术 持续交付
Python自动化测试与单元测试框架:提升代码质量与效率
【9月更文挑战第3天】随着软件行业的迅速发展,代码质量和开发效率变得至关重要。本文探讨了Python在自动化及单元测试中的应用,介绍了Selenium、Appium、pytest等自动化测试框架,以及Python标准库中的unittest单元测试框架。通过详细阐述各框架的特点与使用方法,本文旨在帮助开发者掌握编写高效测试用例的技巧,提升代码质量与开发效率。同时,文章还提出了制定测试计划、持续集成与测试等实践建议,助力项目成功。
34 5
|
11天前
|
测试技术 C# 图形学
掌握Unity调试与测试的终极指南:从内置调试工具到自动化测试框架,全方位保障游戏品质不踩坑,打造流畅游戏体验的必备技能大揭秘!
【9月更文挑战第1天】在开发游戏时,Unity 引擎让创意变为现实。但软件开发中难免遇到 Bug,若不解决,将严重影响用户体验。调试与测试成为确保游戏质量的最后一道防线。本文介绍如何利用 Unity 的调试工具高效排查问题,并通过 Profiler 分析性能瓶颈。此外,Unity Test Framework 支持自动化测试,提高开发效率。结合单元测试与集成测试,确保游戏逻辑正确无误。对于在线游戏,还需进行压力测试以验证服务器稳定性。总之,调试与测试贯穿游戏开发全流程,确保最终作品既好玩又稳定。
36 4
|
11天前
|
测试技术 C# 开发者
“代码守护者:详解WPF开发中的单元测试策略与实践——从选择测试框架到编写模拟对象,全方位保障你的应用程序质量”
【8月更文挑战第31天】单元测试是确保软件质量的关键实践,尤其在复杂的WPF应用中更为重要。通过为每个小模块编写独立测试用例,可以验证代码的功能正确性并在早期发现错误。本文将介绍如何在WPF项目中引入单元测试,并通过具体示例演示其实施过程。首先选择合适的测试框架如NUnit或xUnit.net,并利用Moq模拟框架隔离外部依赖。接着,通过一个简单的WPF应用程序示例,展示如何模拟`IUserRepository`接口并验证`MainViewModel`加载用户数据的正确性。这有助于确保代码质量和未来的重构与扩展。
21 0
|
11天前
|
测试技术 Java Spring
Spring 框架中的测试之道:揭秘单元测试与集成测试的双重保障,你的应用真的安全了吗?
【8月更文挑战第31天】本文以问答形式深入探讨了Spring框架中的测试策略,包括单元测试与集成测试的有效编写方法,及其对提升代码质量和可靠性的重要性。通过具体示例,展示了如何使用`@MockBean`、`@SpringBootTest`等注解来进行服务和控制器的测试,同时介绍了Spring Boot提供的测试工具,如`@DataJpaTest`,以简化数据库测试流程。合理运用这些测试策略和工具,将助力开发者构建更为稳健的软件系统。
21 0
|
11天前
|
API 开发者 Java
API 版本控制不再难!Spring 框架带你玩转多样化的版本管理策略,轻松应对升级挑战!
【8月更文挑战第31天】在开发RESTful服务时,为解决向后兼容性问题,常需进行API版本控制。本文以Spring框架为例,探讨四种版本控制策略:URL版本控制、请求头版本控制、查询参数版本控制及媒体类型版本控制,并提供示例代码。此外,还介绍了通过自定义注解与过滤器实现更灵活的版本控制方案,帮助开发者根据项目需求选择最适合的方法,确保API演化的管理和客户端使用的稳定与兼容。
44 0
|
11天前
|
测试技术 持续交付 开发者
Xamarin 高效移动应用测试最佳实践大揭秘,从框架选择到持续集成,让你的应用质量无敌!
【8月更文挑战第31天】竞争激烈的移动应用市场,Xamarin 作为一款优秀的跨平台开发工具,提供了包括单元测试、集成测试及 UI 测试在内的全面测试方案。借助 Xamarin.UITest 框架,开发者能便捷地用 C# 编写测试案例,如登录功能测试;通过 Xamarin 模拟框架,则可在无需真实设备的情况下模拟各种环境测试应用表现;Xamarin.TestCloud 则支持在真实设备上执行自动化测试,确保应用兼容性。结合持续集成与部署策略,进一步提升测试效率与应用质量。掌握 Xamarin 的测试最佳实践,对确保应用稳定性和优化用户体验至关重要。
24 0
|
5天前
|
运维 Ubuntu Devops
自动化运维工具的魅力:Ansible入门
【9月更文挑战第5天】在快速变化的IT世界里,自动化运维不再是可选项,而是必需品。Ansible,一款简单却强大的自动化工具,正成为众多DevOps工程师的首选。本文将带你了解Ansible的基本概念、安装步骤以及如何编写简单的Playbook,从而开启你的自动化之旅。
55 35
|
3天前
|
存储 弹性计算 运维
自动化监控和响应ECS系统事件
阿里云提供的ECS系统事件用于记录云资源信息,如实例启停、到期通知等。为实现自动化运维,如故障处理与动态调度,可使用云助手插件`ecs-tool-event`。该插件定时获取并转化ECS事件为日志存储,便于监控与响应,无需额外开发,适用于大规模集群管理。详情及示例可见链接文档。
|
7天前
|
运维 监控 安全
python在自动化运维中的妙用分享
python在自动化运维中的妙用分享
22 8