Почему Pytest выполняет вложенную l oop над параметрами прибора - PullRequest
4 голосов
/ 27 марта 2020

Используя Pytest, я хочу написать тестовую функцию, которая принимает в качестве аргументов несколько приборов. Каждый из приборов имеет несколько параметров.

Например, в test_demo.py есть функция test_squared_is_less_than_10, которая принимает приборы, negative_integer и positive_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, похоже, выполняет вложенную итерацию типа l oop, так что выполняется 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 тестов, что является пустой тратой вычислительного времени.

Как я могу решить эту проблему.

PS: Я бы хотел избежать написания двух отдельных тестов, таких как

test_negative_squared_is_less_than_10(negative_integer) и test_positive_squared_is_less_than_10(positive_integer)

1 Ответ

4 голосов
/ 27 марта 2020

Вы можете применить не декартову параметризацию с помощью маркера @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
...