首页 > 编程问答 >如何修改conftest中的参数化值并将它们传递给pytest中的多个测试用例

如何修改conftest中的参数化值并将它们传递给pytest中的多个测试用例

时间:2024-07-21 04:13:11浏览次数:14  
标签:python python-3.x pytest hook command-line-arguments

问题: 假设一个流程需要 10 个步骤才能完成。我一一开始该过程的步骤,在这些步骤之间,我想做出不同的断言。每次断言后,我都会继续执行其余步骤。 我希望每个断言都作为测试用例发生。所以如果有 5 个断言,我需要 5 个测试用例。如果有 2 组参数化值,那么我需要每组进行 5 次断言,因此将执行 10 个测试用例。我可以将所有步骤放在一个测试用例本身中,但我特别希望断言是单独的测试用例。

以下是我的代码。

# conftest.py
import pytest

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("arithmetic_data", data_list, indirect=True)

@pytest.fixture(scope="function")
def arithmetic_data(request):
    return request.param
# test_allure.py
import pytest

class TestClass:
    @pytest.fixture
    def arithmetic_data(self, arithmetic_data):
        self.a, self.b = arithmetic_data                # Step 1
        self.a, self.b = self.a * 2, self.b * 3
        self.c, self.d = self.a * 10, self.b * 10       # Step 4

    def test_addition(self, arithmetic_data):           # Step 2
        result = self.a + self.b
        assert result == self.a + self.b, f"Addition failed: {self.a} + {self.b} != {result}"

    def test_subtraction(self, arithmetic_data):        # Step 3
        result = self.a - self.b
        assert result == self.a - self.b, f"Subtraction failed: {self.a} - {self.b} != {result}"

    def test_multiplication(self, arithmetic_data):     # Step 5 
        result = self.c * self.d
        assert result == self.c * self.d, f"Multiplication failed: {self.c} * {self.d} != {result}"

    def test_square(self, arithmetic_data):             # Step 6
        result = self.a * self.a
        assert result == self.a * self.a, f"Square failed: {self.a}^2 != {result}"

我认为我做了什么: 我将参数化值放入一个类中,在 arithmetic_data 函数中进行了一些后处​​理(步骤 1)。我将此函数作为参数传递给第一个测试用例( test_addition - 步骤 2),然后执行第二个测试用例( test_subtraction - 步骤 3)。

在这个地方,我想执行步骤 4,为什么是因为这里生成的一些值需要传递给其余的测试。然后我将这些值传递给 test_multiplication (步骤 5)。然后,我执行下一步,即最后一个测试用例。

我知道这很糟糕,因为我无法并行运行它,因为这些步骤必须按顺序执行。但理想情况下,我希望每个进程对于每个参数化值集并行运行。任何有关解决此问题的指示都会非常有帮助。谢谢。


你遇到的问题是,你试图在一个本质上是顺序的流程中强制执行测试用例的并行性。你希望在多个测试用例中对同一组数据执行一系列步骤,这与 pytest 的设计理念相悖,pytest 的设计理念是将测试用例相互隔离。

为了解决这个问题,你需要重新考虑你的测试结构。与其尝试在多个测试用例中对同一组数据执行一系列步骤,不如将每个“步骤”视为一个独立的测试用例,每个测试用例都执行必要的设置和断言。

以下是如何重构代码以实现此目的的方法:

# conftest.py
import pytest

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 = [tuple(map(int, item.split(','))) for item in data_str.split()]
    metafunc.parametrize("a, b", data_list)

# test_allure.py
import pytest

class TestClass:
    @pytest.mark.parametrize("a, b", [(1, 2), (3, 4), (5, 6)])
    def test_step1_and_2(self, a, b):       # Step 1 & 2
        a, b = a * 2, b * 3                # Step 1
        result = a + b                      # Step 2
        assert result == a + b, f"Addition failed: {a} + {b} != {result}"

    @pytest.mark.parametrize("a, b", [(1, 2), (3, 4), (5, 6)])
    def test_step3(self, a, b):            # Step 3
        a, b = a * 2, b * 3
        result = a - b
        assert result == a - b, f"Subtraction failed: {a} - {b} != {result}"

    @pytest.mark.parametrize("a, b", [(1, 2), (3, 4), (5, 6)])
    def test_step4_5(self, a, b):            # Step 4 & 5
        a, b = a * 2, b * 3
        c, d = a * 10, b * 10              # Step 4
        result = c * d                      # Step 5
        assert result == c * d, f"Multiplication failed: {c} * {d} != {result}"

    @pytest.mark.parametrize("a, b", [(1, 2), (3, 4), (5, 6)])
    def test_step6(self, a, b):            # Step 6
        a, b = a * 2, b * 3
        result = a * a
        assert result == a * a, f"Square failed: {a}^2 != {result}"

