Pytest генерирует тесты на основе аргументов

новое в pytest...

у меня есть следующее conftest.py чтобы собрать командный аргумент из командной строки и прочитать в конфигурационном файле yaml:

import pytest
import yaml


def pytest_addoption(parser):
    parser.addoption(
        '--team',
        action='store',
        )


@pytest.fixture
def team(request):
    return request.config.getoption('--team')


@pytest.fixture
def conf(request):
    with open('config.yml', 'r') as f:
        conf = yaml.load(f.read())
    return conf

Я хочу запустить тест на каждого игрока внутри conf[team] ['players'] (список). Я могу сделать это следующим образом: test_players.py:

def test_players(team, conf):
    players = conf[team]['players']
    for p in players:
        assert p == something

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

если я поставлю игроков вручную, я могу заставить это работать:

import pytest

class Test_Player():
    @pytest.mark.parametrize(
        'player', [
            'player1',
            'player2',
            'player3',
        ],
    )
    def test_player(self, player):
        assert player == something

Итак, моя проблема в том, что я не знаю, как заставить conf[team] перейти в pytest.отметка.параметризовать. Я пробовал это, но в обоих случаях он жалуется, что conf не определен.

import pytest

class Test_Player():
    @pytest.mark.parametrize(
        'player', conf[team]['players'],
    )
    def test_player(self, player):
        assert player == something

и

import pytest

class Test_Player(team, conf):
    @pytest.mark.parametrize(
        'player', conf[team]['players'],
    )
    def test_player(self, player):
        assert player == something

что я пропустила?

1 ответов


проблема с вашей настройкой заключается в том, что вы хотите параметризовать на conf[team], а conf необходимо определить в импорт время, потому что именно тогда декоратор выполняет.

таким образом, вы будете иметь, чтобы идти по этому поводу параметризации по-другому, с помощью pytest по параметризация metafunc функции.

.
├── conftest.py
├── teams.yml
└── test_bobs.py

в файле yaml:

# teams.yml
bobs: [bob1, bob2, potato]
pauls: [paultato]

в тестовом модуле:

# test_bobs.py
def test_player(player):
    assert 'bob' in player

в pytest conf:

import pytest
import yaml


def pytest_addoption(parser):
    parser.addoption('--team', action='store')


def pytest_generate_tests(metafunc):
    if 'player' in metafunc.fixturenames:
        team_name = metafunc.config.getoption('team')

        # you can move this part out to module scope if you want
        with open('./teams.yml') as f:
            teams = yaml.load(f)

        metafunc.parametrize("player", teams.get(team_name, []))

теперь выполните:

pytest --team bobs

вы должны увидеть три выполненных теста: два теста прохождения (bob1, bob2) и один неудачный тест (картофель). Используя pytest --team pauls сделает один неудачный тест. Используя pytest --team bogus приведет к пропущенному тесту. Если вы хотите другое поведение там, измените teams.get(team_name, []), например, teams[team_name].