一、Pytest配置框架

Pytest的配置旨在改变其默认行为,以适应不同的测试需求和项目结构。理解其配置层级和常用参数,是高效使用Pytest的基础。

1. 配置的意义与层级

配置的本质在于提供一种机制,允许用户根据项目特点、团队规范或特定测试场景,调整Pytest的运行方式。Pytest的配置具有多层级性,优先级从低到高依次为:

•默认配置:Pytest内置的默认行为。

•环境变量:以PYTEST_开头的大写环境变量,例如PYTEST_ADDOPTS。

•配置文件:pytest.ini、pyproject.toml或setup.cfg等配置文件。

•命令行参数:通过命令行传递的参数,优先级最高。

这种层级结构确保了配置的灵活性和可覆盖性,允许用户在不同粒度上进行定制。

2. 获取所有配置信息

要全面了解Pytest支持的所有配置选项,可以通过运行pytest -h命令来获取帮助信息。该命令会列出所有可用的命令行参数、INI配置选项以及相关的环境变量。

命令:

pytest -h 

结果为:

  • 输出解析:

•-开头的选项:通常是命令行参数,用于在执行时直接影响Pytest行为。

•小写字母开头的选项:通常是可以在pytest.ini等配置文件中设置的INI配置项。

•大写字母开头的选项:通常是环境变量,可以在系统层面或脚本中设置。

3. 常用的命令行参数

命令行参数是临时调整Pytest行为最直接的方式,它们在当前测试运行中具有最高优先级。

参数

描述

示例用法

备注

-v

增加输出的详细程度,显示每个测试用例的名称和结果。

pytest -v

适用于需要查看每个测试执行状态的场景。

-s

停止捕获标准输出(stdout)和标准错误(stderr),允许测试用例中的print()函数直接输出到控制台。

pytest -s

在调试测试用例时非常有用,可以直接看到print的输出。

-x

遇到第一个失败的测试用例时立即停止测试执行。

pytest -x

适用于快速定位问题,避免不必要的后续测试。

-m <MARKEXPR>

根据标记表达式筛选要执行的测试用例。

`pytest -m

api|<MARKEXPR>可以是标记名(如api),也可以是逻辑表达式(如'api and web'或'not slow')。 | | -k <EXPR>| 根据表达式筛选测试用例的名称。 |pytest -k "test_add and not test_list"| 匹配测试函数、方法或类的名称。 | |--collect-only| 只收集测试用例,不执行。 |pytest --collect-only| 适用于检查测试发现是否符合预期。 | |--lf/--last-failed| 只运行上次失败的测试用例。 |pytest --lf| 快速重跑失败用例,提高调试效率。 | |--ff/--failed-first| 先运行上次失败的测试用例,然后运行其他测试。 |pytest --ff` | 优先验证修复效果,同时不遗漏其他测试。 |

示例代码(结合-s参数):

Python

import pytestdef add(a, b):return a + b# 示例:测试失败和print输出
def test_print_and_fail():print("Hello from test_print_and_fail!")assert 1 == 2 # 预期失败# 示例:测试输入
def test_input_example():# 当使用 `pytest -s` 时,input() 可以正常工作user_input = input("请输入您的姓名:")print(f"您输入的是:{user_input}")assert len(user_input) > 0class TestCalculator:def test_int_addition(self):assert add(1, 2) == 3def test_string_concatenation(self):assert add("hello", "world") == "helloworld"def test_list_concatenation(self):# 列表的加法是拼接操作assert add([1], [2, 3, 4]) == [1, 2, 3, 4]

4. pytest.ini配置文件

pytest.ini是Pytest最常用的配置文件,它允许我们持久化配置选项,例如注册自定义标记、设置默认命令行参数、配置测试发现规则等。它通常放置在项目的根目录下。

pytest.ini 示例结构:

[pytest]
# Pytest的最低版本要求
minversion = 6.0# 默认添加到命令行参数的选项
# -s: 允许捕获print输出
# -v: 增加输出详细程度
# --strict-markers: 强制要求所有使用的标记都必须在markers中注册
addopts = -s -v --strict-markers# 注册自定义标记及其描述
markers =api: 标记接口测试用例web: 标记UI(Web)测试用例ut: 标记单元测试用例login: 标记登录相关测试用例pay: 标记支付相关测试用例ddt: 标记数据驱动测试用例smoke: 标记冒烟测试用例,用于快速验证核心功能# 配置测试发现规则 (可选)
python_files = test_*.py *_test.py
python_classes = Test*
python_functions = test_# 配置测试路径 (可选)
# testpaths = tests/# 配置报告输出 (可选)
# log_cli = true
# log_cli_level = INFO
# log_cli_format = %(asctime)s [%(levelname)s] %(message)s (%(filename)s:%(lineno)s)

