pytest单元测试框架中可以使用命令行
及代码pytest.main()
两种方式执行测试,且可以加入各种参数来组织执行测试。接下来我们来了解常用的执行参数的含义及其用法。
pytest中的执行参数根据作用的不同大致可以分为以下几类:
- 指定测试用例
- 控制执行过程
- 结果展示
每个示例都会以pytest.main()形式
及命令行形式
两种方式进行说明。
指定测试用例
运行指定路径的测试用例
# 运行当前文件所在的同级目录中,testcase文件夹里的所有测试用例
pytest.main(["./testcase"])
# 也可以写成如下形式。后续示例中都将`./`省略
pytest.main(["testcase"])
# 命令行形式
pytest
# 运行指定模块
pytest.main(["testcase/test_case.py"])
# 命令行形式
pytest testcase/test_case.py
# 运行指定模块中的测试类
pytest.main(["testcase/test_case.py::TestOrder"])
# 命令行形式
pytest testcase/test_case_1.py::TestOrder
# 运行指定类中的测试方法
pytest.main(["testcase/test_case.py::TestOrder::test_order"])
# 命令行形式
pytest testcase/test_case.py::TestOrder::test_order
-m
运行指定标记的测试用例
我们之前已经讲过怎么标记用例,可以查看[]
# 运行被标记为smoke的用例
pytest.main(['-m smoke'])
# 命令行形式
pytest -m smoke
# 运行被标记为smoke或order的用例
pytest.main(["-m", "smoke or order"])
# 命令行形式
pytest -m "smoke or order"
-k
运行匹配指定字符串的测试用例
-k
指定字符串,用于匹配包名、模块名、类名、测试函数名/方法名,这些命名中包含指定的字符串则匹配并执行。
# 运行包名、模块名、类名、测试函数名/方法名中包含order的测试用例
pytest.main(["-k", "order"])
# 命令行形式
pytest -k order
# 运行指定模块中的类名、测试函数名/方法名中包含order的测试用例
pytest.main(["-k", "order", "testcase/test_case.py"])
# 命令行形式
pytest -k login testcase/test_case.py
# 运行指定类中测试函数名包含order的测试用例
pytest.main(["-k", "order", "testcase/test_case.py::TestOrder"])
# 命令行形式
pytest -k order testcase/test_case.py::TestOrder
控制执行过程
用例失败重新执行次数
用例执行时有可能会出现某些偶然因素导致用例断言失败但实际又不是bug的情况,如网络波动导致响应时间慢,此时用例失败后再次去重新执行该用例就显得很重要。
pytest提供了一个常用的插件pytest-rerunfailures
,用于设置测试用例运行失败后的最多重新执行次数(即重试机制)。
使用之前需要先安装:pip install pytest-rerunfailures
,使用方式如下:
# 运行失败后该用例重新运行最多3次
pytest.main(["--reruns", "3", "testcase/test_case.py"])
# 命令行形式
pytest --reruns=3 testcase/test_case.py
用例执行失败则停止运行
根据需求提供一下两种方式:
-
-x
或--exitfirst
,遇到用例执行失败就停止项目的运行,只要失败就立即停止运行 -
--maxfail=num
,遇到多少次用例执行失败就停止项目运行,num
表示用例运行失败次数
# -x,遇到执行用例失败则停止整个项目的运行
pytest.main(["-x", "testcase/test_case.py"])
# 命令行形式
pytest -x testcase/test_case.py
# --maxfail,如累计有5次用例执行失败则停止整个项目的运行
pytest.main(["--maxfail", "5", "testcase/test_case.py"])
# 命令行形式
pytest --maxfail=5 testcase/test_case.py
运行上次失败用例
当bug修复完成后,我们可能只需要去执行上次运行失败的用例,在pytest中就提供了这样的功能,需要用到一下参数:
-
--lf
或--last-failed
,只执行上次运行失败的用例,若上次运行没有失败用例则会执行全部用例。 -
--ff
或--failed-first
,首先执行上次运行失败的用例,再执行项目中其他所有用例。
# --lf,只执行上次运行失败的用例,若上次运行没有失败用例则会执行全部用例
pytest.main(["--lf", "testcase/test_case.py"])
# 命令行形式
pytest --lf testcase/test_case.py
# --ff,首先执行上次运行失败的用例,再执行项目中其他所有用例
pytest.main(["--ff", "testcase/test_case.py"])
# 命令行形式
pytest --ff testcase/test_case.py
执行结果展示
与展示结果相关的常用的参数有以下几个:
-
-s
,在测试结果中显示测试用例里print的内容(执行结果默认不显示测试用例中print的内容)。 -
-v
,显示更详细的测试结果。 -
-q
,展示简略的测试结果,与-v
作用刚好相反。
# -s,测试结果中显示测试用例里print的内容
pytest.main(["-s", "testcase/test_case.py"])
# 命令行形式
pytest -s testcase/test_case.py
# -v,设置测试结果显示的详细程度
pytest.main(["-v", "testcase/test_case.py"])
# 命令行形式
pytest -v testcase/test_case.py
# -q,设置测试结果显示的详细程度
pytest.main(["-q", "testcase/test_case.py"])
# 命令行形式
pytest -q testcase/test_case.py
示例
测试用例写在testcase/test_case.py
中,项目执行代码写在与testcase
同级目录的run.py
中,简单示例如下:
test_case.py
:
def test_01():
print("执行test_01")
a = "hello"
b = "hi"
assert a != b
def test_02():
print("执行test_02")
a = "hello"
b = "hi"
assert a == b
class TestOrder:
def test_order(self):
print("下单")
run.py
:
import pytest
if __name__ == '__main__':
pytest.main(["-s", "-v", "--reruns", "2", "testcase/test_case.py"])
运行run.py
或命令行pytest -s -v --reruns=2 testcase/test_case.py
,结果如下:
我们可以看出来:
- 因为
-s
,结果中打印了测试用例中print
里面的内容。 - 因为
-v
,显示了较为详细的测试结果(不加-v
则只显示执行的测试模块,不显示测试用例而是用.
表示)。 - 因为
--reruns
2
,因为test_02
的断言始终是失败的,所以失败后又执行了2
次,总共执行了3
次。
总结
这里只列举了一些常用的运行方法与参数,大家可以在自己的自动化项目中尝试着使用这些方式与参数。