Python (pytest) 类中函数装饰器中调用的当前类中的另一个函数, 引发的问题

HowardWu · October 21, 2019 · Last by Lee replied at October 28, 2019 · 1675 hits

本人在学习pytest, 最近一直困惑一个地方无法自解, 先上代码

class Test_case1:
def param_info(self):
x = '1'
y = '2'
z = '3'
return [x, y, z]

@pytest.mark.parametrize('x', self.param_info())
def test_x(self, x):
assert x == 1

这里再test_x上使用参数化时, 调用了当前类中的另一个方法param_info, 但因为装饰器的作用域问题, 这里或报错, 无法在装饰器中使用当前类中的函数. 因为的测试用例中的测试参数是需要适时获取, 且会变化的, 不是固定值, 所以必须要从之前的test步骤中执行后生成参数, 并用在后面的测试方法上. 所以这里如何pytest的中的装饰器中调用当前类的方法,或变量, 还想请教各位大神!

最佳回复

一般很少这样用吧,pytest就是单元测试,注意控制变量啊,我用pytest-lazy-fixture插件试了下好像可以,如果有更好的方式请告诉我🤔

import pytest


class Test_case123:

@pytest.fixture(params=[pytest.lazy_fixture('get_x'),
pytest.lazy_fixture('get_y')])
def param_info(self, request):
return request.param

@pytest.fixture
def get_x(self):
return self.__class__.x

@pytest.fixture
def get_y(self):
return self.__class__.y

def test_1(self):
self.__class__.x = "希望小学"

def test_2(self):
self.__class__.y = "希望小学生"

@pytest.mark.parametrize('z', [pytest.lazy_fixture('param_info')])
def test_3(self, z):
assert "希望" in z
共收到 8 条回复 时间 点赞

好像是不支持的,pytest 执行分成3个阶段:1-收集用例,2-执行用例,3-生成报告,所有用例在第一阶段就确定了,没法在用例执行的时候再去根据执行结果参数化。
而且测试用例应该是固定的吧,你这样设计肯定是有问题的,你可以把你的场景再详细描述下,再分析分析。

把 param_info 放到 Test_case1 外面看看。

chen 回复

放到外面是可以, 但是需要传参, 传递的参数是当前类中的变量, 所以这里还是会存在装饰器中的作用域问题.

arrow 回复

测试场景: 学生列表标记. 第1个用例是获取学校信息, 第2个用例是获取学生列表信息, 第3个用例是从第1个用例中获取的学校信息中组合成测试参数, 将第2个用例中学生信息组合成参数, 用于第3个用例的测试参数进行验证. 其实测试数据要是固定的话, 将测试参数直接预先设置好也是可以的, 但我想用于多个测试数据上. 所以测试参数不能固定.

arrow 回复

不过我有点启发了, 可以在fixture中把测试数据准备好. 就是麻烦一些. 谢谢

一般很少这样用吧,pytest就是单元测试,注意控制变量啊,我用pytest-lazy-fixture插件试了下好像可以,如果有更好的方式请告诉我🤔

import pytest


class Test_case123:

@pytest.fixture(params=[pytest.lazy_fixture('get_x'),
pytest.lazy_fixture('get_y')])
def param_info(self, request):
return request.param

@pytest.fixture
def get_x(self):
return self.__class__.x

@pytest.fixture
def get_y(self):
return self.__class__.y

def test_1(self):
self.__class__.x = "希望小学"

def test_2(self):
self.__class__.y = "希望小学生"

@pytest.mark.parametrize('z', [pytest.lazy_fixture('param_info')])
def test_3(self, z):
assert "希望" in z
HowardWu 回复

哎~~又是一个关联性的 case 设计。个人建议不要搞这种case 用fixture 做setUp将前置步骤最短化实现,这样做唯一的坏处就是相关前置步骤修改可能会导致修改量比较大,但fixture是能套fixture的合理的“拆封”是很又必要的。

改成类方法应该就可以了

需要 Sign In 后方可回复, 如果你还没有账号请点击这里 Sign Up