#python #testing #iteration #pytest #late-binding
Вопрос:
Я пытаюсь pytest
перебирать функции, проблема поздней привязки заставляет pytest
применять тест только к последней функции.
Для упрощенного примера я создал следующий test.py
файл:
import pytest def func_1(x): return (x 10) def func_2(y): return (y-10) func_1_test_cases = {'func_1': (10, 20)} func_2_test_cases = {'func_2': (10, 0)} # Iterating over the functions for func in ['func_1', 'func_2']: @pytest.mark.parametrize('param, expected', globals()[func '_test_cases'].values(), ids=list(globals()[func '_test_cases'].keys())) def test(param, expected): eval(func '(param) == expected')
Я прочитал больше о проблеме поздней привязки и о практических предложениях, таких как:
def test(param, expected, func=func): eval(func '(param) == expected')
при использовании команды: pytest test.py -v
pytest
отчеты, собирающие только последнюю функцию в списке( func_2
):
плагины: тайм-аут-1.4.2, anyio-2.2.0, pudb-0.7.0 собрано 1 штука
1.py::тест[
func_2
] ПРОЙДЕНО [100%]============================================================================= 1 прошло за 0,01 с =============================================================================
func_1
никогда не собиралось
, похоже, проблема поздней привязки сложнее при использовании pytest
. Я ожидаю pytest
, что отчет соберет две функции и вернет их статус. Мне действительно нужно разобраться с этим.
Ответ №1:
Это не дает прямого ответа на ваш вопрос об определении нескольких тестов с одинаковым именем, но для конкретного примера, который вы опубликовали, было бы намного проще включить саму функцию в качестве одного из параметров теста:
import pytest def func_1(x): return (x 10) def func_2(y): return (y-10) @pytest.mark.parametrize( 'func,param,expected', [ pytest.param(func_1, 10, 20, id='func_1'), pytest.param(func_2, 10, 0, id='func_2'), ], ) def test(func, param, expected): assert func(param) == expected
Просто предупреждаю: у вашей тестовой функции нет assert
, поэтому она пройдет независимо от того, является ли eval(func '(param) == expected')
она истинной или ложной.
Комментарии:
1. Это не прямой ответ, но он вдохновил на правильный путь. К сожалению , кажется, что нет никакого способа зациклиться на параметризации pytest, и имя функции должно быть включено в список параметров.
Ответ №2:
Вдохновленный ответом Кейла, я считаю, что нет хорошего способа обойти pytest
parametize
декоратора (надеюсь, кто-нибудь поправит меня, если я ошибаюсь).
Единственное практическое решение-включить идентификаторы функций в список параметров.
Вот измененный код, близкий к тому, что я хотел.
import pytest def func_1(x): return (x 10) def func_2(y): return (y-10) func_test_cases = {'func_1': (10, 20, 'func_1'), 'func_2': (10, 3, 'func_2')} @pytest.mark.parametrize('param, expected, func', func_test_cases.values(), ids=func_test_cases.keys()) def test(param, expected, func): assert eval(func '(param) == expected')