Primi passi con Nette Tester
Anche i bravi programmatori sbagliano. La differenza tra un bravo programmatore e uno scadente è che il bravo commette un errore una sola volta e la volta successiva lo scopre con i test automatici.
- “Chi non testa è condannato a ripetere i propri errori.” (proverbio)
- “Appena ci sbarazziamo di un errore, ne compare un altro.” (legge di Murphy)
- “Ogni volta che sei tentato di scrivere un print, scrivi invece un test.” (Martin Fowler)
Avete mai scritto in PHP del codice come questo?
$obj = new MyClass;
$result = $obj->process($input);
var_dump($result);
Cioè: avete mai stampato il risultato della chiamata di una funzione solo per controllare a occhio se restituisce quello che dovrebbe? Probabilmente lo fate più volte al giorno. Mano sul cuore: se tutto funziona correttamente, questo codice lo cancellate? Vi aspettate che la classe non si rompa in futuro? Le leggi di Murphy garantiscono il contrario :-)
In sostanza avete scritto un test. Basta una piccola modifica perché non richieda un controllo visivo, ma si controlli da sé. E se non cancellate il test, potete eseguirlo in qualsiasi momento in futuro per verificare che tutto funzioni ancora come deve. Con il tempo creerete un gran numero di test del genere, quindi tornerebbe utile eseguirli automaticamente.
E in tutto questo vi aiuterà Nette Tester.
Che cosa rende Tester unico?
Scrivere test per Nette Tester è particolare perché ogni test è un normale script PHP che si può eseguire da solo.
Quando scrivete un test, potete quindi semplicemente eseguirlo e scoprire se contiene per esempio un errore di programmazione. Se funziona correttamente. In caso contrario potete percorrerlo comodamente passo passo nel vostro IDE e cercare l'errore. Potete perfino aprirlo nel browser.
E soprattutto: eseguendolo, eseguite il test. Scoprite subito se è passato o fallito. Come? Mostriamolo. Scriveremo un test
banale sul lavoro con un array PHP e lo salveremo nel file ArrayTest.php:
<?php
use Tester\Assert;
require __DIR__ . '/vendor/autoload.php'; # carica l'autoloader di Composer
Tester\Environment::setup(); # inizializza Nette Tester
$stack = [];
Assert::same(0, count($stack)); # ci aspettiamo che count() restituisca zero
$stack[] = 'foo';
Assert::same(1, count($stack)); # ci aspettiamo che count() restituisca uno
Assert::contains('foo', $stack); # verifichiamo che $stack contenga l'elemento 'foo'
Come vedete, per confermare che il valore reale corrisponde a quello atteso si usano i cosiddetti metodi di asserzione come Assert::same().
Il test è scritto e possiamo eseguirlo dalla riga di comando. La prima esecuzione rivelerà eventuali errori di sintassi e, se non avete fatto refusi da nessuna parte, stamperà:
$ php ArrayTest.php
OK
Provate a cambiare l'asserzione nel test in una falsa, per esempio Assert::contains('XXX', $stack);, e guardate
cosa succede all'esecuzione:
$ php ArrayTest.php Failed: ['foo'] should contain 'XXX' in ArrayTest.php(17) Assert::contains('XXX', $stack); FAILURE
Continuiamo a parlare di come scrivere i test nel capitolo Scrivere i test.
Installazione e requisiti
La versione minima di PHP richiesta da Tester è la 8.0 (maggiori dettagli nella tabella Versioni di PHP supportate). Il modo di installazione preferito è con Composer:
composer require --dev nette/tester
Provate a lanciare Nette Tester dalla riga di comando (senza argomenti stampa solo l'aiuto):
vendor/bin/tester
Eseguire i test
Man mano che l'applicazione cresce, cresce con essa anche il numero di test. Eseguirli uno per uno non sarebbe pratico. Tester ha perciò un runner di test di massa, che richiamiamo dalla riga di comando. Come parametro indichiamo la directory in cui si trovano i test. Il punto indica la directory corrente.
vendor/bin/tester .
Il runner esplora la directory indicata e tutte le sottodirectory e cerca i test, cioè i file *.phpt e
*Test.php. Troverà anche il nostro test ArrayTest.php, perché corrisponde alla maschera.
Poi comincia a testare. Ogni test viene eseguito come un nuovo processo PHP, quindi gira completamente isolato dagli altri. Li esegue in parallelo su più thread, il che lo rende estremamente veloce. E per prima cosa esegue i test falliti nell'esecuzione precedente, così scoprite subito se siete riusciti a correggere l'errore.
Durante l'esecuzione dei test, Tester stampa via via i risultati nel terminale sotto forma di caratteri:
.– test passatos– test saltatoF– test fallito
L'output può apparire così:
_____ ___ ___ _____ ___ ___ |_ _/ __)( __/_ _/ __)| _ ) |_| \___ /___) |_| \___ |_|_\ v2.6.0 PHP 8.5.2 (cli) | php | 8 threads ........s................F......... -- FAILED: greeting.phpt Failed: 'Hello John' should be ... 'Hello Peter' in greeting.phpt(19) Assert::same('Hello Peter', $o->say('John')); FAILURES! (35 tests, 1 failures, 1 skipped, 1.7 seconds)
Sono stati eseguiti 35 test, uno è fallito, uno è stato saltato.
Continuiamo nel capitolo Eseguire i test.
Modalità watch
State facendo il refactoring del codice? O magari sviluppate perfino secondo la metodologia TDD (Test Driven Development)? Allora vi piacerà la modalità watch. In questa modalità Tester sorveglia i codici sorgente e si riavvia automaticamente quando cambiano.
Durante lo sviluppo avete nell'angolo del monitor un terminale in cui vi brilla una barra di stato verde e, quando all'improvviso diventa rossa, sapete di aver appena fatto qualcosa che non va. È in realtà un bel gioco: programmate e cercate di mantenere il colore.
La modalità watch si avvia con il parametro --watch.
Report sulla copertura del codice
Tester sa generare report con una panoramica di quanto codice sorgente è coperto dai test. Il report può essere in formato HTML leggibile dalle persone oppure in Clover XML per l'ulteriore elaborazione automatica.
Guardate un report HTML di esempio con la copertura del codice.
Versioni di PHP supportate
| Versione | Compatibile con PHP |
|---|---|
| Tester 2.6 | PHP 8.0 – 8.5 |
| Tester 2.5 | PHP 8.0 – 8.5 |
| Tester 2.4 | PHP 7.2 – 8.2 |
| Tester 2.3 | PHP 7.1 – 8.0 |
| Tester 2.1 – 2.2 | PHP 7.1 – 7.3 |
| Tester 2.0 | PHP 5.6 – 7.3 |
| Tester 1.7 | PHP 5.3 – 7.3 + HHVM 3.3+ |
| Tester 1.6 | PHP 5.3 – 7.0 + HHVM |
| Tester 1.3 – 1.5 | PHP 5.3 – 5.6 + HHVM |
| Tester 0.9 – 1.2 | PHP 5.3 – 5.6 |
Vale per l'ultima versione patch.
Tester fino alla versione 1.7 supportava anche HHVM 3.3.0 o superiore (con
tester -p hhvm). Il supporto è stato interrotto dalla versione 2.0 di Tester.