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?
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.
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 =================================
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,
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")