J'ai un appareil de test avec une portée session qui est paramétrée, par ex.

@pytest.fixture(scope="session", params=["one", "two", "three"])
def myfixture():
    ...

Dans mon répertoire, j'ai des fichiers qui utilisent pytest.mark.usefixtures("myfixture") et un fichier qui contient des tests doit être exécuté uniquement pour myfixture avec le paramètre "two" et py.test doit le sauter sinon.

Existe-t-il des moyens d'y parvenir dans py.test ou dois-je définir une variable spéciale dans une classe de la fonction myfixture()?

8
DuXeN0N 15 juil. 2015 à 20:22

3 réponses

Meilleure réponse

Solution trouvée moi-même, on peut définir la fonction dans conftest.py:

def pytest_namespace():
    return {"param": None}

Et dans la fonction de luminaire, nous pouvons faire:

@pytest.fixture(scope="session", params=["one", "two", "three"])
def myfixture():
    pytest.param = request.param
    # ...

Nous pouvons donc envelopper la classe de test avec:

@pytest.mark.skipif("pytest.param == 'value'")
class TestSmth(object):
    ...
13
das-g 20 mai 2016 à 14:43

Pour ce faire, la méthode la plus simple consiste à utiliser le crochet pytest_collection_modifyitems pour modifier votre collection de tests avant leur exécution.

Compte tenu de votre appareil comme décrit:

@pytest.fixture(scope="session", params=["one", "two", "three"])
def myfixture(request):
    ...

Ajoutez une marque personnalisée à vos tests:

@pytest.mark.restriction("two")
def test_smth(self, myfixture):
    ...

Modifiez ensuite votre collection de tests avec une logique de désélection personnalisée:

def pytest_collection_modifyitems(items, config):
    """ deselect test items which do not match the fixture restriction """
    deselection_items = []
    for item in items:
        # There may be a better way than regex to get the parameter
        passed_param = re.search(r'\[(.+?)\]', item.name).group(1)
        restrictions = set([mark.args[0] for mark in item.iter_markers(name='restriction')])
        if len(restrictions) > 0:
            if passed_param not in restrictions:
                deselection_items.append(item)
    items[:] = [item for item in items if item not in deselection_items]
    config.hook.pytest_deselected(items=deselection_items)
0
Grant 30 avril 2019 à 20:24

Je suis tombé sur cette question en essayant de résoudre un cas d'utilisation similaire. Ma solution, au cas où cela aiderait quelqu'un à éviter quelques heures. C'est un moyen facile de remplacer le paramétrage d'un appareil à partir d'un test:

@pytest.fixture(scope="session", params=["one", "two", "three"])
def myfixture():
    ...

@pytest.mark.parameterize('myfixture', ['two'], indirect=True)
def test1(myfixture):
    ...

def test2(myfixture):
    ...

Merci à https://hackebrot.github.io/pytest-tricks/mark_parametrize_with_indirect/ pour expliquer l'utilisation de l'indirect!

0
Rob Buckley 11 sept. 2018 à 19:24