一、mark标记
1、介绍
Pytest提供的mark标记,允许我们标记测试函数,测试类和整个模块。通过不同的标记实现不同的运行策略,如标记冒烟测试用例。
2、特点
使用装饰器@pytest.mark.markname标记测试函数,测试类。使用pytestmark标记整个模块。一个mark可以标记多个测试函数,一个测试函数可以使用多个mark。有多个mark标记的时候,最接近测试函数的标记将首先迭代。运行没有注册的标记,会出现warning警告,解决办法是先注册标记,在使用标记。可以在pytest.ini文件注册自定义标记。当使用--strict-markers命令行参数的时候,运行未在pytest.ini文件中注册的任何标记都将引发异常。pytest --markers 可以查看所有的mark标签,包括内置标记和自定义标记。
二、内置标记
1、skip - 无条件跳过测试用例
语法糖:
pytest.mark.skip(reason=None)
reason:str类型,默认值为None,可以添加跳过测试用例原因的描述信息。
新建 test_skip.py 如下:
import pytest
@pytest.mark.skip()
def test_one():
pass
def test_two():
pass
运行命令:pytest -v test_skip.py
(venv) C:\Users\057776\PycharmProjects\pytest-demo\testmark>pytest -v test_skip.py =================================== test session starts =================================== platform win32 -- Python 3.8.8, pytest-6.2.3, py-1.10.0, pluggy-0.13.1 -- e:\programs\python\python38\python.exe cachedir: .pytest_cache metadata: {'Python': '3.8.8', 'Platform': 'Windows-10-10.0.19041-SP0', 'Packages': {'pytest': '6.2.3', 'py': '1.10.0', 'pluggy': '0.13.1'}, 'Plugins': {'html': '3.1. 1', 'metadata': '1.11.0', 'rerunfailures': '9.1.1', 'assume': '2.2.0', 'requests-mock': '1.7.0'}, 'JAVA_HOME': 'C:\\Program Files\\Java\\jdk1.8.0_271'} rootdir: C:\Users\057776\PycharmProjects\pytest-demo\testmark, configfile: pytest.ini plugins: html-3.1.1, metadata-1.11.0, rerunfailures-9.1.1, assume-2.2.0, requests-mock-1.7.0 collected 2 items
test_skip.py::test_one SKIPPED (unconditional skip) [ 50%] test_skip.py::test_two PASSED [100%]
============================== 1 passed, 1 skipped in 0.06s ==============================
(venv) C:\Users\057776\PycharmProjects\pytest-demo\testmark>
说明:
pytest运行的时候收集到了2条测试用例,跳过了skip标记的测试用例test_one。
2、skipif - 如果条件为真,则跳过测试用例
语法糖:
pytest.mark.skipif(condition, *, reason=None)
condition,条件,可以为True,False或者条件字符串;条件为真,则标记起作用;条件为假,则标记不起作用;使用condition参数的时候,必须有参数reason,否则会报错ERROR。reason:str类型,默认值为None,可以添加跳过测试用例原因的描述信息。
修改test_skip.py 如下:
import pytest
@pytest.mark.skip(reason="no way of currently testing this")
def test_one():
pass
@pytest.mark.skipif(condition=True, reason='条件为真,则跳过测试用例test_two')
def test_two():
pass
@pytest.mark.skipif(condition=False, reason='条件为假,则不会跳过测试用例test_three')
def test_three():
pass
def test_four():
pass
运行命令:pytest -v test_skip.py
Microsoft Windows [版本 10.0.19044.1826] (c) Microsoft Corporation。保留所有权利。
(venv) C:\Users\057776\PycharmProjects\pytest-demo\testmark>pytest -v test_skip.py ==================================== test session starts ==================================== platform win32 -- Python 3.8.8, pytest-6.2.3, py-1.10.0, pluggy-0.13.1 -- e:\programs\python\python38\python.exe cachedir: .pytest_cache metadata: {'Python': '3.8.8', 'Platform': 'Windows-10-10.0.19041-SP0', 'Packages': {'pytest': '6.2.3', 'py': '1.10.0', 'pluggy': '0.13.1'}, 'Plugins': {'html': '3.1. 1', 'metadata': '1.11.0', 'rerunfailures': '9.1.1', 'assume': '2.2.0', 'requests-mock': '1.7.0'}, 'JAVA_HOME': 'C:\\Program Files\\Java\\jdk1.8.0_271'} rootdir: C:\Users\057776\PycharmProjects\pytest-demo\testmark, configfile: pytest.ini plugins: html-3.1.1, metadata-1.11.0, rerunfailures-9.1.1, assume-2.2.0, requests-mock-1.7.0 collected 4 items
test_skip.py::test_one SKIPPED (no way of currently testing this) [ 25%] test_skip.py::test_two SKIPPED (条件为真,则跳过测试用例test_two) [ 50%] test_skip.py::test_three PASSED [ 75%] test_skip.py::test_four PASSED [100%]
=============================== 2 passed, 2 skipped in 0.05s ===============================
(venv) C:\Users\057776\PycharmProjects\pytest-demo\testmark>
说明:
条件为真,则跳过测试用例。条件为假,则执行测试用例。
3、xfail - 将测试用例标记为预期失败。
语法糖:
pytest.mark.xfail(condition=None, *, reason=None, raises=None, run=True, strict=False)
XFAIL,预期失败的测试用例,实际结果执行失败,预期结果和实际结果一致。XPASS,预期失败的测试用例,实际结果执行成功,预期结果和实际结果不一致。pytest.xfail 方法在用例执行过程中直接标记用例结果为XFAIL,不会执行后面的代码。condition,条件,默认值为None,可以为True,False或者条件字符串;条件为真,则标记起作用。条件为假,则标记不起作用;使用参数condition的时候,必须有参数reason,否则会报错ERROR。reason,str类型,默认值为None,可以添加预期失败原因的描述信息。raises,异常类型,默认值为None,可以是单个异常,也可以是多个异常组成的元组;如果测试用例执行失败,出现的异常类型在raises里,则不会抛出异常,测试用例标记为XFAIL;如果测试用例执行失败,出现raises之外的异常,则测试用例标记为FAILED,并抛出异常信息。run,布尔型,默认值为True;当run=False时候,直接将测试用例标记为XFAIL,不需要执行测试用例。strict,默认值为False;当strict=False时,如果用例执行失败,结果标记为XFAIL,表示符合预期的失败;如果用例执行成功,结果标记为XPASS,表示不符合预期的成功;当strict=True时,如果用例执行成功,结果将标记为FAILED,而不再是XPASS了;可以在pytest.ini文件中配置:xfail_strict=true。
新建 test_xfail.py 文件如下:
import pytest
@pytest.mark.xfail
def test_one():
"""
XFAIL,预期失败的测试用例,实际结果执行失败,预期结果和实际结果一致。
"""
assert 1 == 2
@pytest.mark.xfail
def test_two():
"""
XPASS,预期失败的测试用例,实际结果执行成功,预期结果和实际结果不一致。
"""
assert 1 == 1
def test_three():
"""
pytest.xfail方法在用例执行过程中直接标记用例结果为XFAIL,不会执行后面的代码。
"""
pytest.xfail(reason='pytest.xfail方法在用例执行过程中直接标记用例结果为XFAIL,不会执行后面的代码')
assert 1 == 2
@pytest.mark.xfail(condition=True, reason='条件为真,预期失败的测试用例')
def test_four():
"""
condition,条件参数,默认值为None,可以为True,False或者条件字符串;
条件为真,则标记起作用。条件为假,则标记不起作用;
使用参数condition的时候,必须有参数reason,否则会报错ERROR。
reason,str类型,默认值为None,可以添加预期失败原因的描述信息。
"""
pass
class TestException:
"""
raises,异常类型参数,默认值为None,可以是单个异常,也可以是多个异常组成的元组;
如果测试用例执行失败,出现的异常类型在raises里,则不会抛出异常,测试用例标记为XFAIL;
如果测试用例执行失败,出现raises之外的异常,则测试用例标记为FAILED,并抛出异常信息。
"""
@pytest.mark.xfail(raises=AssertionError)
def test_five(self):
assert 1 == 2
@pytest.mark.xfail(raises=AssertionError)
def test_six(self):
print(1 / 0)
@pytest.mark.xfail(run=False)
def test_seven():
"""
run,布尔型参数,默认值为True;
当run=False时候,直接将测试用例标记为XFAIL,不需要执行测试用例。
"""
pass
@pytest.mark.xfail(strict=True)
def test_eight():
"""
strict,关键字参数,默认值为False;
当strict=False时,如果用例执行失败,结果标记为XFAIL,表示符合预期的失败;如果用例执行成功,结果标记为XPASS,表示不符合预期的成功;
当strict=True时,如果用例执行成功,结果将标记为FAILED,而不再是XPASS了;
可以在pytest.ini文件中配置:xfail_strict=true。
"""
pass
运行命令:pytest test_xfail.py -v
Microsoft Windows [版本 10.0.19044.1826] (c) Microsoft Corporation。保留所有权利。
(venv) C:\Users\057776\PycharmProjects\pytest-demo\testmark>pytest test_xfail.py -v =================================== test session starts =================================== platform win32 -- Python 3.8.8, pytest-6.2.3, py-1.10.0, pluggy-0.13.1 -- e:\programs\python\python38\python.exe cachedir: .pytest_cache metadata: {'Python': '3.8.8', 'Platform': 'Windows-10-10.0.19041-SP0', 'Packages': {'pytest': '6.2.3', 'py': '1.10.0', 'pluggy': '0.13.1'}, 'Plugins': {'html': '3.1. 1', 'metadata': '1.11.0', 'rerunfailures': '9.1.1', 'assume': '2.2.0', 'requests-mock': '1.7.0'}, 'JAVA_HOME': 'C:\\Program Files\\Java\\jdk1.8.0_271'} rootdir: C:\Users\057776\PycharmProjects\pytest-demo\testmark, configfile: pytest.ini plugins: html-3.1.1, metadata-1.11.0, rerunfailures-9.1.1, assume-2.2.0, requests-mock-1.7.0 collected 8 items
test_xfail.py::test_one XFAIL [ 12%] test_xfail.py::test_two XPASS [ 25%] test_xfail.py::test_three XFAIL (pytest.xfail方法在用例执行过程中直接标记用例结果为XFAIL,不会执行后面的代码) [ 37%] test_xfail.py::test_four XPASS (条件为真,预期失败的测试用例) [ 50%] test_xfail.py::TestException::test_five XFAIL [ 62%] test_xfail.py::TestException::test_six FAILED [ 75%] test_xfail.py::test_seven XFAIL ([NOTRUN] ) [ 87%] test_xfail.py::test_eight FAILED [100%]
===================================== FAILURES ===================================== ___________________________________ TestException.test_six ___________________________________
self =
@pytest.mark.xfail(raises=AssertionError) def test_six(self): > print(1 / 0) E ZeroDivisionError: division by zero
test_xfail.py:62: ZeroDivisionError ________________________________________ test_eight ________________________________________ [XPASS(strict)] ================================ short test summary info ================================ FAILED test_xfail.py::TestException::test_six - ZeroDivisionError: division by zero FAILED test_xfail.py::test_eight =========================== 2 failed, 4 xfailed, 2 xpassed in 0.57s ===========================
(venv) C:\Users\057776\PycharmProjects\pytest-demo\testmark>
说明:
每种测试函数都有说明,比对说明文字和运行结果验证相应的知识点。
4、parametrize - 参数化
语法糖:
@pytest.mark.parametrize(argnames, argvalues, indirect=False, ids=None, scope=None, *, _param_mark=None)
argnames:参数名,以逗号分隔的字符串,表示一个或多个参数名称。或参数字符串组成的列表/元组。
如果是一个参数,使用参数名的字符串。
如果是多个参数,多个参数名之间使用逗号分隔的字符串,或者多个参数名组成的列表,或者多个参数名组成的元组。
argvalues:参数值,类型是一个可迭代对象,和参数名一一对应。
如果argnames为一个参数,则argvalues是一个值列表。
如果argnames为多个参数,则argvalues必须是一个嵌套元组的列表,其中每个元组元素值与参数名一一对应。
indirect:参数名称列表(参数名称的子集)或布尔值。
indirect一般与Pytest的fixture,request.param组合使用
当indrect =True时,argnames参数名是fixture夹具的函数名,argvalues则是给这个夹具函数传递的参数。
ids:标记参数化测试用例的执行名称,默认自动生成,多个参数名之间用"-"连接。scope:参数范围。
新建 test_expectation.py 文件如下:
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 test_expectation.py -v
(venv) C:\Users\057776\PycharmProjects\pytest-demo\testmark>pytest test_expectation.py -v =================================== test session starts =================================== platform win32 -- Python 3.8.8, pytest-6.2.3, py-1.10.0, pluggy-0.13.1 -- e:\programs\python\python38\python.exe cachedir: .pytest_cache metadata: {'Python': '3.8.8', 'Platform': 'Windows-10-10.0.19041-SP0', 'Packages': {'pytest': '6.2.3', 'py': '1.10.0', 'pluggy': '0.13.1'}, 'Plugins': {'html': '3.1. 1', 'metadata': '1.11.0', 'rerunfailures': '9.1.1', 'assume': '2.2.0', 'requests-mock': '1.7.0'}, 'JAVA_HOME': 'C:\\Program Files\\Java\\jdk1.8.0_271'} rootdir: C:\Users\057776\PycharmProjects\pytest-demo\testmark, configfile: pytest.ini plugins: html-3.1.1, metadata-1.11.0, rerunfailures-9.1.1, assume-2.2.0, requests-mock-1.7.0 collected 3 items
test_expectation.py::test_eval[3+5-8] PASSED [ 33%] test_expectation.py::test_eval[2+4-6] PASSED [ 66%] test_expectation.py::test_eval[6*9-42] FAILED [100%]
====================================== FAILURES ====================================== _____________________________________ test_eval[6*9-42] _____________________________________
test_input = '6*9', expected = 42
@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 E assert 54 == 42 E +54 E -42
test_expectation.py:15: AssertionError ================================== short test summary info ================================== FAILED test_expectation.py::test_eval[6*9-42] - assert 54 == 42 ================================= 1 failed, 2 passed in 0.46s =================================
(venv) C:\Users\057776\PycharmProjects\pytest-demo\testmark>
说明:
这里,@parametrize装饰器定义了三个不同(test_input,expected) 的元组,以便test_eval函数将依次使用它们运行三次。
篇幅所限,这里只引用官网的例子简单说明下用法,parametrize参数化的详细用法在pytest参数化一文中详见讲解。
5、usefixtures - 使用夹具
语法糖:
pytest.mark.usefixtures(*names)
Parameters:args – The names of the fixture to use, as strings.
usefixtures,夹具名,字符串类型,可以有一个或多个夹具,通过*来解包将夹具名作为参数传给被标记的测试函数。
新建 test_usefixtures.py 文件如下:
import pytest
@pytest.fixture
def fixture_one():
print("this is fixture_one")
@pytest.mark.usefixtures('fixture_one')
class TestClass:
def test_two(self):
pass
def test_three(self):
pass
运行命令:pytest test_usefixtures.py -vs
(venv) C:\Users\057776\PycharmProjects\pytest-demo\testmark>pytest test_usefixtures.py -vs ==================================== test session starts ==================================== platform win32 -- Python 3.8.8, pytest-6.2.3, py-1.10.0, pluggy-0.13.1 -- e:\programs\python\python38\python.exe cachedir: .pytest_cache metadata: {'Python': '3.8.8', 'Platform': 'Windows-10-10.0.19041-SP0', 'Packages': {'pytest': '6.2.3', 'py': '1.10.0', 'pluggy': '0.13.1'}, 'Plugins': {'html': '3.1.1', 'metadata': '1.11.0', 'rerunfailures': '9.1.1', 'assume': '2.2.0', 'requests-mock': '1.7.0'}, 'JAVA_HOME': 'C:\\Program Files\\Java\\jdk1.8.0_271'} rootdir: C:\Users\057776\PycharmProjects\pytest-demo\testmark, configfile: pytest.ini plugins: html-3.1.1, metadata-1.11.0, rerunfailures-9.1.1, assume-2.2.0, requests-mock-1.7.0 collected 3 items
test_usefixtures.py::test_one this is fixture_one PASSED test_usefixtures.py::TestClass::test_two this is fixture_one PASSED test_usefixtures.py::TestClass::test_three this is fixture_one PASSED
==================================== 3 passed in 0.06s ====================================
(venv) C:\Users\057776\PycharmProjects\pytest-demo\testmark>
说明:
usefixtures标记了测试类TestClass,测试类中的所有测试函数都使用了夹具fixture_one 。
6、filterwarnings - 添加警告过滤器
语法糖:
pytest.mark.filterwarnings(filter)
filter,str类型,一个由Python文档的警告过滤器部分中指定的元组内容(action, message, category, module, lineno)组成的警告规范字符串,用“:”分隔。可选字段可以省略。传递给筛选的模块名不是正则表达式转义的。
新建 test_filterwarning.py文件:
import warnings
def api_v1():
warnings.warn(UserWarning("api v1, should use functions from v2"))
return 1
def test_one():
assert api_v1() == 1
运行命令:pytest test_filterwarning.py -vs
(venv) C:\Users\057776\PycharmProjects\pytest-demo\testmark>pytest test_filterwarning.py -vs ==================================== test session starts ==================================== platform win32 -- Python 3.8.8, pytest-6.2.3, py-1.10.0, pluggy-0.13.1 -- e:\programs\python\python38\python.exe cachedir: .pytest_cache metadata: {'Python': '3.8.8', 'Platform': 'Windows-10-10.0.19041-SP0', 'Packages': {'pytest': '6.2.3', 'py': '1.10.0', 'pluggy': '0.13.1'}, 'Plugins': {'html': '3.1.1', 'metadata': '1.11.0', 'rerunfailures': '9.1.1', 'assume': '2.2.0', 'requests-mock': '1.7.0'}, 'JAVA_HOME': 'C:\\Program Files\\Java\\jdk1.8.0_271'} rootdir: C:\Users\057776\PycharmProjects\pytest-demo\testmark, configfile: pytest.ini plugins: html-3.1.1, metadata-1.11.0, rerunfailures-9.1.1, assume-2.2.0, requests-mock-1.7.0 collected 1 item
test_filterwarning.py::test_one PASSED
=================================== warnings summary =================================== test_filterwarning.py::test_one C:\Users\057776\PycharmProjects\pytest-demo\testmark\test_filterwarning.py:14: UserWarning: api v1, should use functions from v2
warnings.warn(UserWarning("api v1, should use functions from v2"))
-- Docs: https://docs.pytest.org/en/stable/warnings.html ================================ 1 passed, 1 warning in 0.05s ================================
(venv) C:\Users\057776\PycharmProjects\pytest-demo\testmark>
添加警告过滤器filterwarnings,修改 test_filterwarning.py文件如下:
import warnings
import pytest
def api_v1():
warnings.warn(UserWarning("api v1, should use functions from v2"))
return 1
@pytest.mark.filterwarnings("ignore:api v1")
def test_one():
assert api_v1() == 1
运行命令:pytest test_filterwarning.py -vs
(venv) C:\Users\057776\PycharmProjects\pytest-demo\testmark>pytest test_filterwarning.py -vs =================================== test session starts =================================== platform win32 -- Python 3.8.8, pytest-6.2.3, py-1.10.0, pluggy-0.13.1 -- e:\programs\python\python38\python.exe cachedir: .pytest_cache metadata: {'Python': '3.8.8', 'Platform': 'Windows-10-10.0.19041-SP0', 'Packages': {'pytest': '6.2.3', 'py': '1.10.0', 'pluggy': '0.13.1'}, 'Plugins': {'html': '3.1.1', 'metadata': '1.11.0', 'rerunfailures': '9.1.1', 'assume': '2.2.0', 'requests-mock': '1.7.0'}, 'JAVA_HOME': 'C:\\Program Files\\Java\\jdk1.8.0_271'} rootdir: C:\Users\057776\PycharmProjects\pytest-demo\testmark, configfile: pytest.ini plugins: html-3.1.1, metadata-1.11.0, rerunfailures-9.1.1, assume-2.2.0, requests-mock-1.7.0 collected 1 item
test_filterwarning.py::test_one PASSED
=================================== 1 passed in 0.05s ===================================
(venv) C:\Users\057776\PycharmProjects\pytest-demo\testmark>
说明:
警告过滤器filterwarnings装饰的测试函数test_one过滤掉了匹配到 "api v1" 开头的警告信息。
警告过滤器:
警告过滤器是用来控制警告是被忽略、显示还是变成错误(引发异常)。是一个形式的元组(action、 message、category、module、lineno),其中:
action是以下字符串之一:
价值 处置 "default" 打印发出警告的每个位置(模块 + 行号)的匹配警告的第一次出现 "error" 将匹配的警告变成异常 "ignore" 从不打印匹配的警告 "always" 总是打印匹配的警告 "module" 为发出警告的每个模块打印第一次出现的匹配警告(无论行号如何) "once" 仅打印第一次出现的匹配警告,无论位置如何
message是一个字符串,其中包含警告消息的开头必须匹配的正则表达式,不区分大小写。在-W和 PYTHONWARNINGS, message是警告消息的开头必须包含的文字字符串(不区分大小写),忽略message开头或结尾的任何空格。 category是一个类(的子类Warning),警告类别必须是其子类才能匹配。 module是一个字符串,其中包含一个正则表达式,完全限定模块名称的开头必须匹配,区分大小写。在-W和 PYTHONWARNINGS, module是一个文字字符串,完全限定的模块名称必须等于(区分大小写),忽略module开头或结尾的任何空格。 lineno是一个整数,出现警告的行号必须匹配,或0匹配所有行号。
三、自定义标记
注册标记>>给测试用例打标记>>运行标记的测试用例
1、注册自定义标记
方法1,在 pytest.ini文件中注册自定义标记
[pytest]
addopts = --strict-markers
markers =
slow: marks tests as slow (deselect with '-m "not slow"')
serial
说明:
: 英文标记名称之后的所有内容都是可选描述。使用没有注册的标记,会出现warning警告,解决办法是在pytest.ini文件注册标记。当使用--strict命令行参数时,未在pytest.ini文件中注册的任何标记都将引发异常,这可用于防止用户意外输错标记名称。
方法2,conftest.py文件中,使用钩子函数注册标记
def pytest_configure(config):
config.addinivalue_line(
"markers", "env(name): mark test to run only on named environment"
)
2、给测试用例打标记
使用装饰器@pytest.mark.markername给测试函数打标记。
(1)标记测试函数,测试类
@pytest.mark.markername
(2)标记整个模块
pytestmark = pytest.mark.markername pytestmark = [pytest.mark.markername1, pytest.mark.markername2]
3、运行标记的测试用例
(1)运行标记的测试用例
pytest -m markername
(2)运行多个标记的测试用例
pytest -m "markername1 or markername2"
(3)运行指定标记以外的所有测试用例
pytest -m "not markername"
新建 test_custom_mark.py 文件如下:
import pytest
def test_one():
pass
@pytest.mark.slow
def test_two():
pass
@pytest.mark.env
class TestMark:
def test_three(self):
pass
def test_four(self):
pass
运行命令:pytest test_custom_mark.py -m slow -v
(venv) C:\Users\057776\PycharmProjects\pytest-demo\testmark>pytest test_custom_mark.py -m slow -v =================================== test session starts =================================== platform win32 -- Python 3.8.8, pytest-6.2.3, py-1.10.0, pluggy-0.13.1 -- e:\programs\python\python38\python.exe cachedir: .pytest_cache metadata: {'Python': '3.8.8', 'Platform': 'Windows-10-10.0.19041-SP0', 'Packages': {'pytest': '6.2.3', 'py': '1.10.0', 'pluggy': '0.13.1'}, 'Plugins': {'html': '3.1.1', 'metadata': '1.11.0', 'rerunfailures': '9.1.1', 'assume': '2.2.0', 'requests-mock': '1.7.0'}, 'JAVA_HOME': 'C:\\Program Files\\Java\\jdk1.8.0_271'} rootdir: C:\Users\057776\PycharmProjects\pytest-demo\testmark, configfile: pytest.ini plugins: html-3.1.1, metadata-1.11.0, rerunfailures-9.1.1, assume-2.2.0, requests-mock-1.7.0 collected 4 items / 3 deselected / 1 selected
test_custom_mark.py::test_two PASSED [100%]
============================== 1 passed, 3 deselected in 0.04s ==============================
(venv) C:\Users\057776\PycharmProjects\pytest-demo\testmark>
说明:
pytest收集到4条测试用例,只执行了slow标记的一条测试用例test_two,忽略了其它三条侧测试用例。
reference:
API Reference — pytest documentation
How to mark test functions with attributes — pytest documentation
Working with custom markers — pytest documentation
文章来源
发表评论