这是一个pytest第三方插件,主要解决用例之间的依赖关系。如果依赖的上下文失败后续的用例会被标识为跳过执行,相当于执行了pytest.mark.skip。

1.安装

安装命令如下:

pip install pytest-dependency

执行上述命令后,再执行pip install pytest-dependency,能找到该组件即可

pytest如何设置用例失败后不执行依赖的用例 pytest 用例依赖_pytest

2.基本用法

第一步:需要在用例开始位置写上@pytest.mark.dependency(),代表这条用例作为主条件,如果这条用例失败,关联它的用例会跳过执行。
第二步:在被关联的用例上,也打上带参数的装饰器@pytest.mark.dependency(),参数depends可写关联的依赖用例名。在depends也可以用别名的方式指定用例名。

2.1函数中执行
我们先看在函数中执行:在test_01函数前我们加上了@pytest.mark.dependency(),在test_02函数前也写了@pytest.mark.dependency(depends=[“test_01”]),表示在执行test_02函数依赖test_01函数。

import pytest

@pytest.mark.dependency()
def test_01():
    print('hello')
    assert 1 == 1

@pytest.mark.dependency(depends=["test_01"])
def test_02():
    print('hello test_02')


if __name__ == '__main__':
     pytest.main(['-sv'])

输出结果:

test_import_02.py::test_01 hello
PASSED
test_import_02.py::test_02 hello test_02
PASSED

若test_01函数断言改成2 == 1,test_01函数会报错,test_02函数会被跳过。输出如下所示:

=========================== short test summary info ===========================
FAILED test_import_02.py::test_01 - assert 2 == 1
================== 1 failed, 1 skipped, 2 warnings in 0.46s ===================

我们也可将test_01用别名,例如:

import pytest

@pytest.mark.dependency(name="dep")
def test_01():
    print('hello')
    assert 1 == 1

@pytest.mark.dependency(depends=["dep"])
def test_02():
    print('hello test_02')


if __name__ == '__main__':
     pytest.main(['-sv'])

输出:

test_import_02.py::test_01 hello
PASSED
test_import_02.py::test_02 hello test_02
PASSED

若我们将函数test_01放在test_02之后执行,test_02函数执行被跳过。代码如下:

import pytest

@pytest.mark.dependency(depends=["test_01"])
def test_02():
    print('function hello')
    assert 1 == 1

@pytest.mark.dependency()
def test_01():
    print('function hello')
    assert 1 == 1

if __name__ == '__main__':
     pytest.main(['-sv'])

输出如下:

test_import_02.py::test_02 SKIPPED (test_02 depends on test_01)
test_import_02.py::test_01 function hello
PASSED

2.2 在类中执行
在类中执行,不能直接写方法名,需要加上类名::方法名或者别名。为什么不能直接写方法名,后面会详细说明。代码如下:

import pytest


class Testdep():
    @pytest.mark.dependency()
    def test_01(self):
        print('cclass hello')
        assert 1 == 1

    @pytest.mark.dependency(depends=["Testdep::test_01"])
    def test_02(self):
        print('hello test_02')


if __name__ == '__main__':
     pytest.main(['-sv'])

输出如下:

test_import_02.py::Testdep::test_01 cclass hello
PASSED
test_import_02.py::Testdep::test_02 hello test_02
PASSED

3.依赖范围

@pytest.mark.dependency(name=None,depends=[],scope=‘module’)的括号中参数说明如下:

  • name:依赖测试所引用的测试名称,如果未设置,则默认使用pytest定义的节点ID,名称需唯一
  • depends:依赖性,此测试所依赖的测试名称的列表
  • scope:搜索依赖的范围,必须是session,package,module或class,默认为module

3.1 依赖范围为:class

作用于所属的类,外部类不会被关联

import pytest

def test_02():
    print('function test_02')
    assert 1 == 1


class Testdep2():
    @pytest.mark.dependency()
    def test_01(self):
        print('class test_01')
        assert 1 == 1

    @pytest.mark.dependency()
    def test_02(self):
        print('class test_02')

class Testdep1():
    @pytest.mark.dependency()
    def test_01(self):
        print('class test_01')
        assert 1 == 1

    @pytest.mark.dependency(depends=["test_01"],scope='class')
    def test_02(self):
        print('class test_02')

