gpt4 book ai didi

python - Pytest参数化测试用例共享一个类变量

转载 作者:行者123 更新时间:2023-12-05 01:16:06 24 4
gpt4 key购买 nike

我最近开始使用pytest,写了一个如下的类。

import pytest
import yaml
import random

testcases = list()
class TestSample(object):
test_yml_file = "/tmp/test_inputs.yml"

yamlTestList = list()
with open(test_yml_file, 'r') as testYamlFile:
yamlTestList = yaml.load(testYamlFile)

global testcases
testcases = []

for d in yamlTestList['testcases']:
temp = dict()
for k,v in d.items():
temp[k] = v
testcases.append((temp['testcase'],temp))

last_value = 2

@classmethod
def setup_class(self):
test_sample = TestSample()

@pytest.mark.debug
@pytest.mark.parametrize(('testname', 'testInput'), testcases)
def test_run(self,testname,testInput):
if last_value >= 10:
last_value += random.randint(1,10)

当前问题是 -对于每个参数化测试,last_value 始终设置为 2。我们如何将之前测试用例中更改的“last_value”变量的值用于当前测试用例?

最佳答案

回答:

您需要在外部作用域中实例化 lastvalue 变量,从中可以调用参数化函数,而不是在测试类本身中。这是因为参数化如何与 pytest 一起工作。具有每个单独参数集的每个函数调用都存在于单独的范围内,因此在您的代码中,您每次调用函数之前基本上都将 lastvalue 变量重置为 2。

解决方案一:

我不推荐全局变量,但按照你的例子,这证明了我在说什么。


last_value = 0


class TestSample(object):
testcases = [("name1", 1), ("name2", 2), ("name3", 3), ("name4", 4)]

@pytest.mark.parametrize(('testname', 'testInput'), testcases)
def test_run(self, testname, testInput):
global last_value
if last_value >= 10:
last_value += random.randint(1, 10)
else:
last_value += 5

print(last_value)

另请注意,我在函数中添加了一个 else 子句来测试它。即使参数化类似于单个类实例中的循环,lastvalue 变量在您的示例代码中也永远不会更改,因为 if last_value >= 10 子句永远不会有机会得到满足,因此 lastvalue 增量从未实际发生。

最佳解决方案:

我建议使用具有“类”作用域的 pytest fixture,而不是使用全局变量。您可以阅读有关 fixture 和 fixture 范围的信息 in the pytest docs here.

@pytest.fixture(name="sample_manager", scope="class")
def sample_manager_fixture():
class SampleManager:
def __init__(self):
self.last_value = 0

return SampleManager()


class TestSample:
testcases = [("name1", 1), ("name2", 2), ("name3", 3), ("name4", 4)]

def test_order(self, sample_manager):
print(sample_manager.last_value)

@pytest.mark.parametrize(('testname', 'testInput'), testcases)
def test_run(self, testname, testInput, sample_manager):
if sample_manager.last_value >= 10:
sample_manager.last_value += random.randint(1, 10)
else:
sample_manager.last_value += 5

print(sample_manager.last_value)

sample_manager_fixture() fixture 函数在传递给测试函数时返回一个 SampleManager 类实例。 Pytest 在幕后处理所有这些,因此您需要做的就是将 fixture 名称(在我的例子中明确声明)作为参数包含在内。 fixture 作用域定义了从 fixture 返回的每个特定对象实例的“生命周期”。因此,将 fixture 的范围设置为“类”会通知 pytest 您希望特定类中的所有测试函数共享从 fixture 返回的对象的相同实例。您可以从所需的固定装置返回具有任何结构的任何对象,因此它们是一个非常强大的工具来管理您的测试数据。

关于python - Pytest参数化测试用例共享一个类变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54354681/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com