Test del gestore per Python 2

L'articolo Test delle unità locali 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 l'esecuzione dell'applicazione, per cui i test di integrazione sono altrettanto importanti.

Per le applicazioni App Engine, i gestori di richieste sono punti di integrazione critici. Mentre un'applicazione WSGI instrada le richieste al gestore corretto, il gestore stesso elabora i dati delle richieste e genera una risposta (scopri di più sui gestori delle richieste). I gestori di richieste sono normali oggetti Python come qualsiasi altra funzione o classe, il che li rende facili da usare nei test automatici. Tuttavia, poiché un'applicazione WSGI le avvolge come una shell, utilizzeremo una shell simile nei nostri test.

WebTest

Per i nostri test, utilizzeremo il framework WebTest. WebTest è una libreria che offre una semplice interfaccia per testare le applicazioni basate su WSGI e quindi i gestori di richieste. Per farlo, inserisce un'applicazione WSGI in un'app di test speciale che può essere utilizzata per i test. WebTest ti consente di interagire con i tuoi gestori senza un ambiente App Engine completo; puoi inviare facilmente le richieste e modificare l'ambiente delle richieste. Le risposte hanno anche un'interfaccia semplificata per i test. Non è necessario usare WebTest, ma ti semplifica la vita.

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

Testare un semplice gestore "Hello World"

Iniziamo con il test di un semplice gestore "Hello World!" che risponde alla richiesta di un 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!')

Successivamente, crea lo scenario 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() (altri metodi di richiesta hanno metodi simili). Il valore restituito è un oggetto di risposta con cui puoi testare il codice di stato, il corpo, il tipo di contenuti e molto altro ancora. Per una descrizione dettagliata di tutto ciò che puoi fare, consulta la home page di WebTest.

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

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

L'esempio seguente utilizza Memcache, ma il principio è lo stesso per altri servizi come Datastore o coda di attività.

Il gestore che testiamo memorizza nella cache la chiave e il valore specificati. Nota che analizziamo entrambi i valori dei parametri della 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, proprio come prima, crea prima un'applicazione e sottoponila a wrapping con WebTest. Inoltre, attiva un'istanza 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 impostare un framework di test. I test per i gestori che utilizzano WebTest possono essere eseguiti come i test delle unità per App Engine. L'unica differenza è che devi assicurarti di aver installato WebTest.