google gae engine app python unit-testing google-app-engine

gae - ¿Qué enfoque(s) has utilizado para pruebas ligeras de la unidad de Python en App Engine?



gae python libraries (6)

Estoy a punto de emprender algunos grandes proyectos de App Engine basados ​​en Python, y creo que debería consultar con "la sabiduría de las multitudes" de Stack Overflow antes de comprometerme con una estrategia de pruebas de unidades. Tengo un marco de pruebas de unidades existente (basado en unittest con corredores personalizados y extensiones) que quiero usar, por lo que cualquier elemento "pesado" / "intrusivo" como nose , webtest o gaeunit no parece apropiado. Las pruebas de unidad cruciales en mi visión del mundo son extremadamente ligeras y rápidas, que se ejecutan en un tiempo extremadamente corto, así que puedo seguir ejecutándolas una y otra vez sin romper mi ritmo de desarrollo (por ejemplo, para un proyecto diferente, me sale 97% o más de cobertura para un proyecto de 20K-líneas con varias docenas de pruebas súper rápidas que toman 5-7 segundos, tiempo transcurrido, para una carrera típica, en general, eso es lo que considero una suite decente de unidades pequeñas y rápidas pruebas). Tendré pruebas más ricas / pesadas, por supuesto, hasta pruebas de integración con selenio o molino de viento, eso no es lo que estoy preguntando ;-) - mi enfoque en esta pregunta (y en la mayoría de mis esfuerzos de desarrollo) ;-) está en las pruebas de unidad pequeñas y livianas que cubren mi código de forma ligera y súper rápida, no en las más profundas.

Así que creo que lo que necesito es esencialmente un conjunto de simulaciones pequeñas y livianas de los diversos subsistemas clave de App Engine: almacenamiento de datos, Memcache, objetos de solicitud / respuesta y llamadas a los manejadores de aplicaciones web, manejo del usuario, correo, yc, más o menos en este orden de prioridad. No he encontrado exactamente lo que estoy buscando, así que me parece que debería confiar en mox , como lo he hecho a menudo en el pasado, lo que básicamente significa burlarse de cada subsistema utilizado en una prueba determinada y configurarlo. todas las expectativas & c (fuerte, pero con mucho trabajo cada vez, y muy sensible a las partes internas del código probado, es decir, muy "white-box" y), o rodar mi propia simulación de cada subsistema (y hacer afirmaciones sobre los subsistemas simulados '' estados como parte de las pruebas unitarias). Los últimos parecen factibles, dada la fuerte arquitectura de "fragmentos" de GAE en el lado de Python ... pero no puedo creer que tenga que rolar el mío, es decir, ¡que nadie ya haya escrito simuladores tan simples! -) Por ejemplo, para el almacén de datos , parece que lo que necesito es más o menos el apéndice "almacén de datos en el archivo" que ya forma parte del SDK, además de una forma de marcarlo como accesadores de solo lectura y fáciles de usar para las afirmaciones sobre el estado del almacén de datos; y así sucesivamente, subsistema por subsistema: cada uno parece necesitar "solo un poco más" que lo que ya está en el SDK, "encaramado en la parte superior" de la arquitectura existente "stubs".

Entonces, antes de sumergirme y pasar uno o dos días de preciadas simulaciones de los subsistemas de GAE "rodando por mi cuenta" para pruebas de unidades, pensé en verificar con la multitud SO y ver qué piensan ustedes de esto. .. o, si ya existe algún conjunto de simuladores de código abierto que simplemente puedo volver a utilizar (¡o retocar mínimamente! -), y que no he podido detectar en mi búsqueda! -)

Edición : para aclarar, si hago mi propia versión, planeo aprovechar los talones provistos por SDK cuando sea posible; pero, por ejemplo, no hay un resguardo para un almacén de datos que inicialmente se lee desde un archivo, pero que luego no se guarda al final, así que debo crear una subclase y ajustar el existente (que tampoco ofrece formas particularmente convenientes de hacer afirmaciones sobre él). estado - lo mismo para el talón del servicio de correo, etc.). ¡Eso es lo que quiero decir con "rodar lo mío" - no "reescribir desde cero"! -)

