pytest框架2---前置后置,夹具fixture的使用


一、前置后置

1.经典的xunit风格,可在模块,类,函数实现fixture

  • 模块级别
    def setup_module():
        print('****************在整个模块开始执行一次*************')
    
    def teardown_module():
        print('*************在整个模块结束执行一次****************')  
  • 类级别
    @classmethod
        def setup_class(cls):
            print('在整个测试类开始执行一次')
    
    @classmethod
        def teardown_class(cls):
            print('在整个测试类结束执行一次')  
  • 方法级别
    # 方法级别
        def setup_method(self):
            print("""类中方法级前置""")
    
        def teardown_method(self):
            print("""类中方法级别后置""") 
  • 函数级别
    def setup_function():
        print("""函数级前置""")
    
    
    def teardown_function():
        print("""函数级别后置""")

test_a.py 应用上述的前后置

# test_a.py
import pytest


# 模块级别
def setup_module():
    print('****************在整个模块开始执行一次*************')


def teardown_module():
    print('*************在整个模块结束执行一次****************')


class TestA:
    # 类级别
    @classmethod
    def setup_class(cls):
        print('在整个测试类开始执行一次')
    
    # 方法级别
    def setup_method(self):
        print("""类中方法级前置""")

    def teardown_method(self):
        print("""类中方法级别后置""")

    def test_f(self):
        assert 1 == 2

    def test_e(self):
        print('e')

    @classmethod
    def teardown_class(cls):
        print('在整个测试类结束执行一次')


# 函数级别
def setup_function():
    print("""函数级前置""")


def test_b():
    print('d')


def teardown_function():
    print("""函数级别后置""")


if __name__ == '__main__':
    pytest.main(["-s","-v",'../testcases/test_a.py'])

结果:

2. unittest风格

@classmethod
def setUpClass(cls) -> None:
    pass
@classmethod
def tearDownClass(cls) -> None:
    pass
def setUp(self) -> None:
    pass
def tearDown(self) -> None:

3.pytest.fixture

3.1 定义

  • 前置条件
    @pytest.fixture()
    def fixture_func():
        print('前置条件')  
  • 后置条件,关键词yield
    @pytest.fixture()
    def fixture_func():
        print('前置条件')
        yield 
        print('后置条件')
    

  • 前置条件给后置条件传值

    @pytest.fixture()
    def fixture_func():
        print('前置条件')
        a = 1
        yield a
        a =a+1
        print('后置条件a的值为{}'.format(a))
    

3.2 调用夹具fixture()

  • 通过装饰器@pytest.mark.usefixtures(fixture_name)
    @pytest.fixture()
    def fixture_func():
        print('前置条件')
    
    
    class TestA:
    
        @pytest.mark.usefixtures("fixture_func")
        def test_1(self):
            pass
    
        def test_2(self):
            pass
    
    
    if __name__ == '__main__':
        pytest.main(["-s", "-v", "../testcases/test_c.py"])
  • 通过在测试函数中定义与夹具函数名同名的参数
    @pytest.fixture()
    def fixture_func():
        print('前置条件')
    
    
    class TestA:
    
        def test_2(self,fixture_func):
            pass  

3.3 夹具的作用范围

@pytest.fixture() 有一个scope参数可以指定夹具的作用范围

scope的取值有:

  • function 默认范围,函数范围
  • class 在类中最后一个测试完成后结束
  • module 在整个模块中最后一个测试完成后结束
  • package 在整个包中的最后一个测试完成后结束
  • session 在一次会话中最后一个测试完成后结束
    @pytest.fixture(scope="function")
    def fixture_func():
        print('前置条件')
        yield
        print('后置条件')
    
    
    class TestA:
    
        @pytest.mark.usefixtures("fixture_func")
        def test_1(self,):
            pass
    
        def test_2(self,fixture_func):
            pass
    
    
    @pytest.mark.usefixtures("fixture_func")
    def test_3():
        pass
    
    *************scope="function"打印结果*************************************:
    test_c.py::TestA::test_1 前置条件
    PASSED后置条件
    
    test_c.py::TestA::test_2 前置条件
    PASSED后置条件
    
    test_c.py::test_3 前置条件
    PASSED后置条件
    *************scope="class"打印结果*************************************:
    fixture为class级别的时候,如果一个class里面有多个用例,都调用了此fixture,那么此fixture只在该class里所有用例开始前执行一次
    test_c.py::TestA::test_1 前置条件
    PASSED
    test_c.py::TestA::test_2 PASSED后置条件
    
    test_c.py::test_3 前置条件
    PASSED后置条件
    
    *************scope="module"打印结果*************************************:
    '''fixture为module级别时在当前.py脚本里面所有用例开始前只执行一次'''
    test_c.py::TestA::test_1 前置条件
    PASSED
    test_c.py::TestA::test_2 PASSED
    test_c.py::test_3 PASSED后置条件
    
    *************scope="package"打印结果*************************************:
    test_c.py::TestA::test_1 前置条件
    PASSED
    test_c.py::TestA::test_2 PASSED
    test_c.py::test_3 PASSED后置条件  

3.4 共享夹具

 如果一个夹具需要被多个测试文件使用,则可以将其移至一个conftest.py文件中,不需要在测试中带入,他会自动被发现

优先在当前文件没有找该夹具,没有找到,则会自动进入conftest.py进行查找

 3.5 夹具的继承

def fixture_second(fixture_func)作为参数传入,调用顺序fixture_func前置,fixture_second前置,fixture_second后置,fixture_func后置

如下test2调用了fixture_second继承了fixture_func夹具,观察期打印结果,test1和test3调用fixture_func

@pytest.fixture()
def fixture_func():
    print('前置条件1')
    yield
    print('后置条件1')


@pytest.fixture()
def fixture_second(fixture_func):
    print('前置条件2')
    yield
    print('后置条件2')


class TestA:

    @pytest.mark.usefixtures("fixture_func")
    def test_1(self,):
        pass

    def test_2(self,fixture_second):
        pass


@pytest.mark.usefixtures("fixture_func")
def test_3():
    pass

*******************打印结果*********************************
test_c.py::TestA::test_1 前置条件1
PASSED后置条件1

test_c.py::TestA::test_2 前置条件1
前置条件2
PASSED后置条件2
后置条件1

test_c.py::test_3 前置条件1
PASSED后置条件1