[Selon https://stackoverflow.com/a/46369945/1021819 , le titre doit faire référence aux tests d'intégration plutôt qu'aux tests unitaires]
Supposons que je veuille tester les éléments suivants Flask API (from here )]:
import flask
import flask_restful
app = flask.Flask(__name__)
api = flask_restful.Api(app)
class HelloWorld(flask_restful.Resource):
def get(self):
return {'hello': 'world'}
api.add_resource(HelloWorld, '/')
if __name__ == "__main__":
app.run(debug=True)
Après avoir enregistré ceci en tant que flaskapi.py
Et l'exécuter, dans le même répertoire j'exécute le script test_flaskapi.py
:
import unittest
import flaskapi
import requests
class TestFlaskApiUsingRequests(unittest.TestCase):
def test_hello_world(self):
response = requests.get('http://localhost:5000')
self.assertEqual(response.json(), {'hello': 'world'})
class TestFlaskApi(unittest.TestCase):
def setUp(self):
self.app = flaskapi.app.test_client()
def test_hello_world(self):
response = self.app.get('/')
if __name__ == "__main__":
unittest.main()
Les deux tests réussissent, mais pour le second test (défini dans la classe TestFlaskApi
), je n'ai pas encore trouvé comment affirmer que la réponse JSON est telle que prévue (à savoir, {'hello': 'world'}
). En effet, il s’agit d’une instance de flask.wrappers.Response
(Qui est probablement essentiellement un objet Réponse de Werkzeug (cf. http://werkzeug.pocoo.org/docs/0.11/wrappers/ ) ), et je n’ai pas pu trouver d’équivalent de la méthode json()
pour requests
Response object.
Comment puis-je faire des assertions sur le contenu JSON de la seconde response
?
J'ai constaté que je pouvais obtenir les données JSON en appliquant json.loads()
à la sortie de la méthode get_data()
:
import unittest
import flaskapi
import requests
import json
import sys
class TestFlaskApiUsingRequests(unittest.TestCase):
def test_hello_world(self):
response = requests.get('http://localhost:5000')
self.assertEqual(response.json(), {'hello': 'world'})
class TestFlaskApi(unittest.TestCase):
def setUp(self):
self.app = flaskapi.app.test_client()
def test_hello_world(self):
response = self.app.get('/')
self.assertEqual(
json.loads(response.get_data().decode(sys.getdefaultencoding())),
{'hello': 'world'}
)
if __name__ == "__main__":
unittest.main()
Les deux tests réussissent comme souhaité:
..
----------------------------------------------------------------------
Ran 2 tests in 0.019s
OK
[Finished in 0.3s]
Flask fournit un client test_ que vous pouvez utiliser dans vos tests:
from source.api import app
from unittest import TestCase
class TestIntegrations(TestCase):
def setUp(self):
self.app = app.test_client()
def test_thing(self):
response = self.app.get('/')
assert <make your assertion here>
Ce que vous faites n’est pas un test unitaire. Dans tous les cas, lorsque vous utilisez la bibliothèque de requêtes ou le client flask, vous exécutez test d'intégration , vous effectuez des appels http réels sur les ordinateurs d'extrémité et testez l'interaction.
Le titre de la question ou l'approche est inexacte.
Avec Python3, j'ai eu l'erreur TypeError: the JSON object must be str, not bytes
. Il est nécessaire de décoder:
# in TestFlaskApi.test_hello_world
self.assertEqual(json.loads(response.get_data().decode()), {'hello': 'world'})
Cette question donne une explication.