web-dev-qa-db-fra.com

Puis-je effectuer plusieurs assertions dans pytest?

J'utilise pytest pour mes tests de sélénium et je voulais savoir s'il est possible d'avoir plusieurs assertions en un seul test?

J'appelle une fonction qui compare plusieurs valeurs et je veux que le test fasse rapport sur toutes les valeurs qui ne correspondent pas. Le problème que j'ai est que l'utilisation de "assert" ou "pytest.fail" arrête le test dès qu'il trouve une valeur qui ne correspond pas.

Existe-t-il un moyen de faire fonctionner le test et de signaler toutes les valeurs qui ne correspondent pas?

14
ChrisG29

Comme l'a commenté Jon Clements, vous pouvez remplir une liste de messages d'erreur, puis affirmer que la liste est vide, en affichant chaque message lorsque l'assertion est fausse.

concrètement, ça pourrait être quelque chose comme ça:

def test_something(self):
    errors = []

    # replace assertions by conditions
    if not condition_1:
        errors.append("an error message")
    if not condition_2:
        errors.append("an other error message")

    # assert no error message has been registered, else print messages
    assert not errors, "errors occured:\n{}".format("\n".join(errors))

Les assertions d'origine sont remplacées par des instructions if qui ajoutent des messages à une liste errors si les conditions ne sont pas remplies. Ensuite, vous affirmez que la liste errors est vide (une liste vide est False) et que le message d'assertion contient chaque message de la liste errors.


Vous pouvez également créer un générateur de test comme décrit dans la documentation nez . Je n'ai trouvé aucun doc pytest qui le décrit, mais je sais que pytest a géré cela exactement de la même manière que le nez.

18
Tryph

pytest-assume est "un plugin pytest qui permet plusieurs échecs par test" . Voici un exemple de la façon dont vous l'utiliseriez (tiré du README):

import pytest

@pytest.mark.parametrize(('x', 'y'), [(1, 1), (1, 0), (0, 1)])
def test_simple_assume(x, y):
    pytest.assume(x == y)
    pytest.assume(True)
    pytest.assume(False)

Même si certaines des affirmations échouent, elles sont toutes évaluées et signalées:

======================================== FAILURES =========================================
_________________________________ test_simple_assume[1-1] _________________________________
>    pytest.assume(False)
test_assume.py:7

y          = 1
x          = 1
----------------------------------------
Failed Assumptions:1
_________________________________ test_simple_assume[1-0] _________________________________
>    pytest.assume(x == y)
test_assume.py:5

y          = 0
x          = 1
>    pytest.assume(False)
test_assume.py:7

y          = 0
x          = 1
----------------------------------------
Failed Assumptions:2
_________________________________ test_simple_assume[0-1] _________________________________
>    pytest.assume(x == y)
test_assume.py:5

y          = 1
x          = 0
>    pytest.assume(False)
test_assume.py:7

y          = 1
x          = 0
----------------------------------------
Failed Assumptions:2
================================ 3 failed in 0.02 seconds =================================
8
akaihola

Voici une approche alternative appelée Assertion différée , Elle ressemble à peu près à ce que @Tryph a fourni et donne une meilleure trace de la pile.

Le package delay-assert sur PyPI implémente cette approche. Voir aussi le référentiel pr4bh4sh/python-delay-assert sur GitHub, ou installez à partir de PyPI en utilisant:

pip install delayed-assert

Vous pouvez utiliser (éventuellement) n'importe quelle bibliothèque d'assertions en combinaison avec python-delay-assert. Considérez-la plus comme une bibliothèque de gestionnaire de trace de pile plutôt qu'une assertion. Vérifiez this par exemple utilise

Voici à quoi ressemble la trace de la pile d'erreurs,

https://github.com/pr4bh4sh/python-delayed-assert/raw/master/sample.jpg

3
pr4bh4sh

encore une autre bibliothèque est disponible par l'auteur du livre Pragmatique sur le pytest 2017, Brian Okken. https://pythontesting.net/books/pytest/https://github.com/okken/pytest-check

import pytest_check as check

def test_example():
    a = 1
    b = 2
    c = [2, 4, 6]
    check.greater(a, b)
    check.less_equal(b, a)
    check.is_in(a, c, "Is 1 in the list")
    check.is_not_in(b, c, "make sure 2 isn't in list")
2
AnneTheAgile