Test automatici per TDD con PHP

Lo sviluppo tradizionale basato sui test può, a volte, essere ingombrante. Devi smettere di scrivere il codice per eseguire i test. Fortunatamente, ci sono soluzioni che forniscono la possibilità di eseguire automaticamente i test durante la codifica. In questo tutorial, imparerai come usare una gemma Ruby, chiamata Watchr, per monitorare il codice e eseguire automaticamente i test appropriati ogni volta che si salva il lavoro.


Passaggio 1: requisiti software

Qualsiasi strumento che ti aiuti a ottenere un feedback più rapido è una risorsa preziosa.

Questo tutorial utilizza PHP per l'esempio di codice, tuttavia, le tecniche sono applicabili a qualsiasi lingua, che offre un'utilità CLI per il test delle unità. È richiesto Rubino perché useremo la gemma watchr. Quindi, assicurati di avere un'installazione funzionante di Ruby e PHP con PHPUnit.

Quindi, assicurarsi di averlo libnotify installato, se sei su Linux; Gli utenti Windows e Mac OSX hanno bisogno di "Growl". Questo tutorial è direttamente applicabile su Linux, ma suggerirò comandi e impostazioni alternativi laddove possibile.

Ora è il momento di installare la gemma watchr. Apri una console e assicurati di essere nella cartella in cui puoi eseguire direttamente gemma. Digita il seguente comando:

gem installare watchr

Passaggio 2: informazioni tecniche

Quando un file o una cartella viene modificato, watchr può attivare una funzione di callback.

Watchr gem è un programma eseguibile scritto in Ruby e include funzionalità presenti nel file system di un sistema operativo per consentire la visualizzazione delle modifiche apportate a un file o una cartella specifici. Naturalmente, queste funzionalità del file system sono diverse per ogni sistema operativo e file system.

watchr fornisce un'interfaccia di programmazione dell'applicazione (API) unificata per tutti i sistemi operativi. Su Linux, usa inotify, la libreria di eventi del file system del kernel; su altri sistemi operativi, utilizza l'alternativa appropriata. Se, per qualche motivo, il sistema operativo non dispone di un servizio eventi disponibile, watchr periodicamente esegue il polling del file o della cartella guardati.

Quando un file o una cartella viene modificato, watchr può attivare una funzione di callback. Useremo questa funzione per eseguire i nostri test.


Passaggio 3: creare un progetto PHP

Il nostro progetto è piuttosto semplice. Replica la semplice struttura di directory mostrata nell'immagine seguente:

Nel Nettuts.php file, aggiungi il seguente codice:

Quindi, aggiungere il seguente codice a NettutsTest.php:

object = new Nettuts;  funzione protetta tearDown () ?>

A questo punto, il file di test è semplicemente uno scheletro e, come puoi vedere nell'immagine sopra, i test passano.


Passaggio 4: crea il primo script watchr

Ora, abbiamo bisogno di creare un file Ruby nella cartella del nostro progetto; chiamiamolo autotest_watchr.rb. Successivamente, aggiungi il seguente codice al file:

guardare ("Classes /(.*). php") do | match | run_test% Test / # match [1] Test.php fine

I test automatici sono indipendenti dall'IDE: un grande vantaggio nel mio libro.

Questo codice usa il orologio metodo per guardare tutto il .php file nel nostro progetto Classi cartella. Quando un .php il file cambia, il sistema operativo emette un evento e il nostro orologio il metodo verrà attivato. Il nome del .php il file viene restituito (meno l'estensione) nella posizione di una matrice di corrispondenza di 1. Come con qualsiasi espressione regolare, vengono utilizzate parentesi per specificare una variabile di corrispondenza e in questo codice le usiamo nella condizione corrispondente per recuperare il nome del file. Quindi, chiamiamo il run_test metodo con il percorso del nome del file di test composto.

Dovremmo anche guardare i nostri file di test; quindi, aggiungi il seguente codice al file Ruby:

guardare ("Test /.* Test.php") do | match | run_test match [0] end

Si noti che il incontro array contiene il nome completo del file in posizione 0, e lo passiamo direttamente al run_test metodo.


Passaggio 5: Creare lo script Esegui i test

Lo script Ruby è impostato per guardare i nostri .php file, e ora abbiamo bisogno di implementare il run_test metodo. Nel nostro caso, vogliamo eseguire PHPUnit per il file specifico.

def run_test (file) a meno che File.exist? (file) rimetta "# file non esiste" return end puts "Esecuzione # file" result = "phpunit # file" mette fine risultato

Prima assicuriamo che il file esista e restituisca semplicemente se non lo è. Successivamente, eseguiamo il test con PHPUnit e inviamo il risultato alla console. Eseguiamo il nostro script watchr. Apri la tua console, vai alla directory del tuo progetto e poi esegui:

watchr ./autotest_watchr.rb

Gli utenti di Windows devono omettere "./" dal comando precedente.

Ora modifica uno dei .php file (basta aggiungere una riga vuota alla fine del file), salvarlo e osservare l'output nella console. Dovresti vedere qualcosa di simile a ciò che è mostrato di seguito:

Running Tests / NettutsTest.php PHPUnit 3.6.0 di Sebastian Bergmann. F Tempo: 0 secondi, Memoria: 3.75Mb Si è verificato un errore 1: 1) Avviso Nessun test trovato nella classe "NettutsTest". / usr / bin / phpunit: 46 GUASTI! Test: 1, Asserzioni: 0, Fallimenti: 1.

