python自动化框架pytest(一)
本文介绍pytest简介,pytest安装,pytest的使用(命令),pytest实现前置及后置步骤
下一篇介绍ptest的fixture 的详细用法
一、pytest简介
pytest是python的一种单元测试框架,与python自带的unittest测试框架类似,但是比unittest框架使用起来更简洁,效率更高。pytest是一个成熟的全功能的Python测试工具,可以帮助你写出更好的程序,让我们很方便的编写测试用例。适合从简单的单元到复杂的功能测试。有很多的第三方插件可以自定义扩展,并且支持allure。
pytest有以下特点:
- 简单灵活,容易上手
- 支持参数化
- 能够支持简单的单元测试和复杂的功能测试,还可以用来做selenium/appnium等自动- - 化测试、接口自动化测试(pytest+requests)
- pytest具有很多第三方插件,并且可以自定义扩展,比较好用的如pytest-selenium(集成selenium)、pytest-html(完美html测试报告生成)、pytest-rerunfailures(失败case重复执行)、pytest-xdist(多CPU分发)等
- 测试用例的skip和xfail处理
- 可以很好的和jenkins集成
- report框架----allure 也支持了pytest
二、pytest安装
pip命令安装
pip install -U pytest
安装后验证
C:\Users\93439>pytest --version
This is pytest version 5.4.3, imported from e:\liang\tools\python3.7.2\lib\site-packages\pytest\__init__.py
pytest文档
官方文档:https://docs.pytest.org/en/latest/contents.html
在pytest框架中,有如下约束:
文件名以test_*.py文件和*_test.py
以test_开头的函数
以Test开头的类
此时,在执行pytest命令时,会自动从当前目录及子目录中寻找符合上述约束的测试函数来执行。
三、pytest使用
1、 Pytest执行测试用例
测试用例
# @File : test_abc.py
import pytest # 引入pytest包
def test_a(): # test开头的测试函数
print("------->test_a")
assert 1 # 断言成功
def test_b():
print("------->test_b")
assert 0 # 断言失败
if __name__ == '__main__':
pytest.main(["-s", "test_abc.py"]) # 调用pytest的main函数执行测试
2、常用pytest命令
2.1 Pytest -v或 Pytest -vv 显示具体的详情信息,一般显示错误的位置及错误的详细信息
2.2 Pytest --collect-only 收集可执行的案例
2.3 Pytest -k 案例名称 表示运行指定的案例,例如 pytest -k “_002” 表示指定运行含有002案例的测试案例
- 在test_file01文件中命名为test_001() 在test_file02文件中命名为test_two_001() ,运行的时候编辑命令 pytest -k “_001” 所以它会运行相关名称下的案例
2.4 Pytest -s 等价于 pytest --capture=no 可以捕获print函数的输出
2.5 pytest --last-failed 等价于pytest --lf 只重新运行上次运行失败的用例(或如果没有失败的话会全部跑)
2.6 Pytest --ff 等价于 pytest --failed-first 运行所有测试,但首先运行上次运行失败的测试
2.7 pytest -q等价于Pytest --quiet 可以简化输出信息,与pytest -v对应
2.8 Pytest -m 用户标记名称 该命令的用法是在测试案例前使用 @pytest.mark.mytest 这个mytest就是我自己定义的名称,使用命令时则:pytest -m mytest即可,main函数写法pytest.main(["-s", "test_001.py","-m=mytest"]),标记执行非指定方法 pytest.main(['-s','文件名','-m=not 标记名'])
2.9 pytest -x等价于pytest --exitfirst,表示在debug过程中遇到一个fail的案例就停止运行后续的案例
2.10 pytest --maxfail=num 其中num表示运行失败案例的个数,假设,5个案例中1个是失败的,则使用pytest --maxfail=1 则运行到一个失败的案例则后续都不用执行,此时你把值改为2,则会继续运行后续的案例,该命令的意思:允许你案例中,fail案例的个数上限(这个值是大于等于则就会触发)
2.11 运行模块中的指定方法 pytest test_mod.py::TestClass::test_method
main函数写法pytest.main(["-s", "test_mod.py::TestClass::test_method"])
2.12 失败重试
在做接口测试时,有事会遇到503或短时的网络波动,导致case运行失败,而这并非是我们期望的结果,此时可以就可以通过重试运行cases的方式来解决。
安装pytest-rerunfailures:
pip install -U pytest-rerunfailures
命令行:pytest test_se.py --reruns NUM
main函数写法pytest.main(["-s", "test_001.py","-m=mytest","--reruns=2"])
2.13 多进程运行cases
当cases量很多时,运行时间也会变的很长,如果想缩短脚本运行的时长,就可以用多进程来运行。
安装pytest-xdist:
pip install -U pytest-xdist
运行模式:
pytest test_001.py -n NUM 其中NUM填写并发的进程数,
main函数写法pytest.main(["-s", "test_001.py","-n=auto"]),-n=auto根据cpu核心数选择进程数
2.14 Pytest测试报告
pytest-HTML是一个插件,pytest用于生成测试结果的HTML报告。
安装方式:pip install pytest-html
pytest test_001.py --html=report\test_001.html
main函数写法pytest.main(["-s", "test_001.py","--html=report\test_001.html"]),其中report\test_001.html为要保存的测试报告路径和文件名
3、pytest的setup和teardown函数
3.1 函数级别setup()/teardown()
运行于测试方法的始末,即:运行一次测试函数会运行一次setup和teardown
# file_name: test_002.py
import pytest
class Test_Case:
def setup(self):
print("------->setup_method")
def teardown(self):
print("------->teardown_method")
def test_0001(self): # test开头的测试函数
print("------->test_0001")
assert 1 # 断言成功
def test_0002(self):
print("------->test_0002")
assert 0 # 断言失败
if __name__ == '__main__':
pytest.main(["-s", "test_002.py"])
执行结果
test_002.py ------->setup_method
------->test_0001
.------->teardown_method
------->setup_method
------->test_0002
F------->teardown_method
可以看出,每个用例执行前都先执行了setup方法,每个用例执行后都执行了teardonw方法。
3.2 类级别setup_class()/teardown_class()
运行于测试类的始末,即:在一个测试类内只运行一次setup_class和teardown_class,不关心测试类内有多少个测试函数。
代码示例:
# file_name: test_002.py
import pytest
class Test_Case:
def setup_class(self):
print("------->setup_method")
def teardown_class(self):
print("------->teardown_method")
def test_0001(self): # test开头的测试函数
print("------->test_0001")
assert 1 # 断言成功
def test_0002(self):
print("------->test_0002")
assert 0 # 断言失败
if __name__ == '__main__':
pytest.main(["-s", "test_002.py"])
输出结果:
test_002.py ------->setup_method
------->test_0001
.------->test_0002
F------->teardown_method
4、pytest的断言
assert xx:判断xx为真
assert not xx:判断xx不为真
assert a in b:判断b包含a
assert a == b:判断a等于b
assert a !=b:判断a不等于b