Il riutilizzo dei casi

PHP unit testing tutorial - Subclassing a test case

# time Un assert indipendente dal tempo

Abbiamo lasciato il test dell'orologio incompleto. Se la funzione `time()` si posticipa durante questo confronto: function testClockTellsTime() { $clock = new Clock(); $this->assertEqual($clock->now(), time(), 'Now is the right time'); } i nostri test saranno fuori di un secondo e potrebbe generarsi una falsa failure. Quando eseguiamo le suite centinaia di volte al giorni, i comportamenti imprevedibili delle test suite non sono esattamente quello che vogliamo ottenere.

Potremmo riscrivere il test così: function testClockTellsTime() { $clock = new Clock();<strong> $time1 = $clock->now(); $time2 = time(); $this->assertTrue($time1 == $time2) || ($time1 + 1 == $time2), 'Now is the right time');</strong> } Difficilmente si può dire che questo sia un design pulito e sarà necessario ripetere queste operazioni per ogni test che riguardi il tempo. La ridondanza è il nemico pubblico numero uno ed useremo questo fatto come incentivo per fattorizzare il codice di test. class TestOfClock extends UnitTestCase { function TestOfClock() { $this->UnitTestCase('Clock class test'); }<strong> function assertSameTime($time1, $time2, $message) { $this->assertTrue( ($time1 == $time2) || ($time1 + 1 == $time2), $message); }</strong> function testClockTellsTime() { $clock = new Clock();<strong> $this->assertSameTime($clock->now(), time(), 'Now is the right time');</strong> } function testClockAdvance() { $clock = new Clock(); $clock->advance(10);<strong> $this->assertSameTime($clock->now(), time() + 10, 'Advancement');</strong> } } naturalmente, ogni volta che viene fatto uno di questi cambiamenti i test vengono rieseguito in modo di assicurarsi che tutto sia sempre ok. Il refactor si esegue sul verde. E' molto più sicuro.

# subclass Riutilizzo degli assert

Può darsi che si voglia che più di un tes sia sensibile al tempo. Può darsi che si stiano leggendo dei timestamp dalle righe del database o da altre risorse che potrebbero tener conto del secondo extra. Perché queste nuove classi di test possano avvantaggiarsi delle nostri nuovi assert abbiamo bisogno di posizionarli in una superclasse. For these new test classes to take advantage of our new assertion we need to place it into a superclass.

Di seguito il file clock_test.php completo dopo che si è promosso il metodo `assertSameTime()` in una sua superclasse: <?php require_once('../classes/clock.php'); <strong> class TimeTestCase extends UnitTestCase { function TimeTestCase($test_name) { $this->UnitTestCase($test_name); } function assertSameTime($time1, $time2, $message) { $this->assertTrue( ($time1 == $time2) || ($time1 + 1 == $time2), $message); } } class TestOfClock extends TimeTestCase { function TestOfClock() { $this->TimeTestCase('Clock class test'); }</strong> function testClockTellsTime() { $clock = new Clock(); $this->assertSameTime($clock->now(), time(), 'Now is the right time'); } function testClockAdvance() { $clock = new Clock(); $clock->advance(10); $this->assertSameTime($clock->now(), time() + 10, 'Advancement'); }<strong> }</strong> ?> Adesso possiamo beneficiate del nuovo assert ogni volta che ereditiamo dalla classe `TimeTestCase` piuttosto che dalla classe di default `UnitTestCase`. Questo assimiglia molto al comportament di JUnit e SimpleTest è un port della sua interfaccia. E' un framework di test nel quale i test di sistema possono essere espansi.

Se eseguiamo i test adesso otteniamo un messaggio cavilloso: Warning: Missing argument 1 for timetestcase() in /home/marcus/projects/lastcraft/tutorial_tests/tests/clock_test.php on line 5

# All tests

3/3 test cases complete. 6 passes and 0 fails. La ragione di questo è abbastanza delicata.

La nostra sottoclasse richiede un parametro nel costruttore che non è stato fornito anche se sembra che lo avevamo fatto. Quando abbiamo ereditato nella nuova classe lo abbiamo passato nel costruttore. E' qui: function TestOfClock() { $this->TimeTestCase('Clock class test'); } Infatti, abbiamo ragione, non è questo il problema.

Ricordiamoci quando abbiamo costruito il gruppo `TimeTestCase` class usando il metodo `addFile()`. Questo metodo cerca le classi test case, le istanzia se non sono ancora state incontrate e quindi lancia ogni test che queste contengono. Quello che è accaduto nel nostro caso è che sono state trovate anche le classi di estensione. Non costituisce un problema se non sono presenti metodi di test al loro interno, cioè metodi il cui nome inizia con la stringa "test". Nessun test extra viene eseguito.

Il problema è che la classe viene istanziata e l'operazione viene seguita senza il parametro `$test_name`, il che genera il warning. Questo parametro normalmente non è richiesto per l'esecuzione di un test case o per l'esecuzione dei suoi assert. Per far coincidere l'estensione del test case con l'interfaccia di `UnitTestCase` dovremmo segnare i parametri come opzionali: class TimeTestCase extends UnitTestCase { function TimeTestCase(<strong>$test_name = false</strong>) { $this->UnitTestCase($test_name); } function assertSameTime($time1, $time2, <strong>$message = false</strong>) {<strong> if (! $message) { $message = "Time [$time1] should match time [$time2]"; }</strong> $this->assertTrue( ($time1 == $time2) || ($time1 + 1 == $time2), $message); } } Naturalmente dovrebbe preoccuparci il fatto che la classe viene istanziata senza necessità dalla test suite . Ecco le modifiche da fare per evitare l'esecuzione: <strong>SimpleTestOptions::ignore('TimeTestCase');</strong> class TimeTestCase extends UnitTestCase { function TimeTestCase($test_name = false) { $this->UnitTestCase($test_name); } function assertSameTime($time1, $time2, $message = '') { if (!$message) { $message = "Time [$time1] should match time [$time2]"; } $this->assertTrue( ($time1 == $time2) || ($time1 + 1 == $time2), $message); } } Questo comunica a SimpleTest di ignorare sempre la classe durante la costruzione delle test suite. Si può includere questo codice in qualsiasi punto del test case.

Sei test passano con successo ma non dicono allo spettatore cosa sia stato collaudato. Per questo, è necessario guardare il codice.

Se questo ti sembrasse scomodo e preferissi poter leggere direttamente queste informazioni, allora potresti leggere come fare per visualizzare i successi più avanti.

Un assert indipendente dal tempo che ci permetterà di guadagnare un secondo. Subclassing dei test case per il riutilizzo dei metodi di test.
The previous section was controlling test variables. The next tutorial section was changing the test display. You will need the SimpleTest test tool to run the sample code.
software development, test case example, programming php, software development tools, php tutorial, creating subclass, free php scripts, architecture, php resources, junit, phpunit style testing, unit test, php testing