【问题标题】:Why does Pytest perform a nested loop over fixture parameters为什么 Pytest 对夹具参数执行嵌套循环
【发布时间】:2020-07-08 01:30:49
【问题描述】:

使用 Pytest,我想编写一个测试函数,它接受多个夹具作为参数。每个灯具都有几个参数。

例如,在 test_demo.py 中有一个函数 test_squared_is_less_than_10,它以夹具 negative_integerpositive_integer 作为参数,然后检查夹具参数的平方是否小于 10。

import pytest

@pytest.fixture(params=[-1, -2, -3])
def negative_integer(request):
    return request.param

@pytest.fixture(params=[1, 2, 3])
def positive_integer(request):
    return request.param

def test_squared_is_less_than_10(negative_integer, positive_integer):
    assert negative_integer ** 2 < 10
    assert positive_integer ** 2 < 10

我希望当我在终端中运行 pytest 命令时,总共应该执行 6 个测试,即[-1, -2, -3] 用于positive_integer[1, 2, 3] 用于negative_integer

但是,pytest 似乎执行了一种嵌套循环的迭代,因此执行了 9 个测试 即[(-1, 1), (-1, 2), (-1, 3), (-2, 1), (-2, 2), (-2, 3), (-3, 1), (-3, 2), (-3, 3)]

这是我运行pytest -v -k "test_squared_is_less"时的输出:

test_squared_is_less_than_10[-1-1] PASSED                                                              
test_squared_is_less_than_10[-1-2] PASSED                                                              
test_squared_is_less_than_10[-1-3] PASSED                                                              
test_squared_is_less_than_10[-2-1] PASSED                                                              
test_squared_is_less_than_10[-2-2] PASSED                                                              
test_squared_is_less_than_10[-2-3] PASSED                                                              
test_squared_is_less_than_10[-3-1] PASSED                                                              
test_squared_is_less_than_10[-3-2] PASSED                                                              
test_squared_is_less_than_10[-3-3] PASSED 

这是不可取的,因为我只想执行 6 个测试而不是 9 个。如果参数数量较多(比如 20 个),pytest 将执行 400 个测试而不是所需的 40 个测试,这是浪费计算时间.

我该如何处理这个问题。

P.S:我想避免编写两个单独的测试,例如

test_negative_squared_is_less_than_10(negative_integer)test_positive_squared_is_less_than_10(positive_integer)

【问题讨论】:

    标签: python pytest fixtures


    【解决方案1】:

    您可以通过@pytest.mark.parametrize 标记应用非笛卡尔参数化。你的代码,重构:

    import pytest
    
    
    neg_params = [-1, -2, -3]
    
    @pytest.fixture(params=neg_params)
    def negative_integer(request):
        return request.param
    
    
    pos_params = [1, 2, 3]
    
    @pytest.fixture(params=pos_params)
    def positive_integer(request):
        return request.param
    
    
    @pytest.mark.parametrize(
        "negative_integer, positive_integer",
        zip(neg_params, pos_params),
        indirect=True
    )
    def test_squared_is_less_than_10(negative_integer, positive_integer):
        assert negative_integer ** 2 < 10
        assert positive_integer ** 2 < 10
    

    【讨论】:

    猜你喜欢
    • 2017-09-20
    • 2015-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-19
    • 1970-01-01
    相关资源
    最近更新 更多