@pytest.mark.dependency()
def test_01():
    print('function test_01')
    assert 1 == 1

if __name__ == '__main__':
     pytest.main(['-sv'])

类Testdep1的test_02方法只会在当前类中找test_01方法,输出如下:

test_import_02.py::test_02 function test_02
PASSED
test_import_02.py::Testdep2::test_01 class test_01
PASSED
test_import_02.py::Testdep2::test_02 class test_02
PASSED
test_import_02.py::Testdep1::test_01 class test_01
PASSED
test_import_02.py::Testdep1::test_02 class test_02
PASSED
test_import_02.py::test_01 function test_01
PASSED

我们将类Testdep1的test_01方法放到test_02后执行,test_02就会被跳过:
输出如下:

test_import_02.py::test_02 function test_02
PASSED
test_import_02.py::Testdep2::test_01 class test_01
PASSED
test_import_02.py::Testdep2::test_02 class test_02
PASSED
test_import_02.py::Testdep1::test_02 SKIPPED (test_02 depends on tes...)
test_import_02.py::Testdep1::test_01 class test_01
PASSED
test_import_02.py::test_01 function test_01
PASSED

3.2 依赖范围为:module

默认参数是’module’,作用于当前文件。只会查找当前文件的符合条件的文件名,类里同名的方法不会被依赖。代码如下:

import pytest

def test_02():
    print('function test_02')
    assert 1 == 1

class Testdep2():
    @pytest.mark.dependency()
    def test_01(self):
        print('class test_01')
        assert 1 == 1

    @pytest.mark.dependency()
    def test_02(self):
        print('class test_02')

class Testdep1():
    @pytest.mark.dependency()
    def test_01(self):
        print('class test_01')
        assert 1 == 1

    @pytest.mark.dependency(depends=["test_01"],scope='module')
    def test_02(self):
        print('class test_02')



@pytest.mark.dependency()
def test_01():
    print('function test_01')
    assert 1 == 1

if __name__ == '__main__':
     pytest.main(['-sv'])

输出如下:

test_import_02.py::test_02 function test_02
PASSED
test_import_02.py::Testdep2::test_01 class test_01
PASSED
test_import_02.py::Testdep2::test_02 class test_02
PASSED
test_import_02.py::Testdep1::test_01 class test_01
PASSED
test_import_02.py::Testdep1::test_02 SKIPPED (test_02 depends on tes...)
test_import_02.py::test_01 function test_01
PASSED

要想调用当前类或别的类,需使用别名或者使用类名::方法名
例如:

import pytest

def test_02():
    print('function test_02')
    assert 1 == 1

class Testdep2():
    @pytest.mark.dependency()
    def test_01(self):
        print('class test_01')
        assert 1 == 1

    @pytest.mark.dependency()
    def test_02(self):
        print('class test_02')

class Testdep1():
    @pytest.mark.dependency()
    def test_01(self):
        print('class test_01')
        assert 1 == 1

    @pytest.mark.dependency(depends=["Testdep2::test_01"],scope='module')
    def test_02(self):
        print('class test_02')



@pytest.mark.dependency()
def test_01():
    print('function test_01')
    assert 1 == 1

if __name__ == '__main__':
     pytest.main(['-sv'])

输出:

test_import_02.py::test_02 function test_02
PASSED
test_import_02.py::Testdep2::test_01 class test_01
PASSED
test_import_02.py::Testdep2::test_02 class test_02
PASSED
test_import_02.py::Testdep1::test_01 class test_01
PASSED
test_import_02.py::Testdep1::test_02 class test_02
PASSED
test_import_02.py::test_01 function test_01
PASSED

3.3 依赖范围为:package

作用于当前目录同级的依赖函数,跨目录无法找到依赖的函数。

例如在dep2目录下,创建了test_dep_01.py和test_dep_02.py.

pytest如何设置用例失败后不执行依赖的用例 pytest 用例依赖_python_02


test_dep_01.py的代码如下:

import pytest


class Testna():
    @pytest.mark.dependency()
    def test_01(self):
        print('function test_01')
        assert 1 == 1

    @pytest.mark.dependency()
    def test_02(self):
        print('function test_02')

