一、pytestmark是什么?
pytestmark是pytest框架提供的装饰器,可以用来装饰整个文件或文件中的某些函数,其作用是将标记(mark)与被装饰的函数或文件相关联。
在pytest中,标记是一种在运行测试用例时动态影响测试用例执行的工具。通过pytestmark,可以在pytest命令行中使用不同的标记,例如-s,-m等
二、pytestmark的使用场景
1、使用pytestmark标记来提供一些默认的参数:可通过pytestmark为整个文件设置pytest.fixture()标记。这样,已被标记为fixture的函数,就可以在文件中被其他测试用例函数直接使用。
import pytest
@pytest.fixture()
def foo_fixture():
return 'foo module'
pytestmark = pytest.mark.usefixtures("foo_fixture")
def test_foo():
assert "foo module" == "foo module"
在上述代码中,我们为整个文件设置了pytest.fixture()标记,并在pytestmark中使用了usefixtures。当运行test_foo函数时,将先运行foo_fixture()函数,因此test_foo函数中的代码可以有效地使用foo_fixture()。
2、使用pytestmark标记来指定测试用例的实例化方式:可通过pytestmark将测试用例与类或函数进行关联。
import pytest
@pytest.mark.webtest
class TestSomething:
def test_one(self):
pass
def test_two(self):
pass
@pytest.mark.nighttest
class TestAnother:
def test_three(self):
pass
def test_four(self):
pass
在上述代码中,我们通过pytestmark将TestSomething和TestAnother类与不同的mark(webtest和nighttest)关联。在运行测试时,我们可以通过-m选项来执行哪种类型的测试用例。
3、使用pytestmark指定fixture执行范围:我们可以通过@pytest.mark.
import pytest
@pytest.fixture(scope="module")
def foo():
return 'foo'
def test_foo1(foo):
assert foo == 'foo'
def test_foo2(foo):
assert foo == 'foo'
pytestmark = pytest.mark.usefixtures("foo")
在上述代码中,我们将foo fixture设置为‘module’级别的fixture,在pytestmark中使用了usefixtures指定它的使用范围。在test_foo1和test_foo2中我们分别使用了foo fixture,它将在整个module的范围内使用。
三、pytestmark相关参数的使用方法
pytestmark也可以使用多个参数来定义一组标记列表
import pytest
@pytest.mark.parametrize("test_input, expected_output", [("3+5", 8), ("2+4", 6), ("6*9", 54)])
def test_eval(test_input, expected_output):
assert eval(test_input) == expected_output
pytestmark = [pytest.mark.number, pytest.mark.eval]
在上述代码中,我们使用pytest.mark.parameterize指定的参数值为test_input, expected_output。在pytestmark中,我们使用了一个长度为2的列表,分别包含了由number和eval标记所组成的标记列表。当我们运行测试用例时,可以通过“-m”参数来只运行标记为其中之一的测试用例。
四、pytestmark的多层嵌套标记
pytestmark也可以实现多层嵌套标记,使得多个标记可以被同时匹配
import pytest
@pytest.mark.parametrize("num", [1, 2, 3])
@pytest.mark.parametrize("letter", ["a", "b", "c"])
def test_multi_tag(num, letter):
pass
pytestmark = pytest.mark.beta
在上述代码中,我们使用pytest.mark.parameterize指定了两个参数值,num和letter。在pytestmark中,我们使用了beta标记。运行时可以使用“-m”参数指定beta标记,同时也可以使用“-k”参数通过一个测试用例的名称键值对来指定需要运行的测试用例。
五、pytestmark的跨文件标记
pytestmark还可以实现跨文件标记,从而为整个测试套件添加标记。
我们可以在conftest.py文件中定义标记,在整个测试套件中使用。pytest也会自动加载相应的标记,从而使整个测试套件具有相同的属性。
#在conftest.py文件中
import pytest
# 为整个测试套件设置webtest标记
pytestmark = pytest.mark.webtest
在上述代码中,我们在conftest.py文件中定义了webtest标记。pytestmark的值设置为pytest.mark.webmark,从而为整个测试套件添加了webtest标记。在执行整个测试套件时,pytest会自动加载conftest.py文件并实现webtest标记。
六、结论
通过以上内容我们可以看出,pytestmark可以在许多方面提高测试用例的复用性和灵活性。通过使用pytestmark和标记参数,开发人员可以使pytest的整体测试环境更加高效和精准。