首页 > 编程问答 >传递参数化值时,类中的设置函数无法按预期工作

传递参数化值时,类中的设置函数无法按预期工作

时间:2024-07-21 10:07:10浏览次数:8  
标签:python python-3.x pytest command-line-arguments parameterization

我不知道为什么将 此处提到的代码 修改为以下内容不起作用?这些变量在测试内部不可访问,并且尽管范围设置为类,但在每次测试之前都会调用设置。任何指示都会非常有帮助。谢谢

#conftest.py
def pytest_addoption(parser):
    parser.addoption("--data", action="store", default="1,2 3,4 5,6", help="Data for parametrization")

def pytest_generate_tests(metafunc):
    data_str = metafunc.config.getoption("data")
    # data_list = [(1, 2), (3, 4), (5, 6)]
    data_list = [tuple(map(int, item.split(','))) for item in data_str.split()]
    # metafunc.parametrize("data", data_list, indirect=True)
    metafunc.parametrize("data", data_list, scope="class")

# @pytest.fixture(scope="class")
# def data(request):
#     return request.param

#test_code.py
import pytest
class Test1():
    @pytest.fixture(scope="class", autouse=True)
    def setup(self, data, request):
        print(data)
        [self.a, self.b] = list(data)
        self.c = self.a + self.b
        print('Test1.setup')

    def test_a(self):
        print("Test1.test_a")
        print(f'Test1.test_a - {self.a}, {self.b}, {self.c}')
        self.d = self.c * 2

    def test_b(self):
        print("Test1.test_b")
        print(f'Test1.test_b - {self.d}')

代码无法按预期工作的原因是,试图将 scope="class" pytest_generate_tests 中的参数化以及 autouse=True setup fixture 中的参数结合使用。这种组合在 pytest 中不起作用。

以下是发生的事情以及如何修复它:

  1. pytest_generate_tests 中的参数化 :当使用 metafunc.parametrize("data", data_list, scope="class") 时,pytest 会为 data_list 中的每个元素创建一个 Test1 类的 实例 。这意味着 setup fixture 和其中的所有内容(包括 self.a self.b self.c )都会为每个测试用例 单独实例化

  2. autouse=True setup fixture 上的 autouse=True 意味着它将在每个测试函数 之前 自动运行,而无需在测试函数中明确请求它。

  3. 组合问题 :由于将 scope="class" pytest_generate_tests 中的参数化一起使用,因此 setup fixture 会在 Test1 类的每个 实例 上运行,该实例是在为 data_list 中的每个值创建的。这意味着 self.a self.b self.c 会在每个测试用例之前被覆盖,从而导致意外行为。

解决方案

为了解决此问题,可以将参数化移动到类级别,并使用 pytest.mark.parametrize 装饰器:

# conftest.py
def pytest_addoption(parser):
    parser.addoption("--data", action="store", default="1,2 3,4 5,6", help="Data for parametrization")

def pytest_generate_tests(metafunc):
    if 'data' in metafunc.fixturenames:
        data_str = metafunc.config.getoption("data")
        data_list = [tuple(map(int, item.split(','))) for item in data_str.split()]
        metafunc.parametrize("data", data_list, scope="class")

# test_code.py
import pytest

@pytest.mark.parametrize("data", [(1, 2), (3, 4), (5, 6)], scope="class")
class Test1():

    @pytest.fixture(scope="class", autouse=True)
    def setup(self, request):
        self.a, self.b = request.param
        self.c = self.a + self.b
        print('Test1.setup')

    def test_a(self):
        print("Test1.test_a")
        print(f'Test1.test_a - {self.a}, {self.b}, {self.c}')
        self.d = self.c * 2

    def test_b(self):
        print("Test1.test_b")
        print(f'Test1.test_b - {self.d}')

在此解决方案中:

  • 我们使用 @pytest.mark.parametrize 装饰器在类级别应用参数化。
  • setup fixture 现在正确地获取了 request.param 中的参数化数据,并为每个测试用例设置了类属性。

