pytest框架进阶自学系列 | 运行的失败管理
haoteby 2025-05-09 18:44 17 浏览
书籍来源:房荔枝 梁丽丽《pytest框架与自动化测试应用》
一边学习一边整理老师的课程内容及实验笔记,并与大家分享,侵权即删,谢谢支持!
附上汇总贴:pytest框架进阶自学系列 | 汇总_热爱编程的通信人的博客-CSDN博客
最多允许失败的测试用例数
当达到最大上限时,退出执行。如未配置,则没有上限。
命令pytest -x遇到第一个失败时,退出执行。
PS D:\SynologyDrive\CodeLearning\WIN\pytest-book\src\chapter-2> pytest -x
========================================================================================================= test session starts =========================================================================================================
platform win32 -- Python 3.7.7, pytest-5.4.1, py-1.11.0, pluggy-0.13.1
rootdir: D:\SynologyDrive\CodeLearning\WIN\pytest-book\src\chapter-2, inifile: pytest.ini
plugins: allure-pytest-2.13.2
collected 32 items
test_assert_1.py F
============================================================================================================== FAILURES ===============================================================================================================
______________________________________________________________________________________________________ test_long_str_comparison _______________________________________________________________________________________________________
def test_long_str_comparison():
str3 = 'abcdef'
str4 = 'adcdef'
> assert str3 == str4
E AssertionError: assert 'abcdef' == 'adcdef'
E - adcdef
E ? ^
E + abcdef
E ? ^
test_assert_1.py:4: AssertionError
========================================================================================================== warnings summary ===========================================================================================================
c:\users\guoliang\appdata\local\programs\python\python37\lib\site-packages\_pytest\terminal.py:289
c:\users\guoliang\appdata\local\programs\python\python37\lib\site-packages\_pytest\terminal.py:289: PytestDeprecationWarning: TerminalReporter.writer attribute is deprecated, use TerminalReporter._tw instead at your own risk.
See https://docs.pytest.org/en/latest/deprecations.html#terminalreporter-writer for more information.
"TerminalReporter.writer attribute is deprecated, use TerminalReporter._tw instead at your own risk.\n"
-- Docs: https://docs.pytest.org/en/latest/warnings.html
======================================================================================================= short test summary info =======================================================================================================
FAILED test_assert_1.py::test_long_str_comparison - AssertionError: assert 'abcdef' == 'adcdef'
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! stopping after 1 failures !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
==================================================================================================== 1 failed, 1 warning in 10.42s ====================================================================================================
PS D:\SynologyDrive\CodeLearning\WIN\pytest-book\src\chapter-2>
命令pytest --maxfail=2遇到第2个失败时,退出执行。同理,命令pytest --maxfail=3遇到第3个失败时退出执行。
执行结果如下:
PS D:\SynologyDrive\CodeLearning\WIN\pytest-book\src\chapter-2> pytest -x
========================================================================================================= test session starts =========================================================================================================
platform win32 -- Python 3.7.7, pytest-5.4.1, py-1.11.0, pluggy-0.13.1
rootdir: D:\SynologyDrive\CodeLearning\WIN\pytest-book\src\chapter-2, inifile: pytest.ini
plugins: allure-pytest-2.13.2
collected 32 items
test_assert_1.py F
============================================================================================================== FAILURES ===============================================================================================================
______________________________________________________________________________________________________ test_long_str_comparison _______________________________________________________________________________________________________
def test_long_str_comparison():
str3 = 'abcdef'
str4 = 'adcdef'
> assert str3 == str4
E AssertionError: assert 'abcdef' == 'adcdef'
E - adcdef
E ? ^
E + abcdef
E ? ^
test_assert_1.py:4: AssertionError
========================================================================================================== warnings summary ===========================================================================================================
c:\users\guoliang\appdata\local\programs\python\python37\lib\site-packages\_pytest\terminal.py:289
c:\users\guoliang\appdata\local\programs\python\python37\lib\site-packages\_pytest\terminal.py:289: PytestDeprecationWarning: TerminalReporter.writer attribute is deprecated, use TerminalReporter._tw instead at your own risk.
See https://docs.pytest.org/en/latest/deprecations.html#terminalreporter-writer for more information.
"TerminalReporter.writer attribute is deprecated, use TerminalReporter._tw instead at your own risk.\n"
-- Docs: https://docs.pytest.org/en/latest/warnings.html
======================================================================================================= short test summary info =======================================================================================================
FAILED test_assert_1.py::test_long_str_comparison - AssertionError: assert 'abcdef' == 'adcdef'
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! stopping after 1 failures !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
==================================================================================================== 1 failed, 1 warning in 10.42s ====================================================================================================
PS D:\SynologyDrive\CodeLearning\WIN\pytest-book\src\chapter-2>
失败运行管理的原理
用例运行失败后,通常希望再次执行失败的用例,看是环境问题还是脚本问题,因此测试方法运行失败需被记录。
这部分内容与第12章缓存目录设置配置内容相一致。cacheprovider插件将执行状态写入缓存文件夹,pytest会将本轮测试的执行状态写入.pytest_cache文件夹,这个行为是由自带的cacheprovider插件实现的。
pytest默认将测试执行的状态写入根目录中的.pytest_cache文件夹,也可以通过在pytest.ini中配置cache_dir选项来自定义缓存的目录,它可以是相对路径,也可以是绝对路径,相对路径指的是相对于pytest.ini文件所在的目录。
例如,我们想把第12章执行的状态的缓存和源码放在一起,该如何实现呢?实现步骤如下。
在src/chapter12/pytest.ini中添加如下配置:
[pytest]
cache_dir = .pytest-cache
这样,即使在项目的根目录下执行src/chapter12/中的用例,也只会在
pytest_book/src/chapter12/.pytest_cache中生成缓存,而不是pytest_book/.pytest_cache中。
(1)在chapter12中复制chapter-2中的test_assert_2.py并改名为test_assert_12.py,需要将内容进行适当修改。
(2)在src路径下执行pytest src/chapter12。
(3)执行状态未写在根目录下,而是写在测试文件所在的目录中(.pytest_cache)。
执行结果如图所示。
cacheprovider插件实现失败管理的准备:
(1)在chapter12下创建pytest.ini文件,代码如下:
[pytest]
cache_dir = .pytest-cache
(2)在chapter12下创建test_failed.py文件,代码如下:
import pytest
@pytest.mark.parametrize('num', [1,2])
def test_failed(num):
assert num == 1
(3)在chapter12下创建test_pass.py文件,代码如下:
def test_pass():
assert 1
(4)如果大家是从前到后进行实践,则需要删除test_assert_12.py和.pytest_cache。
(5)再在根目录下执行pytest src/chapter12。
(6)chapter12下会自动创建缓存文件夹及文件.pytest_cache。
执行结果如下,可以看到一共收集到3个测试用例,其中有一个失败,另外两个成功,并且两个执行成功的用例分属不同的测试模块。
执行结果如下:
PS D:\SynologyDrive\CodeLearning\WIN\pytest-book\src> pytest .\chapter-12\
========================================================================================================= test session starts =========================================================================================================
platform win32 -- Python 3.7.7, pytest-5.4.1, py-1.11.0, pluggy-0.13.1
cachedir: .pytest-cache
rootdir: D:\SynologyDrive\CodeLearning\WIN\pytest-book\src\chapter-12, inifile: pytest.ini
plugins: allure-pytest-2.13.2
collected 3 items
chapter-12\test_failed.py .F [ 66%]
chapter-12\test_pass.py . [100%]
============================================================================================================== FAILURES ===============================================================================================================
___________________________________________________________________________________________________________ test_failed[2] ____________________________________________________________________________________________________________
num = 2
@pytest.mark.parametrize('num', [1,2])
def test_failed(num):
> assert num == 1
E assert 2 == 1
chapter-12\test_failed.py:5: AssertionError
======================================================================================================= short test summary info =======================================================================================================
FAILED chapter-12\test_failed.py::test_failed[2] - assert 2 == 1
===================================================================================================== 1 failed, 2 passed in 0.30s =====================================================================================================
PS D:\SynologyDrive\CodeLearning\WIN\pytest-book\src>
同时,pytest也在src/chapter12/目录下生成缓存文件夹(.pytest_cache)。
具体介绍一下cacheprovider插件的功能。
--lf,--last-failed:只执行上一轮失败的用例。
缓存中的lastfailed文件记录了上次失败的用例ID,可以通过--cache-show命令查看它的内容。
--cache-show命令是cacheprovider提供的新功能,它不会导致任何用例的执行。
执行结果如下:
PS D:\SynologyDrive\CodeLearning\WIN\pytest-book\src> pytest .\chapter-12\ -q --cache-show 'lastfailed'
cachedir: D:\SynologyDrive\CodeLearning\WIN\pytest-book\src\chapter-12\.pytest-cache
---------------------------------------------------------------------------------------------------- cache values for 'lastfailed' ----------------------------------------------------------------------------------------------------
cache\lastfailed contains:
{'test_failed.py::test_failed[2]': True}
no tests ran in 0.00s
PS D:\SynologyDrive\CodeLearning\WIN\pytest-book\src>
可以看到,它记录了一个用例,此用例为上次失败的测试用例的ID:test_failed.py::test_failed[2]。
下次执行,当使用--lf选项时,pytest在收集阶段只会选择这个失败的用例,而忽略其他的用例。命令pytest --lf --collect-only src/chapter12/中的collect-only选项只收集用例而不执行。
执行结果如下:
PS D:\SynologyDrive\CodeLearning\WIN\pytest-book\src> pytest --lf --collect-only .\chapter-12\
========================================================================================================= test session starts =========================================================================================================
platform win32 -- Python 3.7.7, pytest-5.4.1, py-1.11.0, pluggy-0.13.1
cachedir: .pytest-cache
rootdir: D:\SynologyDrive\CodeLearning\WIN\pytest-book\src\chapter-12, inifile: pytest.ini
plugins: allure-pytest-2.13.2
collected 1 item
<Module test_failed.py>
<Function test_failed[2]>
run-last-failure: rerun previous 1 failure (skipped 1 file)
======================================================================================================== no tests ran in 0.02s ========================================================================================================
PS D:\SynologyDrive\CodeLearning\WIN\pytest-book\src>
仔细观察一下上面的回显,collecting...<Module test_failed.py>只收集到test_fail.py文件中<Function test_failed[2]>,表示第二个执行用例失败了,需要重新执行(跳过5个文件)。1deselected(没有选择),此处的“没有选择”是<Module test_failed.py>中执行通过的第一个用例。跳过5个文件包括pytest.ini和test_pass.py在内的5个文件。
实际上,--lf复写了用例收集阶段的两个钩子方法:pytest_ignore_collect(path,config)和
pytest_collection_modifyitems(session,config,items)。
--ff,--failed-first:先执行上一轮失败的用例,再执行其他的用例。
先通过实践看一看这个命令的效果,再去分析它的实现,命令如下:
执行结果如下:
PS D:\SynologyDrive\CodeLearning\WIN\pytest-book\src> pytest --collect-only -s --ff .\chapter-12\
========================================================================================================= test session starts =========================================================================================================
platform win32 -- Python 3.7.7, pytest-5.4.1, py-1.11.0, pluggy-0.13.1
cachedir: .pytest-cache
rootdir: D:\SynologyDrive\CodeLearning\WIN\pytest-book\src\chapter-12, inifile: pytest.ini
plugins: allure-pytest-2.13.2
collected 3 items
<Module test_failed.py>
<Function test_failed[2]>
<Function test_failed[1]>
<Module test_pass.py>
<Function test_pass>
run-last-failure: rerun previous 1 failure first
======================================================================================================== no tests ran in 0.02s ========================================================================================================
PS D:\SynologyDrive\CodeLearning\WIN\pytest-book\src>
可以看到一共收集到3个测试用例,和正常所收集到的测试用例的顺序相比,上一轮失败的test_failed.py::test_failed[2]用例在最前面,将优先执行。
实际上,-ff只复写了钩子方法:
pytest_collection_modifyitems(session,config,items),它可以过滤或者重新排序所收集到的用例。
--nf,--new-first:先执行新加的或修改的用例,再执行其他的用例。
缓存中的nodeids文件记录了上一轮执行的所有用例,命令如下:
执行结果如下:
PS D:\SynologyDrive\CodeLearning\WIN\pytest-book\src> pytest .\chapter-12\ --cache-show 'nodeids'
========================================================================================================= test session starts =========================================================================================================
platform win32 -- Python 3.7.7, pytest-5.4.1, py-1.11.0, pluggy-0.13.1
cachedir: .pytest-cache
rootdir: D:\SynologyDrive\CodeLearning\WIN\pytest-book\src\chapter-12, inifile: pytest.ini
plugins: allure-pytest-2.13.2
cachedir: D:\SynologyDrive\CodeLearning\WIN\pytest-book\src\chapter-12\.pytest-cache
----------------------------------------------------------------------------------------------------- cache values for 'nodeids' ------------------------------------------------------------------------------------------------------
cache\nodeids contains:
['test_failed.py::test_failed[1]',
'test_failed.py::test_failed[2]',
'test_pass.py::test_pass']
======================================================================================================== no tests ran in 0.01s ========================================================================================================
PS D:\SynologyDrive\CodeLearning\WIN\pytest-book\src>
从执行结果可以看到上一轮共执行了3个测试用例。
现在可以在test_pass.py中新加一个用例,并修改一下test_failed.py文件中的用例(但是不添加新用例)。
代码如下:
def test_pass():
assert 1
def test_new_pass():
assert 1
再来执行一下收集命令,命令如下:
执行结果如下:
PS D:\SynologyDrive\CodeLearning\WIN\pytest-book\src> pytest --collect-only -s --nf .\chapter-12\
========================================================================================================= test session starts =========================================================================================================
platform win32 -- Python 3.7.7, pytest-5.4.1, py-1.11.0, pluggy-0.13.1
cachedir: .pytest-cache
rootdir: D:\SynologyDrive\CodeLearning\WIN\pytest-book\src\chapter-12, inifile: pytest.ini
plugins: allure-pytest-2.13.2
collected 4 items
<Module test_pass.py>
<Function test_new_pass>
<Function test_pass>
<Module test_failed.py>
<Function test_failed[1]>
<Function test_failed[2]>
======================================================================================================== no tests ran in 0.48s ========================================================================================================
PS D:\SynologyDrive\CodeLearning\WIN\pytest-book\src>
可以看到,新加的用例排在最前面,其次修改过的测试用例紧接其后,最后才是旧的用例,这个行为在源码中有所体现。
--cache-clear:先清除所有缓存,再执行用例。
如果上一轮没有失败的用例,则需要先清除缓存,再执行test_pass.py模块(它的用例都是能测试成功的)。
执行及结果如下:
======================================================================================================== no tests ran in 0.48s ========================================================================================================
PS D:\SynologyDrive\CodeLearning\WIN\pytest-book\src> pytest --cache-clear -q -s .\chapter-12\test_pass.py
..
2 passed in 0.01s
PS D:\SynologyDrive\CodeLearning\WIN\pytest-book\src>
其结果是不是少了点什么呢?对!因为没有失败的用例,所以不会生成lastfailed文件,那么这个时候再使用--lf和--ff会发生什么呢?我们来试试。
注意:如果我们观察得足够仔细,就会发现现在的缓存目录和之前相比不仅少了lastfailed文件,还少了CACHEDIR.TAG、.gitignore和README.md这3个文件。这是一个Bug,现在pytest的版本是5.2.1,预计会在之后的版本得到修复。
相关推荐
- 提高购票成功率!官方“捡漏神器”,收藏!
-
清明小长假火车票已全部开售您买好假期出行的车票了吗?如果还没有买到的话不妨试试官方“捡漏神器”铁路12306的候补购票功能候补购票说明每个用户同时可以保有6个待兑现候补订单;每个候补订单最多可选择3个...
- 手把手教你用官方“捡漏神器”!提高购票成功率的秘诀在这
-
清明小长假火车票已全部开售您买好假期出行的车票了吗?...
- 微信里隐藏一个免费存放照片的相册,不占手机内存,不会用太浪费
-
才发现,不知道太可惜了,手机里有个免费存放照片的相册,你知道吗?简单一学就会,可惜好多人不知道,这个相册有三大优点:一就是免费长期使用二就是不占手机内存三就是无限次的上传...
- 速存!2025 教资笔试报名照片上传规范细则
-
教资报名卡在照片环节?!照片不合规直接导致报名失败,务必按这5点:1.基本要求:近6个月内免冠正面证件照,清晰无遮挡!2.尺寸要求:295像素(宽)*413像素(高)3.大小要求:文件不能超过...
- 微信新功能:朋友圈支持图片、表情包评论
-
不知道大家是否还记得,在2019年12月期间微信朋友圈评论支持发送自定义表情包,这个当时我也为大家分享过,只不过该功能在上线后没多久就下线了,具体原因未知,但我个人猜测可能跟一些用户发送的图片...
- 全红婵更新抖音动态,上传12张照片,第一张就是妹妹戴眼镜的合照
-
全红婵都抖音动态终于更新了,一共上传十二张照片,第一张就是和妹妹一起游玩戴眼镜的合照,还有婵宝的美甲照片全红婵刚发的新照片炸出一堆粉丝!首图就是她和妹妹戴着3D眼镜,头靠头贴在一起,口罩都挡不住姐妹...
- 女人给你发照片是暗示了什么?读懂背后心意,把握情感信号
-
在日常交流中,女人突然发来照片,看似随意的举动,可能暗藏深意。了解这些照片背后的暗示,不仅能让你更懂她的想法,还能更好地把握彼此之间的情感走向。接下来,就为你解析女人发照片背后的多种潜在含义。一、分享...
- 微信朋友圈评论区迎来大更新:支持发图片和动图
-
最近,不少用户发现微信正在悄悄上线一个全新功能——...
- 有这个神器,插入500个员工照片只需1分钟
-
如下图,是一份模拟的员工档案表,需要根据A列的员工姓名,在C列插入对应的员工照片:...
- 上传模特和商品图片,就能自动合成带货展示视频!
-
上传一张模特照片,再上传一张产品照片,就可以直接生成这种AI数字人带货的展示视频。这就是微度最近上线的主体库功能。·只需要在微度里面找到参考生视频的功能,选择主体库,把自己常用的模特照片和商品图片上传...
- 微信朋友圈终于可以发图片评论了!这次是灰度测试,你中招了吗?
-
微信近期悄然上线了一项全新功能——朋友圈评论可发图片!尽管当下仅在部分iOS用户群体中开展测试,但已有不少用户开始尝鲜使用。该功能最早于2019年曾短暂亮相,后因审核方面的问题而被下线,如今再度回归大...
- 2025税务师报名照上传必看:详细要求+手机制作全攻略
-
一、2025年税务师考试报名时间网上报名时间:2025年5月6日-7月15日...
- 前端移动端上传图片pc端如何实时获取
-
在一个前后端分离的项目中,如果你希望前端移动端上传图片后,PC端能实时获取这张图片,通常有几种实现方式:一、使用轮询(简单但不是实时)PC端每隔几秒请求一次服务器,看是否有新图片。...
- 上传照片文件大小超过了规定的大小怎么办?一招教你搞定!
-
上传照片文件大小如果超过了规定大小怎么办?比如上传照片,首先原始图像的大小多大?把光标放在图片上面,可以直接显示大小是二百四十六,也可以选中图片按右键,属性也可以查看图像大小,属性里面也可以,但也可以...
- 用最简单的方法给手机照片添加文字!雷哥手把手教你2分钟搞定
-
用最简单的方法给手机照片添加文字!雷哥手把手教你2分钟搞定...