说明:

•[pytest]:配置文件的主体部分。

•minversion:指定Pytest的最低版本要求,如果当前Pytest版本低于此值,则会发出警告。

•addopts:用于设置每次运行Pytest时默认添加的命令行选项。这对于团队协作和CI/CD环境非常有用,可以确保测试运行的一致性。

•markers:这是非常重要的部分,用于注册自定义标记。在pytest.ini中注册标记可以避免PytestUnknownMarkWarning警告,并为标记提供清晰的描述,方便团队成员理解和使用。

二、标记mark

标记 可以让用例与众不同,进而可以让用例被区别对待

(一)、用户自动义标记

标记是Pytest中一种强大的元数据机制,它允许我们为测试函数、测试方法或测试类附加额外的信息。通过标记,我们可以对测试用例进行分类、筛选,甚至改变它们的执行行为。

1. 用户自定义标记

用户自定义标记主要用于对测试用例进行分类和筛选。它们需要在使用前在pytest.ini文件中进行注册。

步骤:

1、先注册

[pytest]markers =api:接口测试web:UI测试ut:单元测试login:登录相关pay:支付相关

2、再标记

实例:

import pytestdef add(a, b):return a + bclass TestAdd:@pytest.mark.apidef test_int(self):assert add(1, 2) == 3@pytest.mark.webdef test_str(self):assert add("1", "2") == "12"@pytest.mark.paydef test_list(self):assert add([1] ,[2,3,4,5]) == [1,2,3,4,5]

3、后筛选

利用命令: pytest -m 参数

实例:

pytest -m web

结果:

(二)、框架内置标记

Pytest提供了一些内置标记,它们无需在pytest.ini中注册即可直接使用,并且除了筛选功能外,还具有特殊的执行效果。这些标记通常用于控制测试的跳过、预期失败以及参数化等高级行为。

和用户自定义的区别

特性

用户自定义标记

框架内置标记

注册

必须在pytest.ini中注册

无需注册,直接使用

功能

主要用于筛选测试用例

除了筛选,还具有特殊的执行效果(如跳过、预期失败)

效果

仅影响测试的执行范围

影响测试的执行结果和报告状态

1、无需注册、可以直接使用

2、不仅可以筛选,还可以增加特殊效果

3、不同的标记、增加不同的特殊效果

  • skip:无条件跳过

@pytest.mark.skip装饰器用于无条件地跳过某个测试函数或测试类。这通常用于标记那些暂时不相关、尚未完成或由于特定原因不应执行的测试。

语法:

@pytest.mark.skip(reason="跳过原因")

示例:

import pytestdef add(a, b):return a + bclass TestSkip:@pytest.mark.skip(reason="此功能正在重构,暂时跳过测试")@pytest.mark.apidef test_old_api_endpoint(self):assert add(1, 2) == 3
  • skipif:有条件跳过

@pytest.mark.skipif装饰器允许我们根据特定条件来决定是否跳过测试。如果条件为真,则测试被跳过;否则,测试正常执行。这在跨平台测试、依赖特定环境或版本时非常有用。

语法:

@pytest.mark.skipif(condition, reason="跳过原因")

示例:

import pytest
import sysdef add(a, b):return a + bclass TestSkipIf:@pytest.mark.skipif(sys.version_info < (3, 9), reason="此测试需要Python 3.9或更高版本")@pytest.mark.webdef test_new_python_feature(self):assert add("Python", "3.9+") == "Python3.9+"@pytest.mark.skipif(True, reason="这是一个永远跳过的示例")@pytest.mark.webdef test_always_skip(self):assert add("a", "b") == "ab"
  • xfail:预期失败

@pytest.mark.xfail装饰器用于标记那些我们预期会失败的测试用例。当一个被标记为xfail的测试实际失败时,它不会被报告为错误,而是显示为“预期失败”(xfailed)。如果一个xfail测试意外地通过了,它会被报告为“预期通过”(xpassed)。这对于跟踪已知bug、尚未修复的功能或正在开发中的特性非常有用。

语法:

@pytest.mark.xfail(condition=None, reason="预期失败原因", raises=None, run=True, strict=False)

常用参数:

•reason:说明预期失败的原因。

•raises:指定预期失败时抛出的异常类型。如果测试失败但未抛出指定异常,则会被报告为意外通过。

•strict:如果设置为True,当xfail测试意外通过时,Pytest会将其报告为失败。默认为False。

示例:

import pytestdef divide(a, b):return a / bclass TestXfail:@pytest.mark.xfail(reason="除数为零,预期会抛出ZeroDivisionError")@pytest.mark.paydef test_divide_by_zero_xfail(self):# 预期此操作会引发ZeroDivisionErrorassert divide(10, 0) == 0 # 这个断言会失败,但因为xfail而被标记为预期失败@pytest.mark.xfail(raises=TypeError, reason="预期类型错误,例如字符串和数字相加")@pytest.mark.paydef test_type_error_xfail(self):# 预期此操作会引发TypeErrorassert 1 + "a" # 这会引发TypeError@pytest.mark.xfail(strict=True, reason="此功能正在开发中,如果意外通过则视为错误")def test_feature_in_progress_xfail(self):# 模拟一个正在开发中且目前预期会失败的功能assert False # 模拟失败
  • parametrize:参数化

@pytest.mark.parametrize是Pytest中用于数据驱动测试的核心标记。它允许我们使用不同的数据集重复执行同一个测试函数,从而提高测试的覆盖率和效率。

语法:

@pytest.mark.parametrize(argnames, argvalues, ids=None, scope=None)

常用参数:

•argnames:一个字符串,包含用逗号分隔的参数名称。

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

•ids:一个字符串列表,用于为每个参数组合生成更具可读性的测试ID。

示例:

import pytestdef multiply(a, b):return a * b@pytest.mark.parametrize("num1, num2, expected_result", [(1, 2, 2),(3, 4, 12),(5, 0, 0),(-1, 2, -2),
], ids=["positive_multiplication", "another_positive", "multiply_by_zero", "negative_multiplication"])
def test_multiply_operation(num1, num2, expected_result):assert multiply(num1, num2) == expected_result

一个实例:

import pytestdef add(a, b):return a + bclass TestAdd:@pytest.mark.skip@pytest.mark.apidef test_int(self):assert add(1, 2) == 3@pytest.mark.skipif(1 == 2,reason = "Java太难学了")@pytest.mark.webdef test_str(self):assert add("1", "2") == "12"@pytest.mark.xfail@pytest.mark.paydef test_list(self):assert add([1] ,[2,3,4,5]) == [1,2,3,4,5]@pytest.mark.xfail@pytest.mark.paydef test_list1(self):assert add([1] ,[2,3,4,5]) != [1,2,3,4,5]

结果:

三、数据驱动测试参数

在实际项目中,为了更好地管理和维护测试数据,通常会将测试数据存储在外部文件中,例如CSV、Excel或JSON格式。Pytest结合参数化(parametrize)功能,可以方便地实现数据驱动测试,即通过外部数据文件来驱动测试用例的执行数量和内容。

我们可以编写一个辅助函数来读取这些外部数据,并将其作为@pytest.mark.parametrize装饰器的参数值(argvalues)。

1. 数据文件示例:data.csv

a, b, c
1, 1, 1
2, 3, 5
3, 3, 6
4, 4, 7

2. 测试代码示例置文件

@pytest.mark.ddt
@pytest.mark.parametrize("a, b, c",read_csv("data.csv")
)
def test_ddt(self, a, b, c):res = add(int (a),int(b))assert res == int(c)

在上述test_ddt测试用例中,read_csv("data.csv")会读取data.csv中的每一行数据,并将其作为a、b、c的参数值传递给测试函数。每次执行时,a和b会被转换为整数进行add操作,然后结果与转换后的c进行断言。

3. 配置文件:pytest.ini

为了更好地管理自定义标记,例如本例中的ddt标记,建议在pytest.ini文件中进行注册。这有助于避免Pytest的警告,并提供标记的清晰描述。

[pytest]markers =api:接口测试web:UI测试ut:单元测试login:登录相关pay:支付相关ddt:数据驱动测试

pytest.ini中注册ddt标记,我们可以使用pytest -m ddt命令来专门执行所有数据驱动测试用例。

总结