这将确保 setup fixture 仅运行 一次 ,并且 self.a self.b self.c 的值在 Test1 类的所有测试用例中都可用。

标签:python,python-3.x,pytest,command-line-arguments,parameterization
From: 78774245

相关文章

  • Python 迭代列表
    分配sum_extra给定列表test_grades收到的额外学分总额。满分是100分,所以超过100分都是额外分。对于给定程序,sum_extra是8,因为1+0+7+0是8。给定程序的示例输出:额外总和:8请原谅我,我是编码新手,而且真的很糟糕!这是我的代码(不起作用)请......
  • 计算机毕业设计Python+Spark新能源汽车推荐系统 汽车大数据 汽车数据分析 汽车可视化
    表2黄河交通学院本科毕业设计(论文)开题报告学生姓名刘丹杰专业班级20本大数据一班学号2080910T01521设计(论文)题目基于Hadoop的新能源汽车销售数据分析系统的设计与实现选题的目的和意义:选题目的:新能源汽车销售数据分析系统的设计与实现旨在利用Hadoop等大数......
  • 为什么我的 python 程序一直说没有名为“PIL”的模块?
    我正在pythonIDLEshell中工作,由于某种原因pyautogui.locateOnScreen将无法工作。这是我的代码:frompyautoguiimport*importpyscreezeimportpyautoguiimporttimeimportkeyboardimportrandomimportwin32api,win32conwhile1:ifpyautogui.locateOnS......
  • 我在 Python 时间格式化函数中遇到代码问题
    我一直在研究一个Python函数,将给定的秒数转换为可读的时间格式(HH:MM:SS)。该函数对于大多数测试用例都能正常工作,但对于一些特定的输入会失败。这是我编写的函数:defmake_readable(seconds):ifseconds<60:s1=secondsh1,m1=(0,0)return......
  • 《流畅的Python》第二版 第11章
     fromarrayimportarrayimportmathclassVector2d:__match_args__=('x','y')typecode='d'def__init__(self,x,y):self.__x=float(x)self.__y=float(y)@propertydefx(self)......
  • 《流畅的Python》第二版 第12章
       fromarrayimportarrayimportmathimportfunctoolsimportitertoolsimportoperatorimportreprlibclassVector:typecode='d'def__init__(self,components):self._components=array(self.typecode,components)......
  • 如何在Python中给jupyter单元标准输入?
    我正在尝试在接受用户输入的jupyter笔记本上运行一个程序,但我不知道如何让它读取标准输入。例如,如果我使用shift-enter:a=input()print(a)运行代码,则单元格指示它正在运行,但不接受我的输入。我如何让它接受输入?你遇到的问题是Jupyternotebook中的代码单元默认......
  • Python:如何从 csvreader 列表中删除括号和单引号?
    Pythonn00b在这里。尝试使用csvreader从文件导入数组并打印一个值,但它添加了括号和单引号。这是我的代码:importrandomimportcsvwithopen('crimes.csv','r')ascsvfile:crimes=list(csv.reader(csvfile))hello=["Hello","Greetings","Hi&q......
  • Python 中的多行输入,支持空行并在控制台中检查“\n”
    您好,亲爱的社区,在解决某个竞赛任务时出现了问题。我解决了它,但由于输入棘手而无法交付。我在谷歌上搜索并尝试了几种找到的方法,但如果应用于此任务,它们中的每一种都有一些弱点。而且我无法完全重现所应用的输入,因为它嵌入在竞赛界面中;我可能只依赖描述。这就是为什么我......
  • Python Pandas - 读取 CSV 或 Excel
    我允许用户上传CSV或Excel文件。我正在使用pandas读取文件并创建数据框。由于我无法预测用户将上传哪种文件类型,因此我将pd.read_csv()和pd.read_excel()包装在try/except块中。ifform.validate_on_submit():input_filename=secure_filename(form.file.da......