Python自动化框架之pytest,从入门到精通知识点全收录
ccwgpt 2024-10-09 08:52 27 浏览 0 评论
Pytest是成熟的功能齐全的Python测试工具,有助于编写更好的程序。
一、Pytest基本知识
参考官方文档翻译过来,了解一下Pytest知识点。
1、Pytest中可以按节点ID运行测试。
在命令行中指定测试方法的另一个示例:
pytest test_mod.py::TestClass::test_method
2、通过标记表达式运行测试
pytest -m slow
将运行用@Pytest.mark.slow装饰器装饰的所有测试。
3、详细的总结报告
pytest –ra
4、分析测试执行持续时间
要获取最慢的10个测试持续时间的列表,请执行以下操作:
pytest --durations=10
5、将测试报告发送到在线pastebin服务
为每个测试失败创建一个URL:
pytest --pastebin=failed
为整个测试会话日志创建一个URL
pytest --pastebin=all
6、从python代码中调用Pytest
pytest.main()
注意:
调用Pytest.main()将导致导入你的测试及其导入的任何模块。由于python导入系统的缓存机制,Pytest.main()从同一进程进行后续调用不会反映两次调用之间对这些文件的更改。因此,Pytest.main()不建议从同一进程进行多次调用(例如,以重新运行测试)。
7、断言
使用标准python assert来验证python测试中的期望和值。
8、conftest.py
对于可能的值scope有:function,class,module,package或session。
9、Pytest将建立一个字符串,它是用于在参数化fixture,例如每个fixtures测试ID。这些ID可以用于-k选择要运行的特定情况,并且当一个故障发生时,它们还将标识特定情况。使用Pytest运行--collect-only将显示生成的ID。
10、使用直接测试参数化fixture
给定测试文件的结构为:
tests/
__init__.py
conftest.py
# content of tests/conftest.py
import pytest
@pytest.fixture
def username():
return 'username'
@pytest.fixture
def other_username(username):
return 'other-' + username
test_something.py
# content of tests/test_something.py
import pytest
@pytest.mark.parametrize('username', ['directly-overridden-username'])
def test_username(username):
assert username == 'directly-overridden-username'
@pytest.mark.parametrize('username', ['directly-overridden-username-other'])
def test_username_other(other_username):
assert other_username == 'other-directly-overridden-username-other'
11、使用非参数化的参数覆盖参数化fixture
给定测试文件的结构为:
tests/
__init__.py
conftest.py
# content of tests/conftest.py
import pytest
@pytest.fixture(params=['one', 'two', 'three'])
def parametrized_username(request):
return request.param
@pytest.fixture
def non_parametrized_username(request):
return 'username'
test_something.py
# content of tests/test_something.py
import pytest
@pytest.fixture
def parametrized_username():
return 'overridden-username'
@pytest.fixture(params=['one', 'two', 'three'])
def non_parametrized_username(request):
return request.param
def test_username(parametrized_username):
assert parametrized_username == 'overridden-username'
def test_parametrized_username(non_parametrized_username):
assert non_parametrized_username in ['one', 'two', 'three']
test_something_else.py
# content of tests/test_something_else.py
def test_username(parametrized_username):
assert parametrized_username in ['one', 'two', 'three']
def test_username(non_parametrized_username):
assert non_parametrized_username == 'username'
12、monkeypatch
简单的api获取例子
# contents of app.py, a simple API retrieval example
import requests
def get_json(url):
"""Takes a URL, and returns the JSON."""
r = requests.get(url)
return r.json()
此外,如果该模拟程序旨在应用于所有测试,则fixture可以将其移动到conftest.py文件中并使用with?autouse=True选项。
13、设置捕获方法或禁用捕获
有两种pytest执行捕获的方法:
- 文件描述符(FD)级别捕获(默认):将捕获对操作系统文件描述符1和2的所有写操作。
- sys级别捕获:仅写入Python文件,sys.stdout?并且sys.stderr将被捕获。不捕获对文件描述符的写入。
您可以从命令行影响输出捕获机制:
pytest -s # disable all capturing
pytest --capture=sys # replace sys.stdout/stderr with in-mem files
pytest --capture=fd # also point filedescriptors 1 and 2 to temp file
14、内部Pytest警告
(1)类PytestWarning
基类:UserWarning。
Pytest发出的所有警告的基类。
(2)类PytestAssertRewriteWarning
基类:PytestWarning。
Pytest断言重写模块发出的警告。
(3)类PytestCacheWarning
基地:PytestWarning。
缓存插件在各种情况下发出的警告。
(4)类PytestCollectionWarning
基类:PytestWarning。
Pytest无法在模块中收集文件或符号时发出警告。
(5)类PytestConfigWarning
基地:PytestWarning。
针对配置问题发出警告。
(6)类PytestDeprecationWarning
基类:Pytest.PytestWarning,DeprecationWarning。
在将来的版本中将删除的功能的警告类。
(7)类PytestExperimentalApiWarning
基类:Pytest.PytestWarning,FutureWarning。
警告类别,用于表示Pytest中的实验。请谨慎使用,因为API可能会更改,甚至在将来的版本中会完全删除。
(8)类PytestUnhandledCoroutineWarning
基类:PytestWarning。
当Pytest遇到作为协程的测试函数时发出警告,但任何异步感知插件均未处理该警告。本机不支持协程测试功能。
(9)类PytestUnknownMarkWarning
基类:PytestWarning。
使用未知标记会发出警告。
1)doctest
就像普通的一样conftest.py,fixtures是在目录树conftest中发现的。这意味着,如果将doctest与源代码一起放入,则相关的conftest.py需要位于同一目录树中。fixtures不会在同级目录树中发现!
2)跳过和xfail
一个xfail意味着你期望测试失败的某些原因。一个常见的示例是对尚未实现的功能或尚未修复的错误进行测试。如果尽管测试通过但预期会失败(标记为pytest.mark.xfail),则为xpass,并将在测试摘要中报告。
Pytest分别统计和列出跳过和xfail测试。默认情况下,不显示有关跳过/未通过测试的详细信息,以避免混乱输出。
pytest -rxXs # show extra info on xfailed, xpassed, and skipped tests
17、如何在不同情况下跳过模块中的测试的快速指南:
1)无条件跳过模块中的所有测试:
pytestmark = pytest.mark.skip("all tests still WIP")
2)根据某些条件跳过模块中的所有测试:
pytestmark = pytest.mark.skipif(sys.platform == "win32", reason="tests for linux only")
3)如果缺少某些导入,请跳过模块中的所有测试:
pexpect = pytest.importorskip("pexpect")
18、跨测试运行
该插件提供了两个命令行选项,以从上次Pytest调用重新运行失败:
- --lf,--last-failed-仅重新运行失败。
- --ff,--failed-first-先运行故障,然后测试的其余部分
最后一次运行没有测试失败,或者找不到缓存的lastfailed数据,
Pytest则可以使用以下--last-failed-no-failures选项之一将该选项配置为运行所有测试或不运行测试:
pytest --last-failed --last-failed-no-failures all # run all tests (default behavior)
pytest --last-failed --last-failed-no-failures none # run no tests and exit
19、Pytest支持unittest开箱即用地运行基于Python 的测试
到目前为止,Pytest不支持以下功能:
- load_tests协议 ;
- 子测试
1)具有在给定上下文中自动使用的fixture,@pytest.fixture(autouse=True)
2)xunit样式: 在每个模块/类/功能的基础上实现fixture
Module setup/teardown
def setup_module(module):
""" setup any state specific to the execution of the given module."""
def teardown_module(module):
""" teardown any state that was previously setup with a setup_module
method.
"""
Class setup/teardown
@classmethod
def setup_class(cls):
""" setup any state specific to the execution of the given class (which
usually contains tests).
"""
@classmethod
def teardown_class(cls):
""" teardown any state that was previously setup with a call to
setup_class.
"""
方法和功能的setup/teardown
def setup_method(self,method):
""" setup any state tied to the execution of the given method in a
class. setup_method is invoked for every test method of a class.
"""
def teardown_method(self,method):
""" teardown any state that was previously setup with a setup_method
call.
"""
def setup_function(function):
""" setup any state tied to the execution of the given function.
Invoked for every test function in the module.
"""
def teardown_function(function):
""" teardown any state that was previously setup with a setup_function call.
"""
3)工具启动时插件发现顺序
通常最好将conftest.py文件保存在顶级测试或项目根目录中。
20、典型setup.py摘录:
setup(..., entry_points={"pytest11": ["foo = pytest_foo.plugin"]}, ...)
21、通过名字来访问另一个插件
插件想要与另一个插件的代码协作,则可以通过插件管理器获取引用
plugin = config.pluginmanager.get_plugin("name_of_plugin")
22、Pytest API
23、caplog()
访问和控制日志捕获。
捕获的日志可通过以下属性/方法获得:
* caplog.messages -> list of format-interpolated log messages
* caplog.text -> string containing formatted log output
* caplog.records -> list of logging.LogRecord instances
* caplog.record_tuples -> list of (logger_name, level, message) tuples
* caplog.clear() -> clear captured records and formatted log output string
24、pip用于安装应用程序和所有依赖项以及Pytest程序包本身。这样可确保您的代码和依赖项与系统Python安装隔离。
25、Pytest.approx
26、失败的视频/屏幕截图Pytest-splinter、Pytest-bdd
27. 考虑以下文件和目录布局:
root/
|- foo/
|- __init__.py
|- conftest.py
|- bar/
|- __init__.py
|- tests/
|- __init__.py
|- test_foo.py
执行时会执行以下所有的目录文件
pytest root/
28、测试模块名称不能相同
29、从中找到rootdir的算法args:
- 确定指定的公共祖先目录,这些目录args被识别为文件系统中存在的路径。如果找不到此类路径,则将公共祖先目录设置为当前工作目录。
- 寻找Pytest.ini,tox.ini并setup.cfg在父目录和文件向上。如果匹配,它将成为ini文件,并且其目录将成为rootdir。
- 如果未找到ini文件,请setup.py从公共祖先目录向上查找以确定rootdir。
- 如果没有setup.py被发现,寻找Pytest.ini,tox.ini并?setup.cfg在每个指定args向上。如果匹配,它将成为ini文件,并且其目录将成为rootdir。
- 如果找不到ini文件,则使用已经确定的公共祖先作为根目录。这允许在不属于包且没有任何特定ini文件配置的结构中使用Pytest。
二、Pytest 实际运用
命令行中执行
pip install pytest
pip show pytest
想要在 Pycharm 环境中测试用例以 Pytest 形式运行,可以这样设置。
Settings->Tools->Python Integreated Tools,选择默认的 test runner 为“py.test”。
Pytest 生成 html 报告,命令行中安装 Pytest-html 插件。
pip install pytest-html
cmd 中执行 >pytest test_***.py --html=./testreport.html
在报告存放路径下,可以用 Chrome 浏览器打开本地 html 链接,如
file:///E:/ATS/Test_doctor/testreport.html。
Pytest 测试报告形式如下所示
Pytest 失败重跑机制。在 UI 自动化测试中,由于受到网络不稳定、appium server 等影响,不是每次正确的测试用例都能运行通过,于是使用 Pytest 的失败重跑提高自动化测试的稳定性。安装插件 Pytest-rerunsfailures,在命令行执行
pip install pytest-rerunsfailures
>pytest test_patlist.py --reruns 3 --html=./report.html
实现对测试用例重跑 3 次,3 次不通过才算失败,反之则运行成功。
实践得到,Pytest 不需要创建类,直接定义函数即可。
Pytest 和 unittest 最大的区别是不要求我们必须创建测试类, 自己创建的测试类也不需要继承于 unittest.TestCase 类。但是 Pytest 要求我们创建的测试文件,测试类、方法、测试函数必须以“test”开头,Pytest 默认按照这个规则查找测试用例并执行它们。”
三、Pytest 避开的坑
1)PytestUnknownMarkWarning
解决方案:
① 若是单个标签
在 conftest.py 添加如下代码,直接拷贝过去,把标签名改成你自己的就行了
def pytest_configure(config):
config.addinivalue_line(
"markers", "login_success" # login_success 是标签名
)
② 若是多个标签
在 conftest.py 添加如下代码,直接拷贝过去,把标签名改成你自己的就行了
def pytest_configure(config):
marker_list = ["testmark1","testmark2","testmark3"] # 标签名集合
for markers in marker_list:
config.addinivalue_line(
"markers", markers
)
这样添加之后,再次运行,不再出现 warning。
2)UnicodeDecodeError: 'gbk' codec can't decode byte 0xae in position 42: illegal multibyte sequence
import pytest
@pytest.mark.parametrize("test_input,expected",[("3+5",8),("2+4",6),("6*9",42)])
def test_eval(test_input,expected):
assert eval(test_input) == expected
解决办法:这个跟编码有关,代码目录中有个 Pytest.ini 文件,内容是这样:
[pytest]
doctest_encoding = UTF-8 #默认编码是 UTF-8
删除 Pytest.ini 文件之后,再次运行就可以了。
3)Pytest 执行用例时 collected 0 items
Pytest 执行的文件需要以 test 开头才能被查找到。
4)断言 assert
断言元素是否存在,例如
element = appdriver.find_element_by_id('icon_id')
assert element
我是谁?
我是一名从事了多年软件测试的老测试员,今年年初我花了一个月整理了一份最适合2020年学习的软件测试学习干货,可以送给每一位对软件测试感兴趣的小伙伴,想要获取的可以关注我的头条号并在后台私信我:【测试】,即可免费获取。
相关推荐
- 滨州维修服务部“一区一策”强服务
-
今年以来,胜利油田地面工程维修中心滨州维修服务部探索实施“一区一策”服务模式,持续拓展新技术应用场景,以优质的服务、先进的技术,助力解决管理区各类维修难题。服务部坚持问题导向,常态化对服务范围内的13...
- 谷歌A2A协议和MCP协议有什么区别?A2A和MCP的差异是什么?
-
在人工智能的快速发展中,如何实现AI模型与外部系统的高效协作成为关键问题。谷歌主导的A2A协议(Agent-to-AgentProtocol)和Anthropic公司提出的MCP协议(ModelC...
- 谷歌大脑用架构搜索发现更好的特征金字塔结构,超越Mask-RCNN等
-
【新智元导读】谷歌大脑的研究人员发表最新成果,他们采用神经结构搜索发现了一种新的特征金字塔结构NAS-FPN,可实现比MaskR-CNN、FPN、SSD更快更好的目标检测。目前用于目标检测的最先...
- 一文彻底搞懂谷歌的Agent2Agent(A2A)协议
-
前段时间,相信大家都被谷歌发布的Agent2Agent开源协议刷屏了,简称A2A。谷歌官方也表示,A2A是在MCP之后的补充,也就是MCP可以强化大模型/Agent的能力,但每个大模型/Agent互为...
- 谷歌提出创新神经记忆架构,突破Transformer长上下文限制
-
让AI模型拥有人类的记忆能力一直是学界关注的重要课题。传统的深度学习模型虽然在许多任务上取得了显著成效,但在处理需要长期记忆的任务时往往力不从心。就像人类可以轻松记住数天前看过的文章重点,但目前的...
- 不懂设计?AI助力,人人都能成为UI设计师!
-
最近公司UI资源十分紧张,急需要通过AI来解决UI人员不足问题,我在网上发现了几款AI应用非常适合用来进行UI设计。以下是一些目前非常流行且功能强大的工具,它们能够提高UI设计效率,并帮助设计师创造出...
- 速来!手把手教你用AI完成UI界面设计
-
晨星技术说晨星技术小课堂第二季谭同学-联想晨星用户体验设计师-【晨星小课堂】讲师通过简单、清晰的语言描述就能够用几十秒自动生成一组可编辑的UI界面,AIGC对于UI设计师而言已经逐步发展成了帮助我们...
- 「分享」一端录制,多端使用的便捷 UI 自动化测试工具,开源
-
一、项目介绍Recorder是一款UI录制和回归测试工具,用于录制浏览器页面UI的操作。通过UIRecorder的录制功能,可以在自测的同时,完成测试过程的录制,生成JavaScr...
- APP自动化测试系列之Appium介绍及运行原理
-
在面试APP自动化时,有的面试官可能会问Appium的运行原理,以下介绍Appium运行原理。Appium介绍Appium概念Appium是一个开源测试自动化框架,可用于原生,混合和移动Web应用程序...
- 【推荐】一个基于 SpringBoot 框架开发的 OA 办公自动化系统
-
如果您对源码&技术感兴趣,请点赞+收藏+转发+关注,大家的支持是我分享最大的动力!!!项目介绍oasys是一个基于springboot框架开发的OA办公自动化系统,旨在提高组织的日常运作和管理...
- 自动化实践之:从UI到接口,Playwright给你全包了!
-
作者:京东保险宋阳1背景在车险系统中,对接保司的数量众多。每当系统有新功能迭代后,基本上各个保司的报价流程都需要进行回归测试。由于保司数量多,回归测试的场景也会变得重复而繁琐,给测试团队带来了巨大的...
- 销帮帮CRM移动端UI自动化测试实践:Playwright的落地与应用
-
实施背景销帮帮自2015年成立以来,移动端UI自动化测试的落地举步维艰,移动端的UI自动化测试一直以来都未取得良好的落地。然而移动互联网时代,怎样落地移动端的UI自动化测试以快速稳定进行移动端的端到端...
- 编写自动化框架不知道该如何记录日志吗?3个方法打包呈现给你。
-
目录结构1.loguru介绍1.1什么是日志?程序运行过程中,难免会遇到各种报错。如果这种报错是在本地发现的,你还可以进行debug。但是如果程序已经上线了,你就不能使用debug方式了...
- 聊聊Python自动化脚本部署服务器全流程(详细)
-
来源:AirPython作者:星安果1.前言大家好,我是安果!日常编写的Python自动化程序,如果在本地运行稳定后,就可以考虑将它部署到服务器,结合定时任务完全解放双手但是,由于自动化程序与平...
- 「干货分享」推荐5个可以让你事半功倍的Python自动化脚本
-
作者:俊欣来源:关于数据分析与可视化相信大家都听说自动化流水线、自动化办公等专业术语,在尽量少的人工干预的情况下,机器就可以根据固定的程序指令来完成任务,大大提高了工作效率。今天小编来为大家介绍几个P...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- MVC框架 (46)
- spring框架 (46)
- 框架图 (58)
- flask框架 (53)
- quartz框架 (51)
- abp框架 (47)
- jpa框架 (47)
- springmvc框架 (49)
- 分布式事务框架 (65)
- scrapy框架 (56)
- shiro框架 (61)
- 定时任务框架 (56)
- java日志框架 (61)
- JAVA集合框架 (47)
- mfc框架 (52)
- abb框架断路器 (48)
- ui自动化框架 (47)
- grpc框架 (55)
- ppt框架 (48)
- 内联框架 (52)
- cad怎么画框架 (58)
- ps怎么画框架 (47)
- ssm框架实现登录注册 (49)
- oracle字符串长度 (48)
- oracle提交事务 (47)