Test degli handler per Python 2

L'articolo Test locali delle unità per Python descrive come eseguire i test delle unità per la tua applicazione. Sebbene i test delle unità siano ottimi per testare le unità separate del codice, l'integrazione di queste unità di codice è ciò che consente all'applicazione di funzionare, pertanto i test di integrazione sono altrettanto importanti.

Per le applicazioni App Engine, i gestori delle richieste sono punti di integrazione critici. Mentre un'applicazione WSGI inoltra le richieste all'handler corretto, è lo stesso handler a elaborare i dati della richiesta e a generare una risposta (scopri di più sugli handler di richiesta). I gestori delle richieste sono normali oggetti Python come qualsiasi altra funzione o classe, il che li rende facili da utilizzare nei test automatici. Tuttavia, poiché un'applicazione WSGI le racchiude come una shell, utilizzeremo una shell simile nei nostri test.

WebTest

Per i nostri test, utilizzeremo il framework WebTest. WebTest è una biblioteca che offre un'interfaccia semplice per testare le applicazioni basate su WSGI e quindi i gestori delle richieste. A tal fine, avvolge un'applicazione WSGI in un'app di test speciale che può essere utilizzata per i test. WebTest ti consente di interagire con i gestori senza un ambiente App Engine completo; puoi inviare facilmente richieste e modificare l'ambiente delle richieste. Le risposte hanno anche un'interfaccia adatta ai test. Non è obbligatorio utilizzare WebTest, ma sicuramente ti semplifica la vita.

Prima di iniziare, installa WebTest sulla tua macchina locale o dove intendi eseguire i test degli handler. Le istruzioni sono disponibili all'indirizzo http://webtest.pythonpaste.org/#installation

Test di un gestore "Hello World" semplice

Iniziamo testando un semplice gestore "Hello World!" che risponde a una richiesta dell'utente con una risposta in testo normale. La risposta dell'handle è "Hello World!" e il tipo di contenuto è "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 questo punto, crea il caso di test e inizializza un'applicazione di test che utilizza il tuo gestore:

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

Come puoi vedere, WebTest ti consente di effettuare richieste GET con una semplice chiamata get(), mentre gli altri metodi di richiesta hanno metodi simili. Il valore restituito è un oggetto risposta con cui puoi testare il codice di stato, il corpo, il tipo di contenuto e molto altro. Consulta la home page di WebTest per una descrizione dettagliata di tutte le operazioni che puoi eseguire.

Creazione di un test del gestore che utilizza un servizio App Engine

Ora vediamo come testare un gestore che utilizza un servizio App Engine. Ciò significa che ora dobbiamo gestire due componenti che potrebbero influire sui nostri test: l'handler e il servizio che stiamo utilizzando. Come descritto nell'articolo Test locali delle unità per Python, il modo migliore per gestire i servizi nei test è utilizzare il testbed.

L'esempio seguente utilizza Memcache, ma in linea di principio è lo stesso per altri servizi come Datastore o Task Queue.

Il gestore che testiamo memorizza nella cache la chiave e il valore specificati. Tieni presente che analizziamo entrambi i valori dai parametri di richiesta.

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)

Nel test, come prima, crea prima un'applicazione e avvolgila con WebTest. Inoltre, attiva un'istanza di Testbed e assicurati di disattivarla dopo il test.

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

Configurazione di un framework di test

Se vuoi, puoi configurare un framework di test. I test per i gestori che utilizzano WebTest possono essere eseguiti come i tuoi test di unità per App Engine. L'unica differenza è che devi assicurarti di avere installato WebTest.