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

测试学习之——Pytest Day4

Pytest作为Python中功能强大且易于使用的测试框架,深受开发者喜爱。它不仅提供了简洁的测试编写方式,还通过丰富的配置选项、灵活的标记机制和强大的数据驱动能力,极大地提升了测试效率和可维护性。本文将深入探讨Pytest的配置意义与层级、常用命令参数、标记(mark)的使用,以及数据驱动测试的实现方法。

一、Pytest配置:意义、层级与常用参数

Pytest的配置允许我们自定义测试行为,例如指定测试文件发现规则、添加命令行选项、定义fixture等。理解其配置意义和层级对于高效使用Pytest至关重要。

1. 配置意义与层级

Pytest的配置具有层级性,允许在不同粒度上进行设置,从项目级别到测试文件级别。当存在多个配置时,Pytest会按照一定的优先级进行合并和覆盖。

•全局配置: 通常通过pytest.ini、pyproject.toml或setup.cfg文件在项目根目录进行配置。这些配置对整个项目的所有测试都有效。

•目录级配置: 可以在子目录中放置pytest.ini等配置文件,这些配置仅对当前目录及其子目录下的测试文件生效,并会覆盖全局配置中的同名设置。

•模块/文件级配置: 在测试文件中,可以通过pytest.mark等装饰器对单个测试函数或类进行更细粒度的配置。

•命令行参数: 命令行参数具有最高的优先级,会覆盖所有文件中的配置。

2. 常用命令参数

Pytest提供了丰富的命令行参数,用于控制测试的执行行为。以下是一些常用的参数:

•-v:显示更详细的测试结果(verbose)。

•-s:允许捕获标准输出(stdout)和标准错误(stderr),通常用于打印调试信息。

•-x:遇到第一个失败的测试时立即停止测试。

•--lf (--last-failed):只运行上次失败的测试。

•--ff (--failed-first):先运行上次失败的测试,然后运行所有其他测试。

•-k <expression>:根据名称表达式选择要运行的测试。例如,-k "keyword and not another_keyword"。

•-m <marker_expression>:根据标记表达式选择要运行的测试。例如,-m "web and not slow"。

•--collect-only:只收集测试,不执行。

•--maxfail=<num>:在达到指定数量的失败后停止测试。

•--html=<path>:生成HTML格式的测试报告(需要安装pytest-html插件)。

•--alluredir=<path>:指定Allure报告结果的输出目录(需要安装allure-pytest插件)。

示例:命令行执行

pytest -v -s my_test_file.py pytest -m "smoke" pytest --alluredir=./allure-results

3. 配置文件:pytest.ini

pytest.ini是Pytest最常用的配置文件,它允许我们将常用的命令行参数、标记注册、测试发现规则等固化到文件中,避免每次都在命令行中输入。一个典型的pytest.ini文件可能包含以下内容:

# pytest.ini
[pytest]
# 添加默认的命令行参数
addopts = -vs --strict-markers# 注册自定义标记,避免出现Unknown marker警告
markers =smoke: 冒烟测试regression: 回归测试web: Web自动化测试# 配置测试文件和目录的发现规则
python_files = test_*.py *_test.py
python_classes = Test*
python_functions = test_# 配置测试路径,只在指定路径下查找测试
testpaths =tests/e2e_tests/# 配置allure报告输出目录(如果使用allure)
# addopts = --alluredir=./allure-results --clean-alluredir

配置说明:

•addopts:用于设置默认的命令行参数,每次运行pytest时都会自动加上这些参数。

•markers:用于注册自定义的测试标记。注册后,Pytest就不会对这些标记发出“Unknown marker”警告。

•python_files、python_classes、python_functions:定义Pytest如何发现测试文件、测试类和测试函数。

•testpaths:指定Pytest应该在哪些目录下查找测试文件。

二、标记(Mark):用户自定义与框架内置

Pytest的标记(pytest.mark)是一个强大的功能,它允许我们对测试函数、测试类甚至模块进行分类和筛选。通过标记,我们可以灵活地选择性执行特定类型的测试,例如只运行冒烟测试、跳过某些测试等。

1. 用户自定义标记步骤

自定义标记的步骤非常简单:

1.在测试代码中使用@pytest.mark.<marker_name>装饰器: 将标记应用到测试函数或类上。

2.在pytest.ini中注册标记(可选但推荐): 在pytest.ini文件的[pytest]部分添加markers选项,注册自定义标记。这可以避免Pytest在运行时发出“Unknown marker”警告,并提供标记的描述。

3.通过命令行执行带有特定标记的测试: 使用-m参数加上标记表达式来运行测试。

示例:自定义标记

# test_example.py
import pytest@pytest.mark.smoke
def test_login_success():assert True@pytest.mark.regression
@pytest.mark.slow
def test_complex_calculation():assert True@pytest.mark.web
def test_homepage_load():assert True

pytest.ini配置:

# pytest.ini
[pytest]
markers =smoke: 冒烟测试regression: 回归测试slow: 运行缓慢的测试web: Web自动化测试

 Web自动化测试

执行命令:

# 运行所有冒烟测试
pytest -m smoke# 运行所有回归测试,但不包括慢速测试
pytest -m "regression and not slow"# 运行所有web测试
pytest -m web

2. 框架内置标记

Pytest也提供了一些内置的标记,用于处理常见的测试场景:

•@pytest.mark.skip:无条件跳过测试。可以提供一个reason参数说明跳过的原因。

•@pytest.mark.skipif(condition, reason):根据条件跳过测试。当condition为True时跳过。