Editar : "por qué no GAEUnit" - GAEUnit es bueno para sus propios casos de uso, pero ejecutar dev_appserver y ver los resultados en mi navegador (o incluso a través de urllib.urlopen) definitivamente no es lo que busco - Quiero usar un configuración completamente automatizada, adecuada para ejecutarse dentro de un marco de ejecución de prueba existente que se basa en ampliar unittest y sin HTTP en el camino (dicho framework define una prueba "rápida" como aquella que entre otras cosas no tiene sockets y disco mínimo I / O - simulamos o simulamos esto, así que a través de gaeunit no pude hacer nada mejor que las pruebas "medianas" + ninguna forma conveniente de rellenar previamente el almacén de datos para cada prueba (y ninguna estructura OO para ayudar a personalizar las cosas).


Desde la versión 1.3.1 del SDK, existe el marco de prueba unitario incorporado .

Es Java solo ahora pero me siento como:

  1. es mucho lo mismo de lo que hablas en tu pregunta (y mucho más, como ejecutar una prueba en la nube, por ejemplo)
  2. y es bastante posible port / implementar lo mismo en Python usando SDK

Lo mismo ocurre con el autor de este marco: Max Ross y él nos lo cuenta explícitamente en su presentación de E / S "Técnicas de prueba para Google App Engine".

¿Alguien tiene alguna actualización sobre este tema?


La API SDK 1.4.3 Testbed proporciona una configuración sencilla de las bibliotecas stub para las pruebas de integración local.


No es necesario que escriba sus propios códigos: el SDK los incluye, ya que son lo que usa para emular las API de producción. No todos son adecuados para su uso en pruebas unitarias, pero la mayoría sí lo son. Echa un vistazo a este código para ver un ejemplo del código de instalación / desmontaje que necesitas para usar los talones integrados.


También podría agregar que Fixture ha sido muy útil en mis pruebas unitarias. Le permite crear modelos en una sintaxis declarativa, que convierte en entidades almacenadas que puede cargar en sus pruebas. De esta forma, tendrá el mismo conjunto de datos al comienzo de cada caso de prueba !, lo que le ahorrará tener que crear datos a mano al comienzo de cada prueba. Aquí hay un ejemplo de la documentación de Fixture: dado este modelo:

from google.appengine.ext import db class Entry(db.Model): title = db.StringProperty() body = db.TextProperty() added_on = db.DateTimeProperty(auto_now_add=True)

Su accesorio se vería así:

from fixture import DataSet class EntryData(DataSet): class great_monday: title = "Monday Was Great" body = """/ Monday was the best day ever. """

Sin embargo, tenga en cuenta que me encontré con los siguientes problemas: 1. Este error , pero el parche incluido lo soluciona. 2. El almacén de datos no se restablece, por defecto, entre los casos de prueba. Así que uso esto para forzar un reinicio para cada caso de prueba:

class TycoonTest(unittest.TestCase): def setUp(self): # Clear out the datastore before starting the test. apiproxy_stub_map.apiproxy._APIProxyStubMap__stub_map[''datastore_v3''].Clear() self.data = self.load_data() self.data.setup() os.environ[''SERVER_NAME''] = "dev_appserver" self.after_setUp() def load_data(self): return datafixture.data(*dset.__all__) def after_setUp(self): """ After setup """ pass def tearDown(self): # Teardown data. try: self.data.teardown() except: pass


Uso GAEUnit para mi aplicación Google App Engine y estoy muy contento con la velocidad de las pruebas. Lo que más me gusta de GAEUnit, y estoy seguro de que Webtest lo hace, es que crea su propia versión para los stubs de todo para probar y deja sus versiones "en vivo" para probar.

Por lo tanto, su almacén de datos que pueda estar utilizando para el desarrollo quedará como está cuando ejecuta sus GAETests.


NoseGAE es un plugin de nariz que admite NoseGAE configurando automáticamente el entorno de desarrollo y un almacén de datos de prueba para usted. Muy útil cuando se desarrolla en dev_appserver.