Aktualna wersja Zend Framework wspomaga tworzenie testów jednostkowych. Wykorzystuje do tego znaną paczkę PHPUnit dostępną w repozytorium PEAR.
Obecnie po utworzeniu naszego projektu opartego o ZF (zf create project nazwa_projektu) i po dodaniu automagicznie nowych kontrolerów (zf create controller nazwa_kontrolera) tworzone są automatycznie puste klasy testujące w katalogu /tests.
Dlaczego warto korzystać z testów jednostkowych?
UnitTesty automatyzują nam testowanie aplikacji. Dzięki nim jesteśmy w stanie natychmiast wychwycić błąd z innych części systemu, gdzie takie błędy nie powinny się pojawiać.
Pomagają również kontrolować postęp tworzenia aplikacji, na zasadzie najpierw unitTest, poźniej implementacja, gdzie takie podejście jest używane w eXtreme Programming. Korzystając z unitTestów możemy stworzyć odpowiednie narzędzia monitorujące dany system na podstawie wyników z testów jednostkowych.
Przygotowanie środowiska
Aby móc skorzystać z przyjemności tworzenia testów jednostkowych najpierw musimy zainstalować paczkę PHPUnit.
- Najpierw zaktualizujmy na wszelki wypadek dotychczasowe pakiety PEAR’a:
1$ pear upgrade-all - Dodajemy nowy kanał dla PEAR:
1$ pear channel-discover pear.phpunit.de - I instalujemy PHPUnit z zależnościami
1$ pear install --alldeps phpunit/PHPUnit
Jeśli wszystko poszło bez problemów możemy do korzystania z PHPUnit zwiększyć dostępną pamięć dla PHP w pliku ini zmieniając wartość memory_limit na przynajmniej 64M.
Teraz już możemy przejść do samych testów. Do tego celu posłużymy się przykładowym kontrolerem.
- Tworzymy kontroler Kontakt:
1zf create controller kontakt - Nasza hierarchia katalogów w skrócie wygląda teraz tak:
12345678910111213`-- application|-- configs`-- controllers|-- KontaktController.php|-- library|-- public`--tests`-- application`-- controllers|-- KontaktControllerTest.php|-- bootstrap.php|-- library|-- phpunit.xml - Powinniśmy skonfigurować bootstrap do celów testowych, edytujemy /tests/application/bootstrap.php:
12345678910111213141516set_include_path(implode(PATH_SEPARATOR, array(realpath(dirname(__FILE__) . '/../../library'),get_include_path(),)));defined('APPLICATION_PATH') || define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../../application'));defined('APPLICATION_ENV') || define('APPLICATION_ENV', 'testing');defined('APPLICATION_LOAD_TESTDATA') || define('APPLICATION_LOAD_TESTDATA', true);require_once 'Zend/Loader/Autoloader.php';$autoloader = Zend_Loader_Autoloader::getInstance();spl_autoload_unregister(array($autoloader, 'autoload'));Zend_Loader_Autoloader::resetInstance();$autoloader = Zend_Loader_Autoloader::getInstance();$autoloader->registerNamespace('PHPUnit_'); - Pozostało nam już tylko zedytować klasę KontaktControllerTest, aby korzystało z naszego bootstrapa, i dopisania prostego testu. Po zmianach powinna klasa wyglądać tak:
12345678910111213141516171819class KontaktControllerTest extends Zend_Test_PHPUnit_ControllerTestCase {public function setUp() {$application = new Zend_Application(APPLICATION_ENV, APPLICATION_PATH . '/configs/application.ini');$this->bootstrap = array($application->getBootstrap(), 'bootstrap');return parent::setUp();}public function tearDown() {/* Tear Down Routine */}public function testIndexAction() {$this->dispatch('/kontakt');$this->assertController('kontakt');$this->assertAction('index');}} - Aby nie musieć każdej klasy wywoływać osobno, możemy skonfigurować odpowiednie phpUnit. Przykładowy plik konfiguracyjny /tests/phpunit.xml może wyglądać tak:
1234567891011<phpunit bootstrap="./application/bootstrap.php"colors="true"convertErrorsToExceptions="true"convertNoticesToExceptions="true"convertWarningsToExceptions="true"stopOnFailure="false"><testsuite name="Test_ZF"><directory>./application/</directory></testsuite></phpunit>
Pierwszy test
Powstała klasę testującą możemy już uruchomić. Umieściłem przykładowy test (testIndexAction) sprawdzający czy znajdujemy się we właściwej lokalizacji. W tym celu udajemy się do /tests i wydajemy polecenie:
1 2 3 4 5 |
$ phpunit --configuration phpunit.xml PHPUnit 3.3.17 by Sebastian Bergmann. Time: 0 seconds OK (1 test, 2 assertions) |
Dzięki skorzystaniu z pliku konfiguracyjnego xml, nie będziemy musieli dokonywać żadnych modyfikacji podczas dodawania kolejnych klas testujących. Docelowo, można przygotować stronę, która przedstawi nam graficznie jakie klasy działają już prawidłowo.
Możliwości porównań pakietu Zend_Test / PHPUnit możemy znaleźć w dokumentacji.
Mam nadzieję, ze to małe wprowadzenie poszerzy grono programistów korzystających z Zend Framework do używania testów jednostkowych, tak bardzo przydatnych przy większych aplikacjach.