La dernière fois, j'ai utilisé pytest pour faire un test unitaire de flacon. Cependant, cela est devenu très difficile à voir car j'ai créé et testé le client flask dans une fonction de test. Cette fois, nous utiliserons diverses fonctions de pytest pour rendre le test un peu plus facile à voir.
J'avais l'habitude de combiner le client flask et la source de test en une seule fonction, mais cela devient difficile à voir à mesure que le nombre de fonctions de test augmente. De plus, à proprement parler, la création d'un client n'est pas un test, il n'est donc pas bon d'être influencé par les tests de performance et les résultats des fonctions. Par conséquent, la création / suppression de client est séparée du test.
La source à tester utilise la source du flacon précédent.
flask_mod.py
from flask import Flask, jsonify
app = Flask(__name__)
@app.route('/')
def root():
return "root"
@app.route('/sample/<message>')
def sample(message):
return 'sample_' + message
Créez des fonctions de pré et post-traitement et enregistrez-les avec les décorations
@ pytest.fixture '' Il s'agit d'une image dans laquelle la fonction de test est intégrée au rendement de cette fonction. Le prétraitement est décrit avant le rendement et le post-traitement est décrit après le rendement.
Dans l'exemple, un client de test est généré et donné à yield. Après cela, la suppression est utilisée pour supprimer le client.
pytest_flask.py
@pytest.fixture
def client():
app.config['TESTING'] = True
test_client = app.test_client()
yield test_client
test_client.delete()
Créez une fonction de test et spécifiez l'argument qui reçoit la valeur donnée à yield dans la source du prétraitement et du post-traitement. Cet argument doit avoir le même nom que les fonctions de prétraitement et de post-traitement. Après cela, la source de test est décrite normalement. Dans l'exemple, la fonction `` test_flask_simple () '' a un argument qui reçoit le client généré par fixture, et get est émis pour le test.
pytest_flask.py
import pytest
from flask_mod import app
@pytest.fixture
def client():
app.config['TESTING'] = True
test_client = app.test_client()
yield test_client
test_client.delete()
def test_flask_simple(client):
result = client.get('/')
assert b'root' == result.data
Maintenant que vous avez la source de la cible de test et de la méthode de test, exécutez-la.
PS C:\Users\xxxx\program\python> pytest .\pytest_flask.py
======= test session starts ========
platform win32 -- Python 3.6.5, pytest-5.3.5, py-1.8.1, pluggy-0.13.1
rootdir: C:\Users\xxxx\program\python\flask
collected 1 item
pytest_flask.py . [100%]
======== 1 passed in 0.21s =========
En regardant le résultat, le pytest_flask créé précédemment est de 100% et il se termine normalement. Le test était OK et j'ai réussi à créer et à détruire le client à l'aide de fixture.
Vous souhaitez souvent créer une source de test et la tester avec différents arguments. Dans ce cas, inscrivez-vous avec l'argument param
de la décoration
@ pytest.fixture () ''.
@ pytest.fixture () '' Les paramètres du décorateur des fonctions de pré-traitement et de post-traitement décrivent les paramètres de test dans un format de liste tuple. Préparez un argument dans la fonction pour recevoir ces paramètres et donnez param avec yield. Dans l'exemple, la source testée est
sample (message) '', nous définissons donc les paramètres à donner au flacon en premier dans le taple et mettons la réponse dans le second.
pytest_flask.py
@pytest.fixture(params=[('message', b'sample_message'),('sample', b'sample_sample')])
def client(request):
app.config['TESTING'] = True
test_client = app.test_client()
yield test_client, request.param
test_client.delete()
Puisque la valeur donnée par yield '' dans les fonctions de prétraitement et de post-traitement est incluse dans l'argument de la fonction de test sous forme de taple, les éléments nécessaires sont extraits et utilisés. Dans l'exemple, le premier de l'argument
client` `` contient le client, et le second contient l'un des tapples donnés dans les paramètres, donc nous l'extrayons et l'utilisons pour l'URL et la confirmation du résultat.
pytest_flask.py
import pytest
from flask_mod import app
@pytest.fixture(params=[('message', b'sample_message'),('sample', b'sample_sample')])
def client(request):
app.config['TESTING'] = True
test_client = app.test_client()
yield test_client, request.param
test_client.delete()
def test_flask_simple(client):
test_client = client[0]
test_param = client[1]
result = test_client.get('/sample/' + test_param[0])
assert test_param[1] == result.data
Maintenant que vous avez la source de la cible de test et de la méthode de test, exécutez-la.
PS Users\xxxx\program\python> pytest -v .\pytest_flask.py
======= test session starts ========
platform win32 -- Python 3.6.5, pytest-5.3.5, py-1.8.1, pluggy-0.13.1 -- c:\users\xxxx\appdata\local\programs\python\python36-32\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\xxxx\program\python\flask
collected 2 items
pytest_flask.py::test_flask_simple[client0] PASSED [ 50%]
pytest_flask.py::test_flask_simple[client1] PASSED [100%]
======== 2 passed in 0.20s =========
En regardant le résultat, la fonction test_flask_simple créée précédemment est PASSÉE deux fois. Cela signifie que j'ai donné deux taples dans l'appareil, alors je l'ai testé deux fois et les deux étaient OK.
Pour vous assurer que les valeurs sont correctement transmises, donnez une valeur incorrecte à une seule d'entre elles.
PS Users\xxxx\program\python> pytest -v .\pytest_flask.py
======= test session starts ========
platform win32 -- Python 3.6.5, pytest-5.3.5, py-1.8.1, pluggy-0.13.1 -- c:\users\xxxx\appdata\local\programs\python\python36-32\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\xxxx\program\python\flask
collected 2 items
pytest_flask.py::test_flask_simple[client0] FAILED [ 50%]
pytest_flask.py::test_flask_simple[client1] PASSED [100%]
============= FAILURES =============
_______ test_flask_simple[client0] _______
client = (<FlaskClient <Flask 'flask_mod'>>, ('message', b'sample_detail'))
def test_flask_simple(client):
test_client = client[0]
test_param = client[1]
result = test_client.get('/sample/' + test_param[0])
> assert test_param[1] == result.data
E AssertionError: assert b'sample_detail' == b'sample_message'
E At index 7 diff: b'd' != b'm'
E Full diff:
E - b'sample_detail'
E + b'sample_message'
pytest_flask.py:17: AssertionError
============= 1 failed, 1 passed in 0.27s =============
Lorsque j'ai donné une valeur qui n'a échoué qu'une seule, l'une des fonctions est devenue FAILED et a échoué.
Le pytest résumé ici n'est qu'une petite partie de la fonctionnalité. En plus de cela, il existe des fonctions plus pratiques telles qu'une fonction pour créer automatiquement une combinaison de paramètres et une fonction pour enregistrer les données. Cependant, comme c'est le cas cette fois, il y a quelques bizarreries à l'utiliser, et vous pouvez le trouver difficile à utiliser à première vue. Cependant, il dispose de nombreuses fonctions pratiques et faciles à utiliser, de sorte que plus vous vous y habituerez, plus tôt vous pourrez créer une variété de tests. La façon de vérifier la couverture fournie avec les tests unitaires est résumée dans Vérification de la couverture python avec pytest-cov.
Recommended Posts