本节我们介绍基于 Python 的自动化测试框架 —— Pytest。无论你是做接口测试、车载自动化测试,还是业务回归、复杂测试体系建设,Pytest 都是一个值得掌握的利器。此外,Pytest 拥有丰富的生态支持:与 Requests 结合可实现 API 接口自动化测试;与 Selenium 结合可实现 Web 端自动化测试;与 Allure 结合可生成美观、清晰的测试报告;与 Jenkins 结合可接入持续集成流水线,实现自动化回归。如何让 pytest 自动找到你的测试用例?命名在其中扮演了重要的角色,其中测试模块需以test_开头或者_test结尾;测试类需以Test开头,并且不能包含__init__方法,测试方法/函数需以test_开头。遵循以上规则,执行pytest命令即可自动发现并执行测试用例。
##模块名:test_calculator.pyimport pytestclass TestCalculator: """测试计算器功能""" def test_add(self): """测试加法""" assert 2+2==4 def test_subtract(self): """测试减法""" assert 4-2==2def test_multiply(): assert 2*3==6def test_divide(): assert 6/3==2#命令行终端输入:pytest -vs ./test_calculator.py即可运行
注意:pytest 自动化框架中提供了多个便捷的运行参数,方便不同场景下的测试执行,如[-v]可用于显示详细的信息(每个测试用例的名称及结果);[-s]可用于输出调试信息(如代码中print()打印的信息);
##模块名:test_calculator.pyimport pytestclass TestCalculator: """测试计算器功能""" def test_add(self): """测试加法""" assert 2+2==4 def test_subtract(self): """测试减法""" assert 4-2==2def test_multiply(): assert 2*3==6def test_divide(): assert 6/3==2#命令行终端输入:pytest -vs ./test_calculator.py即可运行
在终端中直接输入pytest命令并加上对应的参数,是最常用及最灵活的运行方式。该运行方式自动发现当前目录及子目录下所有符合命名规则的测试文件,并执行所有对应的测试用例。其中[.]表示该用例测试通过,[F]表示测试失败,[E]表示错误,[S]表示跳过。##执行指定文件pytest -vs ./test_calculator.py##只执行test_calculator.py中的测试用例
##执行指定目录pytest -vs ./##执行当前目录下所有测试文件
##执行指定的函数pytest -vs ./test_calculator.py::test_multiply##执行指定类中的指定函数 pytest -vs ./test_calculator.py::TestCalculator::test_add
除了上面介绍的[v][s]外,还有一些其他的参数,掌握他们能让我们的调试事半功倍。[-q]pytest -q ./test_calculator.py#简化输出,只显示整体结果,不显示每个用例的详细信息 [-k]pytest -vk "sub or add"#根据测试名称(文件名、类名、函数名)中的关键字来选择要执行的用例 [-m]pytest -vm smoke#可以结合标记(如@pytest.mark.smoke)进行针对性测试,但是自定义的标记需在pytest.ini中进行声明,否则运行时会上报警告信息[-x]pytest -vx ./test_calculator.py#遇到第一个失败用例后,立即停止执行,不再运行后续测试[--maxfail=n]pytest -v --maxfail=2 ./test_calculator.py#当失败用例数达到2次后,程序停止运行 [--lf]pytest --lf #只运行上次失败的测试用例[--ff]pytest --ff#优先执行上次失败的测试用例,之后再执行完其余测试用例 [-n]pytest -v -n 2 ./test_calculator.py#多线程或分布式运行测试用例 [--reruns=2]pytest -v --reruns=2 ./test_calculator.py#用于设置失败用例的重跑次数,但是需要安装插件pip install pytest-rerunfailures
主函数运行方式的控制参数和命令行运行方式是一致的,只是运行的方式不同,下面给出常用参数的运行代码。####模块名称run.pyimport pytestif __name__=="__main__": pytest.main(['-s','-v','./test_calculator.py']) pytest.main(['-v','-k', 'add', './test_calculator.py'])
pytest.ini是Pytest的主配置文件,一般放在项目的根目录下。在执行测试用例时会自动读取该文件中的配置。[pytest]addopts= -vs --alluredir ./report/tmp -p no:warnings --clean-alluredirtestpaths=./test_calculator.pyfilterwarnings= error ignore::UserWarningpython_files=test_*.pypython_classes = Test*python_functions= test_markers = P0:极高
上述的.ini文件中定义了运行pytest时的控制参数及规则,如使用allure报告、指定测试目录、声明自定义标记;[addopts]中指定了控制参数为-vs、指定allure报告数据的输出目录为./report/tmp以及执行前清空allure报告目录(--clean-alluredir),避免残留数据;[testpaths]中指定了pytest搜索测试用例的根目录;[filterwarnings]主要用于控制警告的处理方式,上述定义了将所有警告视为错误(出现警告即测试失败),但忽略UserWarning类型的警告;[python_files][python_classes][python_functions]指定了那些文件可以被识别为测试文件、那些类可以被识别为测试类、那些函数/方法可以被识别为测试用例。[markers]声明了自定义的标记,但要在测试方法前加入对应的装饰器内容(如@pytest.mark.P0)。# 直接执行(自动使用 addopts 中的所有参数)pytest# 只执行 P0 级别测试pytest -m P0# 执行指定文件(仍然会应用 addopts 参数)pytest ./test_calculator.py
pytest支持分组测试,如车载测试中极高优先级的冒烟测试、回归测试及全量测试。分组测试的本质就是给测试函数打上不同的“标签”,执行时按照标签进行筛选。实现方式可总结为如下三步:1)测试用例方法前加上分组模块的标记(自定义的标记需要在.ini文件中进行声明);2).ini文件中加上参数(markers);3)使用[pytest -m 标签名]命令执行。示例如下:##模块名:test_calculator.pyimport pytestimport timeclass TestCalculator: """测试计算器功能""" def test_add(self): """测试加法""" time.sleep(2) assert 2+2==4 def test_subtract(self): """测试减法""" time.sleep(2) assert 4-2==2@pytest.mark.P0def test_multiply(): time.sleep(2) assert 2*3==6def test_divide(): time.sleep(2) assert 6/3==3
import pytestif __name__=="__main__": pytest.main(['-v','-s','-m','P0'])
本文简要介绍了 pytest 的命名规则、三种运行方式及分组执行机制。后续将继续介绍用例跳过、前后置处理等相关用法,并在此基础上,利用 Python 模拟 ECU 的应答机制,与 pytest 相互结合形成自动化测试闭环,进一步夯实此前所学知识。