一、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 = <testmark.test_xfail.TestException object at 0x000002049D00DA00>

    @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(argnamesargvaluesindirect=Falseids=Nonescope=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、 messagecategorymodulelineno),其中:

  • action是以下字符串之一:

    价值

    处置

    "default"

    打印发出警告的每个位置(模块 + 行号)的匹配警告的第一次出现

    "error"

    将匹配的警告变成异常

    "ignore"

    从不打印匹配的警告

    "always"

    总是打印匹配的警告

    "module"

    为发出警告的每个模块打印第一次出现的匹配警告(无论行号如何)

    "once"

    仅打印第一次出现的匹配警告,无论位置如何

  • message是一个字符串,其中包含警告消息的开头必须匹配的正则表达式,不区分大小写。在-W和 PYTHONWARNINGSmessage是警告消息的开头必须包含的文字字符串(不区分大小写),忽略message开头或结尾的任何空格。

  • category是一个类(的子类Warning),警告类别必须是其子类才能匹配。

  • module是一个字符串,其中包含一个正则表达式,完全限定模块名称的开头必须匹配,区分大小写。在-W和 PYTHONWARNINGSmodule是一个文字字符串,完全限定的模块名称必须等于(区分大小写),忽略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

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