Iniziare con Nette Tester

Anche i bravi programmatori commettono errori. La differenza tra un buon programmatore e uno cattivo è che quello buono lo commette solo una volta e la prossima volta lo rileva tramite test automatizzati.

  • “Chi non testa, è condannato a ripetere i propri errori.” (proverbio)
  • “Non appena ci liberiamo di un errore, ne appare un altro.” (Legge di Murphy)
  • “Ogni volta che senti il bisogno di stampare una variabile sullo schermo, scrivi piuttosto un test.” (Martin Fowler)

Avete mai scritto in PHP un codice simile?

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

var_dump($result);

Cioè, avete stampato il risultato della chiamata di una funzione solo per verificare a occhio se restituisce ciò che dovrebbe? Sicuramente lo fate molte volte al giorno. Mano sul cuore: nel caso in cui tutto funzioni correttamente, cancellate questo codice? Vi aspettate che la classe non si rompa in futuro? Le leggi di Murphy garantiscono il contrario :-)

In sostanza, avete scritto un test. Basta solo modificarlo leggermente affinché non richieda un controllo visivo, ma si controlli da solo. E se non cancellate il test, potete eseguirlo in qualsiasi momento in futuro e verificare che tutto funzioni ancora come dovrebbe. Con il tempo creerete un gran numero di tali test, quindi sarebbe utile eseguirli in modo automatizzato.

E con tutto questo vi aiuterà proprio Nette Tester.

Cosa rende Tester unico?

Scrivere test per Nette Tester è unico nel senso che ogni test è uno script PHP comune che può essere eseguito separatamente.

Quindi, quando scrivete un test, potete semplicemente eseguirlo e scoprire se, ad esempio, contiene un errore di programmazione. Se funziona correttamente. In caso contrario, potete facilmente eseguirlo passo passo nel vostro IDE e cercare l'errore. Potete persino aprirlo nel browser.

E soprattutto – eseguendolo, eseguite il test. Scoprite immediatamente se è passato o fallito. Come? Vediamolo. 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';  # caricamento dell'autoloader di Composer
Tester\Environment::setup();               # inizializzazione di 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, i cosiddetti metodi di asserzione come Assert::same() vengono utilizzati per confermare che il valore effettivo corrisponde al valore atteso.

Abbiamo scritto il test e possiamo eseguirlo dalla riga di comando. La prima esecuzione ci rivelerà eventuali errori di sintassi e se non avete fatto errori di battitura da nessuna parte, verrà visualizzato:

$ php ArrayTest.php

OK

Provate a cambiare nel test l'asserzione in una falsa Assert::contains('XXX', $stack); e osservate cosa succede all'esecuzione:

$ php ArrayTest.php

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

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

FAILURE

Continuiamo a scrivere nel capitolo Scrivere test.

Installazione e requisiti

La versione minima di PHP richiesta da Tester è 7.1 (più dettagliatamente nella tabella podporované verze PHP). Il metodo di installazione preferito è tramite Composer:

composer require --dev nette/tester

Provate ad eseguire Nette Tester dalla riga di comando (senza parametri visualizzerà solo l'help):

vendor/bin/tester

Esecuzione dei test

Man mano che l'applicazione cresce, il numero di test cresce con essa. Non sarebbe pratico eseguire i test uno per uno. Pertanto, Tester dispone di un esecutore di test di massa, che chiamiamo dalla riga di comando. Come parametro indichiamo la directory in cui si trovano i test. Il punto significa la directory corrente.

vendor/bin/tester .

L'esecutore di test esamina la directory specificata e tutte le sottodirectory e cerca i test, che sono i file *.phpt e *Test.php. Trova così anche il nostro test ArrayTest.php, poiché corrisponde alla maschera.

Successivamente avvia il test. Ogni test viene eseguito come un nuovo processo PHP, quindi si svolge completamente isolato dagli altri. Li esegue in parallelo in più thread e grazie a ciò è estremamente veloce. E come primi esegue i test che sono falliti nell'esecuzione precedente, così scoprirete immediatamente se siete riusciti a correggere l'errore.

Durante l'esecuzione dei test, Tester visualizza continuamente i risultati sul terminale come caratteri:

  • . – test superato
  • s – test saltato (skipped)
  • F – test fallito (failed)

L'output può apparire così:

 _____ ___  ___ _____ ___  ___
|_   _/ __)( __/_   _/ __)| _ )
  |_| \___ /___) |_| \___ |_|_\  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à Watch

State rifattorizzando il codice? O addirittura sviluppate secondo la metodologia TDD (Test Driven Development)? Allora vi piacerà la modalità watch. Tester in essa monitora i codici sorgente e all'occorrenza si avvia da solo.

Durante lo sviluppo avete quindi nell'angolo del monitor un terminale dove brilla su di voi una barra di stato verde, e quando improvvisamente diventa rossa, sapete che avete appena fatto qualcosa non del tutto correttamente. È in realtà un gioco fantastico, in cui programmate e cercate di mantenere il colore.

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

Report di Code Coverage

Tester può generare report con una panoramica di quanto codice sorgente coprono i test. Il report può essere sia in formato HTML leggibile dall'uomo, sia in Clover XML per un'ulteriore elaborazione automatica.

Date un'occhiata a un esempio di report HTML 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

Vale per l'ultima versione patch.

Tester fino alla versione 1.7 supportava anche HHVM 3.3.0 o superiore (tramite tester -p hhvm). Il supporto è stato interrotto dalla versione Tester 2.0.