En el artículo Pruebas unitarias locales de Python se explica cómo ejecutar pruebas unitarias para tu aplicación. Aunque las pruebas unitarias son muy útiles para probar las unidades independientes de tu código, la integración de esas unidades de código es lo que hace que tu aplicación funcione, por lo que las pruebas de integración son igual de importantes.
En las aplicaciones de App Engine, los controladores de solicitudes son puntos de integración críticos. Mientras que una aplicación WSGI dirige las solicitudes al controlador adecuado, el controlador en sí procesa los datos de la solicitud y genera una respuesta (consulte más información sobre los controladores de solicitudes). Los controladores de solicitudes son objetos de Python normales, como cualquier otra función o clase, lo que hace que sean fáciles de usar en pruebas automatizadas. Sin embargo, como una aplicación WSGI los envuelve como un shell, usaremos un shell similar en nuestras pruebas.
WebTest
En nuestras pruebas, utilizaremos el framework WebTest. WebTest es una biblioteca que te ofrece una interfaz sencilla para probar aplicaciones basadas en WSGI y, por lo tanto, los controladores de solicitudes. Para ello, envuelve una aplicación WSGI en una aplicación de prueba especial que se puede usar para hacer pruebas. WebTest te permite interactuar con tus controladores sin un entorno completo de App Engine. Puedes enviar solicitudes fácilmente y modificar el entorno de la solicitud. Las respuestas también tienen una interfaz compatible con las pruebas. No tienes que usar WebTest, pero sin duda te hará la vida mucho más fácil.
Antes de empezar, instala WebTest en tu máquina local o en el lugar donde quieras ejecutar las pruebas de controladores. Puedes consultar las instrucciones en http://webtest.pythonpaste.org/#installation.
Probar un controlador sencillo de "Hello World"
Vamos a empezar probando un controlador sencillo de "Hola, mundo" que responda a una solicitud de usuario con una respuesta de texto sin formato. La respuesta del controlador es "Hello World!" y el tipo de contenido es "text/plain":
import webapp2 import webtest class HelloWorldHandler(webapp2.RequestHandler): def get(self): # Create the handler's response "Hello World!" in plain text. self.response.headers['Content-Type'] = 'text/plain' self.response.out.write('Hello World!')
A continuación, crea el caso de prueba e inicializa una aplicación de prueba que use tu controlador:
... class AppTest(unittest.TestCase): def setUp(self): # Create a WSGI application. app = webapp2.WSGIApplication([('/', HelloWorldHandler)]) # Wrap the app with WebTest’s TestApp. self.testapp = webtest.TestApp(app) # Test the handler. def testHelloWorldHandler(self): response = self.testapp.get('/') self.assertEqual(response.status_int, 200) self.assertEqual(response.normal_body, 'Hello World!') self.assertEqual(response.content_type, 'text/plain')
Como puedes ver, WebTest te permite hacer solicitudes GET con una simple llamada get() (otros métodos de solicitud tienen métodos similares). El valor devuelto es un objeto de respuesta con el que puedes probar el código de estado, el cuerpo, el tipo de contenido y mucho más. Consulta la página principal de WebTest para ver una descripción detallada de todo lo que puedes hacer.
Crear una prueba de controlador que use un servicio de App Engine
Ahora, veamos cómo probar un controlador que usa un servicio de App Engine. Esto significa que ahora debemos ocuparnos de dos componentes que pueden afectar a nuestras pruebas: el controlador y el servicio que estamos usando. Como se describe en el artículo Pruebas unitarias locales de Python, la mejor forma de gestionar los servicios en las pruebas es usar testbed.
En el siguiente ejemplo se usa Memcache, pero el principio es el mismo para otros servicios, como Datastore o Task Queue.
El controlador que probamos almacena en caché la clave y el valor proporcionados. Ten en cuenta que analizamos ambos valores de los parámetros de la solicitud.
from google.appengine.api import memcache from google.appengine.ext import testbed import webapp2 import webtest class CacheHandler(webapp2.RequestHandler): def post(self): key = self.request.get('key') value = self.request.get('value') memcache.set(key, value)
En la prueba, al igual que antes, primero crea una aplicación y envuélvela con WebTest. Además, activa una instancia de Testbed y asegúrate de desactivarla después de la prueba.
... class AppTest(unittest.TestCase): def setUp(self): app = webapp2.WSGIApplication([('/cache/', CacheHandler)]) self.testapp = webtest.TestApp(app) self.testbed = testbed.Testbed() self.testbed.activate() def tearDown(self): self.testbed.deactivate() def testCacheHandler(self): # First define a key and value to be cached. key = 'answer' value = '42' self.testbed.init_memcache_stub() params = {'key': key, 'value': value} # Then pass those values to the handler. response = self.testapp.post('/cache/', params) # Finally verify that the passed-in values are actually stored in Memcache. self.assertEqual(value, memcache.get(key))
Cómo implementar un marco de pruebas
Puedes configurar un marco de pruebas si quieres. Las pruebas de controladores que usan WebTest se pueden ejecutar como las pruebas unitarias de App Engine. La única diferencia es que debes asegurarte de que tienes instalado WebTest.