通过本文的详细阐述,我们深入了解了Pytest的配置机制和强大的标记功能。合理利用命令行参数、pytest.ini配置文件以及各种内置和自定义标记,可以极大地提升测试的组织性、可控性和执行效率。掌握这些高级特性,将帮助您构建更专业、更高效的Python测试实践。

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Go-Redis × RediSearch 全流程实践

1. 连接 Redis ctx : context.Background()rdb : redis.NewClient(&redis.Options{Addr: "localhost:6379",Password: "",DB: 0,Protocol: 2, // 推荐 RESP2// UnstableResp3: true, // 若要体验 RESP3 Raw* })2. 准备示例数据 u…

深入理解指针(指针篇2)

在指针篇1我们已经了解了整型指针&#xff0c;当然还有很多其他类型的指针&#xff0c;像字符指针、数组指针、函数指针等&#xff0c;他们都有他们的特别之处&#xff0c;让我们接着学习。1. 指针类型介绍和应用1.1 字符指针变量字符指针变量类型为char*&#xff0c;一般这样使…

Python+Selenium自动化爬取携程动态加载游记

1. 引言 在旅游行业数据分析、舆情监测或竞品研究中&#xff0c;获取携程等平台的游记数据具有重要价值。然而&#xff0c;携程的游记页面通常采用动态加载&#xff08;Ajax、JavaScript渲染&#xff09;&#xff0c;传统的**<font style"color:rgb(64, 64, 64);backg…

ESP8266服务器建立TCP连接失败AT+CIPSTART=“TCP“,“192.168.124.1“,8080 ERROR CLOSED

1.检查服务器端口8081是否开启监听2.检查路由项是否被防火墙拦截方法 1&#xff1a;使用 netsh查看防火墙规则​netsh advfirewall firewall show rule nameall dirout | findstr "8081"如果无输出&#xff0c;说明防火墙未针对该端口设置规则&#xff08;可能默认拦…

Linux 内存管理(2):了解内存回收机制

目录一、透明大页1.1 原理1.2 透明大页的三大优势1.3 透明大页控制接口详解1.4 使用场景与最佳实践1.5 问题排查与监控1.6 与传统大页的对比二、Linux伙伴系统水位机制详解2.1 三种核心水位详解2.2 水位在伙伴系统中的实现2.3 水位触发机制的实际行为2.4 水位关键操作接口2.5 水…

前端学习7:CSS过渡与动画--补间动画 (Transition) vs 关键帧动画 (Animation)

一、补间动画&#xff08;Tween Animation&#xff09;vs 关键帧动画&#xff08;Keyframe Animation&#xff09;概念对比表&#xff1a;补间动画 (Transition)关键帧动画 (Animation)定义元素从初始状态到结束状态的过渡效果通过定义多个关键帧控制动画的中间状态触发方式需要…

PyTorch 损失函数详解:从理论到实践

目录 一、损失函数的基本概念 二、常用损失函数及实现 1. 均方误差损失&#xff08;MSELoss&#xff09; 2. 平均绝对误差损失&#xff08;L1Loss/MAELoss&#xff09; 3. 交叉熵损失&#xff08;CrossEntropyLoss&#xff09; 4. 二元交叉熵损失&#xff08;BCELoss&…

MinIO深度解析:从核心特性到Spring Boot实战集成

在当今数据爆炸的时代&#xff0c;海量非结构化数据的存储与管理成为企业级应用的关键挑战。传统文件系统在TB级数据面前捉襟见肘&#xff0c;而昂贵的云存储服务又让中小企业望而却步。MinIO作为一款开源高性能对象存储解决方案&#xff0c;正以其独特的技术优势成为开发者的首…

腾讯云服务上下载docker以及使用Rabbitmq的流程

执行以下命令&#xff0c;添加 Docker 软件源并配置为腾讯云源。sudo yum-config-manager --add-repohttps://mirrors.cloud.tencent.com/docker-ce/linux/centos/docker-ce.repo sudo sed -i "s/download.docker.com/mirrors.tencentyun.com\/docker-ce/g" /etc/yu…

UE5 一些关于过场动画sequencer,轨道track的一些Python操作

删除多余的轨道 import unreal def execute():movie_scene_actors []sequence_assets []data 0.0# 获取编辑器实用工具库lib unreal.EditorUtilityLibrary()selected_assets lib.get_selected_assets()for asset in selected_assets:if asset.get_class() unreal.LevelS…

前端性能优化“核武器”:新一代图片格式(AVIF/WebP)与自动化优化流程实战

前端性能优化“核武器”&#xff1a;新一代图片格式(AVIF/WebP)与自动化优化流程实战 当你的页面加载时间超过3秒时&#xff0c;用户的跳出率会飙升到40%以上。而在所有的前端性能优化手段中&#xff0c;图片优化无疑是投入产出比最高的一环。一张未经优化的巨大图片&#xff0…

单元测试学习+AI辅助单测

标题单元测试衡量指标具体测试1、Resource2、MockBean3、Test4、Test模板5、单测示例H2数据库JSON1、使用方式AI辅助单测使用方法单元测试 单元测试一般指程序员在写好代码后&#xff0c;提交测试前&#xff0c;需要验证自己的代码是否可以正常工作&#xff0c;同时将自己的代…

Spring Cloud Gateway与Envoy Sidecar在微服务请求路由中的架构设计分享

Spring Cloud Gateway与Envoy Sidecar在微服务请求路由中的架构设计分享 在现代微服务架构中&#xff0c;请求路由层承担着流量分发、安全鉴权、流量控制等多重职责。传统的单一网关方案往往面临可扩展性和可维护性挑战。本文将从真实生产环境出发&#xff0c;分享如何结合Spri…

GitHub Pages+Jekyll 静态网站搭建(二)

GitHub PagesJekyll 静态网站搭建&#xff08;二&#xff09;GitHub PagesJekyll 静态网站搭建&#xff08;二内容简介搭建模板网站部署工作流程GitHub PagesJekyll 静态网站搭建&#xff08;二 内容简介 &#x1f6a9; Tech Contents 该文主要涉及Jekyll主题的下载与使用。Gi…

Django 实战:I18N 国际化与本地化配置、翻译与切换一步到位

文章目录一、国际化与本地化介绍定义相关概念二、安装配置安装 gettext配置 settings.py三、使用国际化视图中使用序列化器和模型中使用四、本地化操作创建或更新消息文件消息文件说明编译消息文件五、项目实战一、国际化与本地化介绍 定义 国际化和本地化的目标&#xff0c;…

通过国内扣子(Coze)搭建智能体并接入discord机器人

国内的扣子是无法直接授权给discord的&#xff0c;但是用国外的coze的话&#xff0c;大模型调用太贵&#xff0c;如果想要接入国外的平台&#xff0c;那就需要通过调用API来实现。 1.搭建智能体&#xff08;以工作流模式为例&#xff09; 首先&#xff0c;我们需要在扣子平台…

【办公类-107-02】20250719视频MP4转gif(削减MB)

背景需求 最近在写第五届智慧项目结题(一共3篇)写的昏天黑地,日以继夜。 我自己《基于“AI技术”的幼儿园教学资源开发和运用》提到了AI绘画、AI视频和AI编程。 为了更好的展示AI编程的状态,我在WORD里面插入了MP4转gif的动图。 【教学类-75-04】20241023世界名画-《蒙…

一文讲清楚React的render优化,包括shouldComponentUpdate、PureComponent和memo

文章目录一文讲清楚React的render优化&#xff0c;包括shouldComponentUpdate、PureComponent和memo1. React的渲染render机制2. shouldComponentUpdate2.1 先上单组件渲染&#xff0c;验证state变化2.2 上父子组件&#xff0c;验证props2. PureComponent2.1 单组件验证state2.…

物联网iot、mqtt协议与华为云平台的综合实践(万字0基础保姆级教程)

本学期的物联网技术与应用课程&#xff0c;其结课设计内容包含&#xff1a;mqtt、华为云、PyQT5和MySQL等结合使用&#xff0c;完成了从华为云配置产品信息以及转发规则&#xff0c;到mqtt命令转发&#xff0c;再到python编写逻辑代码实现相关功能&#xff0c;最后用PyQT5实现面…

使用IntelliJ IDEA和Maven搭建SpringBoot集成Fastjson项目

使用IntelliJ IDEA和Maven搭建SpringBoot集成Fastjson项目 下面我将详细介绍如何在IntelliJ IDEA中使用Maven搭建一个集成Fastjson的SpringBoot项目&#xff0c;包含完整的环境配置和代码实现。 一、环境准备 软件要求 IntelliJ IDEA 2021.x或更高版本JDK 1.8或更高版本&#x…