2009-10-20 12 views
15

Sono principalmente un ragazzo Ruby, ma ultimamente ho lavorato su molte cose di Python, in particolare, sul codice App Engine. In Ruby, utilizzerei l'integrazione continua automatica (autotest), gli strumenti di copertura del codice (rcov), l'analisi statica (reek) e il test delle mutazioni (heckle) nel mio processo di sviluppo, ma non sono sicuro di come impostare al meglio un processo di sviluppo simile per un ambiente App Engine. Sarei interessato anche agli analoghi a RSpec e Cucumber per Python che potrebbe funzionare in App Engine.Come faccio a configurare un processo di sviluppo TDD con Google App Engine?

+3

E 'assolutamente incredibile la cultura TDD che si è formata all'interno della comunità di Ruby. –

risposta

15

sul mio progetto GAE, io uso:

  • NoseGAE — Questo è il pezzo fondamentale che lega tutto il resto insieme
  • Mock, come nell'eccellente risposta di John. Io uso questo in gran parte per AWS e altri servizi web
  • Fixtures (il pacchetto, non l'idea)

Anch'io preferisco molti idiomi di Rails. Ho rotto i miei test in unità, e funzionale utilizzando pacchetti Python. È possibile eseguire un sottoinsieme di test utilizzando --tests=unit o --tests=functional. È tutto un po 'più manuale di Rails, ma almeno posso testare unitamente le cose difficili e assicurarmi di non avere mai regressioni.

Ho anche creato una semplice classe FunctionalTest per eseguire molte delle azioni più comuni in Rails, come ad esempio assert_response e assert_xpath (simile a assert_select).

class FunctionalTest(Test): 
    def get(self, *args, **kw): 
    self.response = app.get(*args, **kw) 

    def post(self, *args, **kw): 
    self.response = app.post(*args, **kw) 

    def assert_response(self, expected): 
    pattern = str(expected) if re.search(r'^\d+$', expected) \ 
          else (r'^\d+ %s' % expected) 
    assert re.search(pattern, self.response.status, re.IGNORECASE), \ 
      'Response status was not "%s": %s' % (expected, self.response.status) 

    def assert_xpath(self, path, expected): 
    element = ElementTree.fromstring(self.response.body) 
    found_nodes = element.findall('.' + path) 
    if type(expected) is int: 
     assert_equal(expected, len(found_nodes)) 
    elif type(expected) is str or type(expected) is unicode: 
     assert (True in [(node.text == expected) for node in found_nodes]) 
    else: 
     raise Exception, "Unknown expected value: %r" % type(expected) 

Se stai facendo un sacco di ricerche di uguaglianza LISTELEMENT, sicuramente imparare la sintassi --tests=foo perché i test per gli elementi corrispondenti all'interno di una lista è molto lenta.

A volte mi piace caricare la console di Rails contro i miei dati di installazione per vedere cosa succede nell'ambiente di test (ad esempio script/console test). Per fare qualcosa di simile con GAE, eseguire dev_appserver.py con il parametro --datastore_path="$TMPDIR/nosegae.datastore" (o, eventualmente, sostituire /tmp per $TMPDIR.

+0

Questa risposta è stata accettata per il bit di informazione critico NoseGAE, sebbene la risposta di John sia stata incredibilmente utile. –

+0

Grazie, Bob! In effetti, ho intenzione di integrare più dei suggerimenti di John nei miei progetti futuri. – JasonSmith

+0

Bob, tornando indietro nel mio codice ho notato che avevo un modo per eseguire il normale server SDK contro l'archivio dati creato da NoseGAE, quindi l'ho aggiunto come ultimo paragrafo. – JasonSmith

26

In Python non troverete sempre gli equivalenti uno a uno degli strumenti di test di Ruby, ma in Python ci sono alcuni strumenti di test eccezionali. Alcuni degli strumenti che ho trovato utili includono:

  • unittest - lo strumento xUnit incluso nella libreria standard Python. Include tutte le nozioni di base per il test dell'unità.
  • doctest - una parte impressionante della libreria standard, consente di scrivere test nelle docstring di funzioni, classi, moduli, metodi. È ottimo per trasmettere l'uso previsto dell'API. Ian Bicking suggerisce di utilizzare doctest per lo sviluppo basato sul comportamento. Doctest si adatta molto bene al sistema di documentazione Sphinx (puoi assicurarti che tutti gli esempi nella tua documentazione passino ogni volta che crei i documenti).
  • nose e py.test sono visti come le versioni next-gen di unittest. Possono eseguire tutti i casi di unittest esistenti, ma consentono di eseguire test unitari non basati su classi. py.test consente anche l'esecuzione distribuita.
  • mock è una bella libreria per il comportamento di derisione.
  • tdaemon controlla una directory per gli aggiornamenti del codice e eseguirà di nuovo la suite di test. (il mio personal branch contiene alcuni miglioramenti non completati).
  • Buildbot, Bitten e anche Hudson funzionano tutti bene come server di integrazione continua completi per codice Python.
  • coverage.py calcola la copertura del codice del codice.
  • pylint fornirà un'analisi del codice simile a un filamento, assicurandosi che segua le comuni convenzioni di codifica e non abbia bug comuni. C'è anche uno strumento di analisi "più leggero", PyFlakes.
  • Esistono numerosi strumenti di test HTTP/Browser che funzionano bene in Python, inclusi Twill, Selenium e Windmill.

Se si utilizza Django su App Engine, che include several extensions a unittest che consentono di simulare un client HTTP e persistenza del database.

Esistono molti altri strumenti che non ho utilizzato (come PySpec e Behaviour) che potrebbero essere utili. Non ho visto nessuno strumento di test delle mutazioni in Python, ma scommetto che ce n'è uno là fuori (mi piacerebbe sapere di cosa si tratta).

Test felici!

+3

favoriting questa domanda esclusivamente per questa risposta –

+0

un sacco di link fantastici qui. sto cercando di indovinare un sacco di questi sono non drop- per GAE però. Mi piacerebbe vedere più risposte nel dettaglio su come sono state integrate con l'ambiente di sviluppo di GAE, in particolare con OS X launcher. –

+1

Bob, la risposta di John è davvero eccellente. Come ho appena detto, una volta installato il plug-in NoseGAE per Nose, la navigazione è praticamente fluida con tutti questi strumenti. – JasonSmith

3

non hanno utilizzato App Engine, ma la mia sensazione per i più popolari strumenti di test di pitone è

  • unittest/doctest sono i pacchetti di test dal libreria standard di Python. unittest è xUnit per python.
  • nose è un test runner/finder. Ha molte opzioni, tra cui --with-coverage, che utilizza coverage per fornire report di copertura del codice .
  • pylint è il lint-checker più funzionale per Python. Utile oltre un controllore di sintassi poiché consiglia su variabili/funzioni non utilizzate, quando i metodi devono essere funzioni e altro.
  • pester (test di mutazione)
  • buildbot (integrazione continua)

Probabilmente si vorrà fare riferimento a queste (non del tutto completo) elenco di Python Testing Tools.

Per BDD, il campo era sottile l'ultima volta che ho controllato. Molti dei veri strumenti BDD non erano utilizzabili con il naso e/o troppo limitanti nella sintassi richiesta. Potresti avere un po 'di fortuna con lo spec, che è un plug-in per il naso simile a BDD. Appena trovato pyccuracy, che assomiglia molto al cetriolo, ma non l'ho provato con lo .

Per quanto il suo valore, ora basta usare nosetests -v (il corridore naso con --verbose), che utilizzerà la prima riga della docstring nel test runner uscita. Cioè, dato un test come:

class TestFoo(unittest.TestCase): 
    def testAnyNameHere(self): 
     """ Foo should be bar""" 
     foo = "bar" 
     self.assertEqual(foo, 'bar') 

nosetests darà:

$ nosetests -v 
Foo should be bar... ok 

----------------------------- 
Ran 1 tests in 0.002s 
OK 
+0

+1 per menzione pester –