pytest:使用夹具和 pandas 数据框进行参数化

pytest: use fixture with pandas dataframe for parametrization

我有一个夹具,returns一个pd.DataFrame。我需要将单独的列 (pd.Series) 插入到单元测试中,我想使用 parametrize.

这是一个没有 parametrize 的玩具示例。数据框的每一列都将单独测试。但是,我想我可以摆脱 input_series 夹具,不是吗?使用此代码,只会执行 1 个测试。但是,我正在寻找 3 个测试,同时摆脱 for 循环。

import numpy as np
import pandas as pd
import pytest


@pytest.fixture(scope="module")
def input_df():
    return pd.DataFrame(
        data=np.random.randint(1, 10, (5, 3)), columns=["col1", "col2", "col3"]
    )


@pytest.fixture(scope="module")
def input_series(input_df):
    return [input_df[series] for series in input_df.columns]


def test_individual_column(input_series):
    for series in input_series:
        assert len(series) == 5

我基本上是在寻找这样的东西:

@pytest.mark.parametrize("series", individual_series_from_input_df)
def test_individual_column(series):
    assert len(series) == 5

如果您尝试根据另一个夹具从一个夹具生成多个数据,您将收到 yield_fixture function has more than one 'yield' 错误消息。

一种解决方案是使用 fixture parametrization。在您的情况下,您希望按列进行迭代,因此 Dataframe 列是参数。

# test data
input_df = pd.DataFrame(
    data=np.random.randint(1, 10, (5, 3)), columns=["col1", "col2", "col3"]
)


@pytest.fixture(
    scope="module",
    params=input_df.columns,
)
def input_series(request):
    series = request.param
    yield input_df[series]


def test_individual_column(input_series):
    assert len(input_series) == 5

这将按测试数据帧的列生成一个测试。

pytest test_pandas.py
# test_pandas.py::test_individual_column[col1] PASSED
# test_pandas.py::test_individual_column[col2] PASSED
# test_pandas.py::test_individual_column[col3] PASSED