介绍
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()