Pytest genera pruebas basadas en argumentos

Nuevo en pytest

Tengo lo siguiente en conftest.py para recostackr un argumento del equipo desde la línea de comandos y leer un archivo de configuración de 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 

Quiero realizar una prueba en cada jugador dentro de conf [equipo] [‘jugadores’] (una lista). Puedo hacerlo de la siguiente manera en test_players.py:

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

Este tipo de trabajo funciona, ya que se repite en los jugadores, pero todo se trata como una prueba única. Si algo falla, toda la prueba se trata como fallida. Me gustaría que cada jugador sea probado por separado.

Si pongo los jugadores manualmente puedo hacer que esto funcione:

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

Así que mi problema es que no sé cómo hacer que conf [equipo] pase a pytest.mark.parametrize. He intentado esto, pero en ambos casos se queja de que conf no está definido.

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

y

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

¿Que me estoy perdiendo aqui?

El problema con su configuración es que desea parametrizar en conf[team] , pero conf debe definirse en el momento de la importación , porque ahí se ejecuta el decorador.

Por lo tanto, tendrá que realizar esta parametrización de manera diferente, utilizando las funciones de parametrización metafunc de pytest .

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

En el archivo yaml:

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

En el módulo de prueba:

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

En el confit de pytest:

 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, [])) 

Ahora ejecuta:

 pytest --team bobs 

Debería ver tres pruebas ejecutadas: dos pruebas que pasan (bob1, bob2) y una prueba que falla (papa). El uso de pytest --team pauls hará una prueba fallida. El uso de pytest --team bogus resultará en una prueba omitida. Si desea un comportamiento diferente, cambie el teams.get(team_name, []) a, por ejemplo, teams[team_name] .