在这个重构的版本中:

  • 每个测试用例都代表流程中的一个“步骤”。
  • 每个测试用例都接收参数化数据 a b
  • 每个测试用例都执行必要的设置(例如,计算 c d )并在其特定步骤的结果上进行断言。

这种方法使的测试用例相互独立,允许并行执行,并使的测试套件更易于理解和维护。

标签:python,python-3.x,pytest,hook,command-line-arguments
From: 78773786

相关文章

  • 当值来自函数 python unittest 时,如何模拟全局变量
    我必须在python中模拟全局变量,但变量值来自另一个函数。当我导入文件时,这个函数正在运行,但我想要那里的模拟值。secrets.pyimporttracebackimportloggingimportboto3importosimportjsonlogger=logging.getLogger()logger.setLevel(logging.INFO)secret_......
  • 使用 python print 和 gdb 时出现 BrokenPipeError
    我正在尝试在Linux中运行应用程序并使用Python生成输入:python3-c'print(".....")'|./someapp但出现下一个错误:Exceptionignoredin:<_io.TextIOWrappername='<stdout>'mode='w'encoding='utf-8'>BrokenPipeError:......
  • python 舰队容器
    我正在尝试使用容器在flet中制作一个菜单,它应该是半透明的,但其中的项目不是。我尝试将opacity=1分配给元素,但没有成功-它们与容器一样透明感谢任何帮助我的代码:nickname=ft.TextField(label="xxx",hint_text="xxx")column=ft.Column(controls=[nickname......
  • Python应用程序跨子包共享的配置文件
    我正在构建一个应用程序来控制一些硬件。我在包中实现了不同类型的硬件:电机和测量设备。我的文件结构如下:name_of_my_app/__init__.pymain.pyconfig.iniCONFIG.pymotors/__init__.pyone_kind_of_motor.pymeasurement_devices/......
  • python中时间序列数据的梯度计算
    我正在尝试编写一个函数,它可以从最适合下面的线返回梯度dataframe在浏览了谷歌的几个资源之后,我仍然不确定这是如何完成的。我明白最佳拟合线的计算公式为:y=mx+b将因变量(y)设置为foos,将自变量(x)设置为DateTimeDatafram......
  • 调试用 C 编写的 Python 扩展
    我非常熟悉编写C代码,并且很擅长编写Python代码。我正在尝试学习如何用C编写可以从OSX10.15.7上的Python-3.9.X调用的模块。我已经得到了几个“helloworld”类型的示例,但是对于复杂的示例,我正在努力弄清楚如何调试我编写的C扩展。MWE:src/add.c//......
  • 具有块大小选项的 Python pandas read_sas 因索引不匹配而失败并出现值错误
    我有一个非常大的SAS文件,无法容纳在我的服务器内存中。我只需要转换为镶木地板格式的文件。为此,我使用pandas中chunksize方法的read_sas选项分块读取它。它主要是在工作/做它的工作。除此之外,一段时间后它会失败并出现以下错误。此特定SAS文件有794......
  • 使用 requests 包 python 时打开文件太多
    我正在使用Pythonrequests包向API发出大量请求。然而,在某些时候,我的程序由于“打开的文件太多”而崩溃。当我明确关闭我的会话时,我真的不知道这是怎么回事。我使用以下代码:importrequestsimportmultiprocessingimportnumpyasnps=requests.session()s.keep......
  • Python 是一种选择性解释语言吗?为什么下面的代码不起作用?
    由于程序是从上到下运行的,为什么下面的代码不执行块中的第一行就直接抛出错误?if5>2:print("TwoislessthanFive!")print("Fiveisgreaterthantwo!")错误:文件“/Users/____/Desktop/Pythonpractise/practise.py”,第3行print("五比二大!")Indentati......
  • 裁剪时间变量 Python Matplotlib Xarray
    我不确定这是否是一个愚蠢的问题,但我想按时间变量剪辑.nc文件。我在xarray中打开了数据集,但以下ds.sel行(之前已运行)仅返回错误。ds=xr.open_dataset('/Users/mia/Desktop/RMP/data/tracking/mcs_tracks_2015_11.nc')selected_days=ds.sel(time=slice('2015-11-22',......