[PYTHON] Donner les paramètres de nettoyage pytest pour le test unitaire du flacon

introduction

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.

environnement

Séparation du test et du prétraitement / post-traitement

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.

Source à tester

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

Source du prétraitement et du post-traitement

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()

Fonction de test

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

Résultat d'exécution

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.

Réutilisez la source de test avec plusieurs paramètres.

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 () ''.

Définition des paramètres de test

@ 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()

Fonction de test

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

Résultat d'exécution

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.

Essayez d'en échouer un

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é.

en conclusion

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

Donner les paramètres de nettoyage pytest pour le test unitaire du flacon
J'ai écrit un test unitaire pour différentes langues
Donner les paramètres de nettoyage pytest pour le test unitaire du flacon
Test unitaire Python
Comment faire un test unitaire Part.2 Conception de classe pour les tests
Test unitaire du flacon avec pytest
Obtenir les paramètres de requête pour Flask GET
J'ai écrit un test unitaire pour différentes langues
Test unitaire Python
Comment faire un test unitaire Part.2 Conception de classe pour les tests