•@pytest.mark.xfail(condition, reason, raises):预期失败的测试。即使测试失败,也不会计入失败总数,而是标记为“xfailed”。

•@pytest.mark.parametrize(argnames, argvalues):用于数据驱动测试,将在下一节详细介绍。

三、Pytest的数据驱动测试:parametrize实现

数据驱动测试(Data-Driven Testing)是一种测试方法,它将测试逻辑与测试数据分离。通过使用不同的测试数据重复执行相同的测试逻辑,可以有效地增加测试覆盖率并减少代码冗余。Pytest通过@pytest.mark.parametrize装饰器提供了强大的数据驱动能力。

1. parametrize的基本用法

@pytest.mark.parametrize装饰器接受两个主要参数:

•argnames:一个字符串,包含用逗号分隔的参数名称。这些参数将作为测试函数的参数传入。

•argvalues:一个列表,包含参数值的元组或列表。每个元组/列表对应一次测试执行的参数组合。

示例:单个参数的数据驱动

# test_data_driven.py
import pytest@pytest.mark.parametrize("input_value, expected_output", [(1, 2),(2, 3),(3, 4),
])
def test_increment(input_value, expected_output):assert input_value + 1 == expected_output

在这个例子中,test_increment函数会被执行三次,每次传入不同的input_value和expected_output。

2. 多个参数的数据驱动

parametrize可以很方便地处理多个参数的组合。

示例:多个参数的数据驱动

# test_data_driven.py
import pytest@pytest.mark.parametrize("num1, num2, expected_sum", [(1, 2, 3),(0, 0, 0),(-1, 5, 4),(10, -3, 7),
])
def test_addition(num1, num2, expected_sum):assert num1 + num2 == expected_sum

3. parametrize与fixture结合

parametrize还可以与fixture结合使用,为每个参数组合提供不同的fixture实例。

示例:parametrize与fixture结合

# conftest.py
import pytest@pytest.fixture
def setup_data(request):# request.param 会获取到parametrize传入的参数data = request.param * 2yield data# test_data_driven.py
import pytest@pytest.mark.parametrize("setup_data", [1, 2, 3], indirect=True)
def test_with_fixture_data(setup_data):# setup_data 会依次是 2, 4, 6assert setup_data % 2 == 0

在@pytest.mark.parametrize中设置indirect=True,表示setup_data不是直接作为参数传入,而是作为fixture的名称,Pytest会为每个参数值调用setup_data fixture。

4. 从外部文件加载数据

对于大量的测试数据,通常会将其存储在外部文件(如CSV、JSON、YAML)中,然后动态加载。这里以YAML为例,结合之前提到的PyYAML库。

data.yaml文件:

# data.yaml
- test_case:id: 1input: 10expected: 20
- test_case:id: 2input: 0expected: 0
- test_case:id: 3input: -5expected: -10

test_from_file.py文件:

import pytest
import yamldef load_test_data(file_path):with open(file_path, 'r', encoding='utf-8') as f:return yaml.safe_load(f)@pytest.mark.parametrize("test_data", load_test_data('data.yaml'))
def test_multiply_by_two(test_data):input_value = test_data['test_case']['input']expected_output = test_data['test_case']['expected']assert input_value * 2 == expected_output

这种方式使得测试数据与测试逻辑完全分离,便于数据的管理和维护。

总结

Pytest通过其灵活的配置机制、强大的标记功能和便捷的数据驱动能力,为Python项目的测试提供了全面的支持。合理利用pytest.ini进行项目级配置,通过@pytest.mark对测试进行分类和筛选,以及运用@pytest.mark.parametrize实现数据驱动测试,都能够显著提升测试的效率、可读性和可维护性。掌握这些进阶用法,将帮助您构建更加健壮和高效的自动化测试体系。

http://www.xdnf.cn/news/1154017.html

相关文章:

  • Cosmos:构建下一代互联网的“区块链互联网
  • 黑马教程Webday6
  • 从零开始的云计算生活——番外5,使用ELK实现对应用日志的监控
  • HTML Style 对象深度解析:从基础到高级应用
  • client-go: k8s选主
  • 【Linux】1. Linux操作系统介绍及环境搭建
  • 20250720-6-Kubernetes 调度-nodeName字段,DaemonS_笔记
  • MySQL笔记3
  • 西门子 S7-1500 系列 PLC CPU 选型全指南:从类型到实战
  • 30天打牢数模基础-K均值聚类
  • 最大子数组和问题-详解Kadane算法
  • MySQL 配置性能优化实操指南:分版本5.7和8.0适配方案
  • 爬虫实战案例(两个)
  • 笔试——Day13
  • LeetCode 1712.将数组分成三个子数组的方案数
  • LVS(Linux Virtual Server) 集群
  • 【AI】文生图文生视频
  • 基于单片机的危险气体远程检测报警系统设计
  • 周末总结(2024/07/19)
  • 前端面试专栏-工程化:28.团队协作与版本控制(Git)
  • Jmeter系列(7)-线程组
  • python基础笔记
  • 西门子 S7-1500 PLC 电源选型指南:系统电源与负载电源的核心区别
  • LLM大模型微调技术与最佳实践
  • freertos任务调度关键函数理解
  • 动态规划——状压DP经典题目
  • 【Keil5-map文件】
  • FMEA-CP-PFD三位一体数字化闭环:汽车部件质量管控的速效引擎
  • simulink系列之模型接口表生成及自动连线脚本
  • Nestjs框架: 理解 RxJS响应式编程的核心概念与实践