Test del gestore per Python 2

L'articolo Local Unit Testing for 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 fa eseguire la tua applicazione, quindi il test di integrazione è altrettanto importante.

Per le applicazioni App Engine, i gestori delle 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 delle richieste sono normali oggetti Python come qualsiasi altra funzione o classe, che li rende facili da usare nei test automatici. Tuttavia, poiché un'applicazione WSGI le aggrega come una shell, utilizzeremo una shell simile nei nostri test.

WebTest

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

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

Il test di un gestore "Hello World" semplice

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 contenuti è "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 consente di effettuare richieste GET con una semplice chiamata get() (altri metodi di richiesta hanno metodi simili). Il valore restituito è un oggetto risposta con il quale puoi testare il codice di stato, il corpo, il tipo di contenuti e molto altro ancora. Consulta la home page di WebTest per una descrizione dettagliata di tutte le cose che puoi fare.

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

Ora diamo un'occhiata a come testare un gestore che utilizza un servizio App Engine. Ciò significa che ora dobbiamo gestire due componenti che potrebbero interessare i nostri test: il gestore e il servizio che stiamo utilizzando. Come descritto nell'articolo Local Unit Testing for 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 Task Queue.

Il gestore sottoposto a test memorizza nella cache la chiave e il valore specificati. Tieni presente che analizziamo entrambi i valori dai 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 in precedenza, devi prima creare un'applicazione e includerla in 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.