test_dep_02.py的代码如下:

import pytest

def test_02():
    print('function test_02')
    assert 1 == 1


class Testdep1():
    @pytest.mark.dependency()
    def test_01(self):
        print('class test_01')
        assert 1 == 1

    @pytest.mark.dependency(depends=["test_dep_01.py::Testna::test_01"], scope='package')
    def test_02(self):
        print('class test_02')

输出结果为:

D:\pythonProject\dependency\dep\dep2>pytest -sv
======================================================================== test session starts ========================================================================
platform win32 -- Python 3.7.6, pytest-6.2.4, py-1.10.0, pluggy-0.13.1 -- d:\python3.7.6\python.exe
cachedir: .pytest_cache
rootdir: D:\pythonProject\dependency\dep\dep2
plugins: allure-pytest-2.9.41, dependency-0.5.1
collected 6 items                                                                                                                                                    

test_dep_01.py::Testna::test_01 function test_01
PASSED
test_dep_01.py::Testna::test_02 function test_02
PASSED
test_dep_02.py::test_02 function test_02
PASSED
test_dep_02.py::Testdep1::test_01 class test_01
PASSED
test_dep_02.py::Testdep1::test_02 class test_02
PASSED
test_dep_02.py::test_01 function test_01
PASSED

========================================================================= 6 passed in 0.05s =========================================================================

3.4 依赖范围为:session

作用域全局,可跨目录调用。但被依赖的用例必须先执行

例如结构如下:

pytest如何设置用例失败后不执行依赖的用例 pytest 用例依赖_dependency_03

在dep1目录下创建了test_dep_01.py,代码如下:

import pytest


class Testna():
    @pytest.mark.dependency()
    def test_01(self):
        print('function test_01')
        assert 1 == 1

    @pytest.mark.dependency()
    def test_02(self):
        print('function test_02')

在dep2目录下创建了test_dep_02.py,代码如下:

import pytest

def test_02():
    print('function test_02')
    assert 1 == 1


class Testdep1():
    @pytest.mark.dependency()
    def test_01(self):
        print('class test_01')
        assert 1 == 1

    @pytest.mark.dependency(depends=["dep1/test_dep_01.py::Testna::test_01"], scope='session')
    def test_02(self):
        print('class test_02')



@pytest.mark.dependency()
def test_01():
    print('function test_01')
    assert 1 == 1

在上一级目录dep下执行

D:\pythonProject\dependency\dep>pytest -sv
======================================================================== test session starts ========================================================================
platform win32 -- Python 3.7.6, pytest-6.2.4, py-1.10.0, pluggy-0.13.1 -- d:\python3.7.6\python.exe
cachedir: .pytest_cache
rootdir: D:\pythonProject\dependency\dep
plugins: allure-pytest-2.9.41, dependency-0.5.1
collected 6 items                                                                                                                                                    

dep1/test_dep_01.py::Testna::test_01 function test_01
PASSED
dep1/test_dep_01.py::Testna::test_02 function test_02
PASSED
dep2/test_dep_02.py::test_02 function test_02
PASSED
dep2/test_dep_02.py::Testdep1::test_01 class test_01
PASSED
dep2/test_dep_02.py::Testdep1::test_02 class test_02
PASSED
dep2/test_dep_02.py::test_01 function test_01
PASSED

在dep2目录下执行,结果如下:

D:\pythonProject\dependency\dep\dep2>pytest -sv
======================================================================== test session starts ========================================================================
platform win32 -- Python 3.7.6, pytest-6.2.4, py-1.10.0, pluggy-0.13.1 -- d:\python3.7.6\python.exe
cachedir: .pytest_cache
rootdir: D:\pythonProject\dependency\dep\dep2
plugins: allure-pytest-2.9.41, dependency-0.5.1
collected 4 items                                                                                                                                                    

test_dep_02.py::test_02 function test_02
PASSED
test_dep_02.py::Testdep1::test_01 class test_01
PASSED
test_dep_02.py::Testdep1::test_02 SKIPPED (test_02 depends on dep1/test_dep_01.py::Testna::test_01)
test_dep_02.py::test_01 function test_01
PASSED

=================================================================== 3 passed, 1 skipped in 0.04s ====================================================================