Sì, non abbiamo ancora un test da eseguire; quindi mettiamo un test fittizio. Aggiungi il seguente codice al file PHP di prova:

function testDummyPassingTest () $ this-> assertTrue (true); 

Esegui di nuovo lo script Ruby e dovresti vedere:

Running Test / NettutsTest.php PHPUnit 3.6.0 di Sebastian Bergmann ... Tempo: 0 secondi, Memoria: 3.75Mb OK (1 test, 1 assertion)

Passaggio 6: analizzare l'output di test

Informiamo l'utente, tramite il meccanismo di notifica del sistema, sui risultati del test. Modificheremo il run_tests metodo per attivare un metodo, chiamato notificare. Di seguito è la modifica run_tests:

def run_tests (file) a meno che File.exist? (file) rimetta "# file non esiste" return end puts "Esecuzione # file" result = "phpunit # file" inserisce risultato se result.match (/ OK /) notifica "# file", "Test passati con successo", "success.png", fine 2000

Il nome del file immagine, success.png, punta all'immagine che si desidera visualizzare nell'area di notifica. Questa immagine non è fornita in questo tutorial; quindi dovrai trovare il tuo. Ora, scriviamo il notificare metodo:

def notify title, msg, img, show_time images_dir = "~ / .autotest / images" system "notify-send" # title "# msg '-i # images_dir / # img -t #  show_time "fine

Utenti Mac OSX e Windows: sostituire il notify-invio comando con l'alternativa Growl appropriata. Modifica qualcosa nel file di test o di codice in modo che il test passi ancora. Salva il file PHP modificato e osserva la magia che si verifica. Di seguito è riportata un'immagine del risultato sul mio sistema:

Quindi, dobbiamo catturare i fallimenti. Il seguente codice aggiunge un paio di righe a run_tests:

def run_tests (file) a meno che File.exist? (file) rimetta "# file non esiste" return end puts "Esecuzione # file" result = "phpunit # file" inserisce risultato se result.match (/ OK /) notifica "# file", "Test passati con successo", "success.png", 2000 elsif result.match (/ FAILURES \! /) Notify_failed file, risultato end-end

Inoltre, aggiungiamo il notify_failed metodo per il file:

def notify_failed cmd, result failed_examples = result.scan (/ failure: \ n \ n (. *) \ n /) notifica "# cmd", failed_examples [0], "failure.png", 6000 end

Modifica uno dei tuoi file PHP per fare fallire il test; salva il file modificato. Osservare il messaggio di notifica. Contiene il nome del primo test fallito. Questo nome è selezionato dall'espressione regolare nel metodo notify_failed, che analizza l'output di PHPUnit.


Passaggio 7: Cancellare la console prima di ogni esecuzione di prova

Aggiungi il seguente metodo allo script Ruby e assicurati di chiamarlo nel run_test metodo. Il codice dovrebbe funzionare in Linux e Mac OSX, anche se potrebbe essere necessario fare qualche ricerca per Windows.

def clear_console inserisce "\ e [H \ e [2J" # fine console

Conclusione

Ogni volta che programmi utilizzando TDD, qualsiasi strumento che ti aiuti a ottenere un feedback più rapido è una risorsa preziosa. I miei colleghi usano script simili con watchr o alternative (alcuni sono scritti in giro fs_event su MacOS). Inutile dire che ora siamo viziati e non possiamo immaginare di sviluppare qualcosa senza eseguire automaticamente test.

I test automatici sono indipendenti dall'IDE: un grande vantaggio nel mio libro. Troppi IDE ti costringono a utilizzare un framework di test specifico e non mi aiutano a testare a distanza. Preferisco usare quotidianamente script come questo, e sicuramente li consiglio a qualsiasi sviluppatore di software agile.