如何在pytest参数化参数中使用fixture值

问题描述 投票:0回答:1

我想在参数化参数中使用一个名为“time_period”的装置。该装置返回一个 TimePeriod 对象,该对象存储 2 个日期“开始”和“结束”。我需要编写一个测试来检查我的函数“filter_data_by_time_horizon”是否删除了 pyspark 数据帧中给定时间段之外的所有行。为此,我想参数化我的测试以覆盖所有边缘情况:

@pytest.mark.parametrize("date_from, date_to", [
             (time_period.start - relativedelta(days=4), time_period.start - relativedelta(days=2)),
             (time_period.end + relativedelta(days=4), time_period.end + relativedelta(days=2)),
    ])
def test_filter_data_by_time_horizon(factory, date_from, date_to):
    test_data = filter_data_by_time_horizon(factory_batch_to_dataframe(factory.create_batch(
        size=2,
        date_from=date_from,
        date_to=date_to,
    )))
    assert test_data.count() == 0

但是我无法按照我在代码中编写的方式使用 time_period 固定装置。我可以从技术上将其声明为测试用例之外的变量,但这似乎不是一个干净的解决方案。顺便说一句,time_period 固定装置存储在模块范围conftest.py 中。 我该如何干净利落地处理它?

python pyspark pytest factory-boy
1个回答
0
投票

您可以创建一个间接夹具,在返回您将在测试函数中使用的参数之前进行计算。这是一个未经测试的草稿,应该可以让您了解如何处理它:

from functools import reduce
from operator import add, sub

@pytest.fixture()
def time_horizon(time_period, request):
    tp = getattr(time_period, request.param[0])
    tp_from = reduce(request.param[1], (tp, relativedelta(days=request.param[3])))
    tp_to = reduce(request.param[1], (tp, relativedelta(days=request.param[5])))

    return (tp_from, tp_to)

@pytest.mark.parametrize("time_horizon", [('start', sub, 4, 2), ('end', add, 4, 2)], indirect=True)
def test_filter_data_by_time_horizon(time_horizon, factory):
    test_data = filter_data_by_time_horizon(factory_batch_to_dataframe(factory.create_batch(
        size=2,
        date_from=time_horizon[0],
        date_to=time_horizon[1],
    )))
    assert test_data.count() == 0

参数化中的关键元素是

indirect=True
,它会导致调用
time_horizon
夹具,而夹具中的
request.param
则允许您访问可变参数。

© www.soinside.com 2019 - 2024. All rights reserved.