unit - testing en python
Cómo aplicar pruebas de integración(en lugar de pruebas unitarias) a una API RESTful de Flask (4)
[Según https://stackoverflow.com/a/46369945/1021819 , el título debe referirse a pruebas de integración en lugar de pruebas unitarias]
Supongamos que me gustaría probar la siguiente API de Flask (desde 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)
Después de guardar esto como flaskapi.py
y ejecutarlo, en el mismo directorio ejecuto el 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()
Ambas pruebas pasan, pero para la segunda prueba (definida en la clase TestFlaskApi
) aún no he descubierto cómo afirmar que la respuesta JSON es la esperada (a saber, {''hello'': ''world''}
). Esto se debe a que es una instancia de flask.wrappers.Response
(que probablemente es esencialmente un objeto de Respuesta Werkzeug (consulte http://werkzeug.pocoo.org/docs/0.11/wrappers/ )), y no he sido capaz de encontrar un equivalente del método json()
para las requests
Objeto de Response .
¿Cómo puedo hacer afirmaciones sobre el contenido JSON de la segunda response
?
Con Python3, obtuve el error TypeError: the JSON object must be str, not bytes
. Se requiere para decodificar:
# in TestFlaskApi.test_hello_world
self.assertEqual(json.loads(response.get_data().decode()), {''hello'': ''world''})
Esta pregunta da una explicación.
Descubrí que puedo obtener los datos JSON aplicando json.loads()
a la salida del método 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()
Ambas pruebas pasan como se desea:
..
----------------------------------------------------------------------
Ran 2 tests in 0.019s
OK
[Finished in 0.3s]
Flask proporciona un test_client que puedes usar en tus pruebas:
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>
Lo que estás haciendo allí no es una prueba de unidad. En todos los casos, al utilizar la biblioteca de solicitudes o el cliente del matraz, está realizando pruebas de integración a medida que realiza llamadas http reales a los puntos finales y prueba la interacción.
El título de la pregunta o el enfoque no son precisos.