Смешивание параметризованных тестов и оценок - PullRequest
0 голосов
/ 21 мая 2018

Хорошо, я борюсь с чем-то, что буквально поражает меня.

Несмотря на то, что мой настоящий код отличается, это, в основном, устраняет проблему.Предположим, этот пример кода:

import pytest

@pytest.mark.parametrize('type',(
    pytest.param('stability', marks=pytest.mark.stability),
    pytest.param('integration', marks=pytest.mark.integration),
))
@pytest.mark.integration
@pytest.mark.stability
def test_meh(type):
    assert type == 'integration'

И ниже приведен результат выполнения этого теста.

$pytest -m integration test_meeh.py
========================================================= test session starts =========================================================
platform darwin -- Python 3.6.4, pytest-3.1.2, py-1.5.2, pluggy-0.4.0
rootdir: /Users/yzT/Desktop, inifile:
collected 2 items

test_meeh.py F

============================================================== FAILURES ===============================================================
_________________________________________________________ test_meh[stability] _________________________________________________________

type = 'stability'

    @pytest.mark.parametrize('type',(
        pytest.param('stability', marks=pytest.mark.stability),
        pytest.param('integration', marks=pytest.mark.integration),
    ))
    @pytest.mark.integration
    @pytest.mark.stability
    def test_meh(type):
>       assert type == 'integration'
E       AssertionError: assert 'stability' == 'integration'
E         - stability
E         + integration

test_meeh.py:10: AssertionError
========================================================= 1 tests deselected ==========================================================
=============================================== 1 failed, 1 deselected in 0.07 seconds ================================================


$ pytest -m stability test_meeh.py
========================================================= test session starts =========================================================
platform darwin -- Python 3.6.4, pytest-3.1.2, py-1.5.2, pluggy-0.4.0
rootdir: /Users/yzT/Desktop, inifile:
collected 2 items

test_meeh.py .

========================================================= 1 tests deselected ==========================================================
=============================================== 1 passed, 1 deselected in 0.02 seconds ================================================

Что здесь происходит?Почему, когда я использую -m integration, он использует stability, а когда я использую -m stability, он использует integration?

1 Ответ

0 голосов
/ 22 мая 2018

Похоже, есть две проблемы с предоставленным вами примером кода.

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

Вот минимальное сравнение.Как с отметками о функциональных, так и с индивидуальными параметризованными тестами:

# parametrized_tests.py
import pytest
@pytest.mark.parametrize('smiley', [
    pytest.param(':)', marks=[pytest.mark.happy]),
    pytest.param(':(', marks=[pytest.mark.unhappy]),
])
@pytest.mark.happy
@pytest.mark.unhappy
def test_meh(smiley):
    assert smiley == ':)'

У вас будет собрано и выбрано два теста:

$ pytest -m happy --collect-only parametrized_tests.py
========================================================================================== test session starts ===========================================================================================
platform darwin -- Python 3.6.5, pytest-3.5.1, py-1.5.3, pluggy-0.6.0
rootdir: [redacted], inifile:
collected 2 items
<Module 'params-individual-tests.py'>
  <Function 'test_smiley[:)]'>
  <Function 'test_smiley[:(]'>

====================================================================================== no tests ran in 0.01 seconds ======================================================================================

Но если отмечены только параметризованные тесты:

# parametrized_tests.py
import pytest

@pytest.mark.parametrize('smiley', [
    pytest.param(':)', marks=[pytest.mark.happy]),
    pytest.param(':(', marks=[pytest.mark.unhappy]),
])
def test_smiley(smiley):
    assert smiley == ':)'

Вы получите два собранных теста, но, как вы ожидаете, будет выбран только один:

$ pytest -m happy --collect-only parametrized_tests.py
========================================================================================== test session starts ===========================================================================================
platform darwin -- Python 3.6.5, pytest-3.5.1, py-1.5.3, pluggy-0.6.0
rootdir: [redacted], inifile:
collected 2 items / 1 deselected
<Module 'params-individual-tests.py'>
  <Function 'test_smiley[:)]'>

====================================================================================== 1 deselected in 0.01 seconds ======================================================================================

Во-вторых, в * есть недооцененная ошибка (или недокументированная "особенность") в pytest.param , где использование точного имени метки в качестве значения параметра делает тест не выбранным.

Из вашего (слегка измененного) кода:

# mark_name.py
import pytest

@pytest.mark.parametrize('type_', [
    pytest.param('integration', marks=[pytest.mark.integration]),
    pytest.param('stability', marks=[pytest.mark.stability]),
])
def test_meh(type_):
    assert type_ == 'integration'

Если я попытаюсь запустить только тесты integration, он не выберет ни одного:

$ pytest -m integration mark_name.py
========================================================================================== test session starts ===========================================================================================
platform darwin -- Python 3.6.5, pytest-3.5.1, py-1.5.3, pluggy-0.6.0
rootdir: [redacted], inifile:
collected 2 items / 2 deselected

Но простое изменение значения (в данном случае я только прописал его в верхнем регистре) заставляет все работать как положено:

# mark_name.py
import pytest

@pytest.mark.parametrize('type_', [
    pytest.param('INTEGRATION', marks=[pytest.mark.integration]),
    pytest.param('STABILITY', marks=[pytest.mark.stability]),
])
def test_meh(type_):
    assert type_ == 'INTEGRATION'

И теперь я могу правильно выбрать тесты:

$ pytest -m integration mark_name.py
========================================================================================== test session starts ===========================================================================================
platform darwin -- Python 3.6.5, pytest-3.5.1, py-1.5.3, pluggy-0.6.0
rootdir: [redacted], inifile:
collected 2 items / 1 deselected

mark_name.py .                                                                                                                                                                                     [100%]

================================================================================= 1 passed, 1 deselected in 0.01 seconds =================================================================================
$ pytest -m stability mark_name.py
========================================================================================== test session starts ===========================================================================================
platform darwin -- Python 3.6.5, pytest-3.5.1, py-1.5.3, pluggy-0.6.0
rootdir: [redacted], inifile:
collected 2 items / 1 deselected

mark_name.py F                                                                                                                                                                                     [100%]

================================================================================================ FAILURES ================================================================================================
__________________________________________________________________________________________ test_meh[STABILITY] ___________________________________________________________________________________________

type_ = 'STABILITY'

    @pytest.mark.parametrize('type_', [
        pytest.param('INTEGRATION', marks=[pytest.mark.integration]),
        pytest.param('STABILITY', marks=[pytest.mark.stability]),
    ])
    def test_meh(type_):
>       assert type_ == 'INTEGRATION'
E       AssertionError: assert 'STABILITY' == 'INTEGRATION'
E         - STABILITY
E         + INTEGRATION

mark_name.py:9: AssertionError
================================================================================= 1 failed, 1 deselected in 0.08 seconds =================================================================================

Я подозреваю, что это связано со строковым значением, используемым в качестве идентификатора теста, но предлагает открыть GitHub Issue Если это то, что вы не хотитечтобы обойти.


Кроме того, совершенно не связаны, но лучше не определять аргумент как type, потому что вы скрываете встроенную функцию type. PEP-8 предлагает использовать конечное подчеркивание для предотвращения конфликта имен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...