pytest fixture的一些使用技巧个人总结

发布时间 2023-09-19 09:35:49作者: Device_Tech

介绍

pytest的fixture在自动化测试中真的是非常好用,我在工作中几乎所有的用例都需要使用到该功能,下面是一些基本的用法
fixture在我个人的理解中,它就是一个支持测试前置与测试后处理的工具

Scope级别

通俗易懂的来说该参数就是指定fixture的生命周期;
function是每一个测试函数都会执行一次,class是每一个类只会执行一次,module是每一个module只会执行一次(也就是一个py file),session是整个测试只会执行一次
这样的话我们就可以针对不同的测试用例来设置不同的scope,我个人经常使用的是class以及function
在我的项目中,经常会有对某一个资源进行测试的情况,如果对上层的资源没有要求,那我就会用class,这样只会创建一个前置资源用于该class下的所有测试

class TestExample:
    @pytest.fixture(scope="class")
    def vpc(self):
        # cls中的测试用例只需要一个VPC即可
        vpc_obj = CreateVPC()
        yield vpc_obj

    @pytest.fixture(scope="function")
    def config(self,vpc):
        # 每次都需要获取到最新的config
        yield vpc.get_config()

    def test_update_vpc_name(self,vpc,config):
        config['name'] = "random"
        vpc.update(config=config)

    def test_update_vpc_gateway(self,vpc,config):
        """test update NAT Gateway IP"""

set_up & tear_down的支持

支持测试前置处理以及测试后处理,继续使用上一个例子,在我们的测试用例执行完后,需要清理这个资源,如果要在测试函数中清理肯定是不优雅的,并且如果是并发执行测试也会有问题(清理了之后可能还有测试需要这个资源),所以我们将清理的逻辑放在fixture中

class TestExample:
    @pytest.fixture(scope="class")
    def vpc(self):
        # cls中的测试用例只需要一个VPC即可
        vpc_obj = CreateVPC()
        yield vpc_obj
        vpc_obj.delete()

这样就可以在每一个test class测试完成后清理或者处理相对应的资源或逻辑了

搭配pytest.dependency插件食用更加美好

在我的项目中,我常常会频繁的创建删除不同配置的资源,并且其他的用例也会到这种配置的资源,但是测试函数是不能call的(其实是可以调用,但是就相当于执行了两次),为此我实现了一个测试函数之间引用资源的方式,需要结合fixture与pytest.dependency来使用
原则上,测试用例之间最好不要产生依赖是最好的,但我这边考虑到成本的问题不得不去使用这种方式.

import pytest


class SharedClass:
    pass


# 这个可以放在conftest.py中以供全局使用
@pytest.fixture(scope="class")
def shared():
    yield SharedClass()


# 独立的一个类,专门用于支持依赖测试的支持
class PytestBase:
    @pytest.fixture(autouse=True)
    def set_up(self, shared):
        self._shared_cls = shared

    @property
    def shared_class(self):
        return self._shared_cls


class TestCase(PytestBase):
    @pytest.mark.dependency(name="create vpc")
    def test_case_01(self):
        """测试亚洲的VPC是否能够创建"""
        vpc = CreateVPC(region="asia")
        # 创建成功直接传参
        self.shared_class.vpc = vpc

    @pytest.mark.dependency(depends=["create vpc"])
    def test_case_02(self):
        """测试亚洲的compute资源能否创建"""
        instance = CreateInstance(vpc=self.shared_class.vpc)
        assert instance.exist()