Pytest基于参数生成测试

问题描述 投票:8回答:1

新的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.mark.parametrize。我尝试过这些,但在这两种情况下都抱怨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

我在这里错过了什么?

python pytest
1个回答
3
投票

您的设置问题是您想要在conf[team]上进行参数化,但需要在导入时定义conf,因为那是装饰器执行时的情况。

因此,您必须使用pytest的metafunc parametrization功能以不同方式进行此参数化。

.
├── 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]

© www.soinside.com 2019 - 2024. All rights reserved.