Come iniziare con Tester

Anche i bravi programmatori commettono errori. La differenza tra un buon programmatore e uno scadente è che quello bravo lo fa una sola volta e la volta successiva lo rileva usando test automatizzati.

  • “Chi non fa test è destinato a ripetere i propri errori”. (proverbio saggio)
  • “Quando ci liberiamo di un errore, ne compare un altro”. (Legge di Murphy)
  • “Ogni volta che siete tentati di stampare una dichiarazione, scrivetela invece come test”. (Martin Fowler)

Avete mai scritto il seguente codice in PHP?

$obj = new MyClass;
$result = $obj->process($input);

var_dump($result);

Avete mai scaricato il risultato di una chiamata di funzione solo per verificare a occhio che restituisca ciò che dovrebbe restituire? Sicuramente lo fate molte volte al giorno. Con la mano sul cuore, se tutto funziona, cancellate questo codice e vi aspettate che la classe non si rompa in futuro? La legge di Murphy garantisce il contrario :-)

In effetti, il test l'avete scritto voi. Ha bisogno di una piccola modifica per non richiedere la nostra ispezione, semplicemente per essere in grado di controllare se stesso. E se non lo avete cancellato, potremo eseguirlo in qualsiasi momento in futuro per verificare che tutto funzioni ancora come dovrebbe. È possibile che nel corso del tempo si crei una grande quantità di questi test, quindi sarebbe bello poterli eseguire automaticamente.

Nette Tester ci aiuta proprio in questo.

Cosa rende unico Tester?

La scrittura di test per Nette Tester è unica nel suo genere, in quanto ogni test è uno script PHP standard che può essere eseguito autonomamente.

Quindi, quando si scrive un test, si può semplicemente eseguirlo per vedere se c'è un errore di programmazione. Se funziona correttamente. In caso contrario, si può facilmente analizzare il programma nell'IDE e cercare un bug. È anche possibile aprirlo in un browser.

E soprattutto, eseguendo il programma, si esegue il test. Scoprirete immediatamente se è stato superato o meno. Come? Vediamo qui di seguito. Scriviamo un test banale per l'utilizzo di un array in PHP e salviamolo nel file ArrayTest.php:

<?php
use Tester\Assert;

require __DIR__ . '/vendor/autoload.php';  # load Composer autoloader
Tester\Environment::setup();               # initialization of Nette Tester

$stack = [];
Assert::same(0, count($stack));   # we expect count() to return zero

$stack[] = 'foo';
Assert::same(1, count($stack));   # we expect count() to return one
Assert::contains('foo', $stack);  # verify that the $stack contains the item 'foo'

Come si può vedere, i metodi di asserzione come Assert::same() sono usati per affermare che un valore reale corrisponde a un valore atteso.

Il test è scritto, possiamo eseguirlo da riga di comando. La prima esecuzione rivelerà eventuali errori di sintassi e, se non si è fatto un errore di battitura, si vedrà:

$ php ArrayTest.php

OK

Provate a cambiare l'istruzione in Assert::contains('XXX', $stack); nel test e guardate cosa succede quando viene eseguito:

$ php ArrayTest.php

Failed: ['foo'] should contain 'XXX'

in ArrayTest.php(17) Assert::contains('XXX', $stack);

FAILURE

Continuiamo a parlare di scrittura nel capitolo Scrivere i test.

Installazione e requisiti

La versione minima di PHP richiesta da Tester è la 7.1 (per maggiori dettagli, consultare la tabella delle versioni PHP supportate ). Il metodo di installazione preferito è Composer:

composer require --dev nette/tester

Provate a eseguire Nette Tester dalla riga di comando (senza argomenti mostrerà solo un riassunto della guida):

vendor/bin/tester

Esecuzione dei test

Man mano che la nostra applicazione cresce, cresce anche il numero di test. Non sarebbe pratico eseguire i test uno per uno. Per questo motivo, il Tester dispone di un'esecuzione massiva dei test, che viene invocata dalla riga di comando. Il parametro è la directory in cui si trovano i test. Il punto indica la directory corrente.

vendor/bin/tester .

Il runner Nette Tester cerca nella directory specificata e in tutte le sottodirectory i test, che sono i file *.phpt e *Test.php. Troverà anche il nostro test ArrayTest.php, poiché corrisponde alla maschera.

Quindi inizia a eseguire i test. Ogni test viene eseguito come un nuovo processo PHP, in modo da essere completamente isolato dagli altri. Viene eseguito in parallelo su più thread, il che lo rende estremamente veloce. Esegue prima i test che non sono riusciti durante l'esecuzione precedente, in modo da sapere subito se l'errore è stato risolto.

Per ogni test eseguito, il runner stampa un carattere per indicare il progresso:

  • . – test superato
  • s – il test è stato saltato
  • F – test fallito

L'output può essere simile a questo:

 _____ ___  ___ _____ ___  ___
|_   _/ __)( __/_   _/ __)| _ )
  |_| \___ /___) |_| \___ |_|_\  v2.5.2

Note: No php.ini is used.
PHP 8.3.2 (cli) | php -n | 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 Esecuzione dei test.

Modalità di osservazione

State rifattorizzando il codice? Oppure sviluppate secondo la metodologia TDD (Test Driven Development)? Allora vi piacerà la modalità di controllo. Il Tester monitora il codice sorgente ed esegue se stesso quando viene modificato.

Durante lo sviluppo, avete un terminale nell'angolo del monitor, dove la barra di stato verde si illumina e quando diventa improvvisamente rossa, sapete che avete appena fatto qualcosa di indesiderato. In realtà è un grande gioco in cui si programma e si cerca di attenersi al colore.

La modalità Watch si avvia con il parametro –watch.

Rapporti di CodeCoverage

Il Tester può generare rapporti con una panoramica della copertura del codice sorgente da parte dei test. I rapporti possono essere in formato HTML leggibile dall'uomo o Clover XML per un'ulteriore elaborazione meccanica.

Vedere il rapporto HTML di esempio con la copertura del codice.

Versioni PHP supportate

Versione compatibile con PHP
Tester 2.5 PHP 8.0 – 8.3
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

Si applica alle ultime versioni della patch.

Fino alla versione 1.7 Tester supportava HHVM 3.3.0 o più recente (usando tester -p hhvm). Il supporto è stato abbandonato da Tester 2.0. L'uso era semplice: