Testowanie

Uwaga: Wparcie dla testowania opisane w tym rozdziale wymaga Yii w wersji 1.1 lub wyższej. Nie oznacza to jednak, że nie możesz testować aplikacji utworzonej za pomocą Yii 1.0.x.
Istnieje wiele świetnych frameworków testujących, które mogą posłużyć Ci w tym celu, takich jak PHPUnit, SimpleTest.

Testowanie jest nieodzownym procesem podczas tworzenia oprogramowania.

Bez względu na to, czy zdajemy sobie z tego sprawę, czy też nie, przeprowadzamy testy cały czas w procesie tworzenia aplikacji internetowej. Na przykład, podczas pisania klasy w PHP, możemy używać instrukcji echo lub die w celu pokazania, że zaimplementowaliśmy metodę poprawnie. Podczas tworzenia strony zawierającej złożone formularze HTML, możemy spróbować wprowadzić trochę danych testowych aby upewnić się, że interakcja pomiędzy stroną a nami jest taka jakiej oczekujemy. Bardziej zaawansowani programiści napiszą kod aby zautomatyzować wspomniany proces testowania, w taki sposób, aby za każdym razem gdy występuje potrzeba przetestowania czegoś, wywołać napisany kod i pozwolić komputerowi wykonać testy za nas. Takie postępowanie nazywamy testami automatycznymi i są one głównym tematem niniejszego rozdziału.

Wsparcie testów oferowane przez Yii to wsparcie dla testów jednostkowych oraz testów funkcjonalnych.

Test jednostkowy weryfikuje czy pojedyncza jednostka kodu działa w oczekiwany sposób. W obiektowo zorientowanym programowaniu, najbardziej podstawową jednostką kodu jest klasa. Tak więc test jednostkowy weryfikuje głównie to czy metody interfejsu klasy działają prawidłowo. Oznacza to, że biorąc różne parametry wejściowe, test weryfikuje czy metoda zwraca oczekiwany rezultat. Testy jednostkowe zazwyczaj są pisane przez ludzi, którzy tworzą klasę, która ma być testoswana.

Test funkcjonalny weryfikuje czy funkcjonalność (np. zarządzanie postami w systemie blogowym) działa jak należy. W porównaniu do testu jednostkowego, test funkcjonalny znajduje się na wyższym poziomie, ponieważ testowana funkcjonalność wykorzystuje wiele klas. Testy funkcjonalne pisane są zazwyczaj przez ludzi, którzy bardzo dobrze znają
wymagania stawiane systemowi (mogą być to zarówno programiści jak i inżynierowie jakości).

1. Programowanie sterowanie testami (ang. TDD, Test-Driven Development)

Poniżej przedstawimy cykle programowania w tak zwanym programowaniu sterowanym testami (TDD):

  1. Utwórz nowy test, który pokrywa zaimplementowaną funkcjonalność. Oczekuje się, że test nie powiedzie się podczas pierwszego wywołania, ponieważ funkcjonalność ta dopiero zostanie zaimplementowana.
  2. Uruchom wszystkie testy i upewnij się, że nowy test nie powiódł się.
  3. Napisz kod, tak aby nowy test powiódł się.
  4. Wywołaj wszystkie testy i upewnij się, że wszystkie powiodły się.
  5. Po poprawieniu kodu, który został nowo napisany i upewnij się, że wszystkie testy wciąż kończą się sukcesem.

Powtarzaj kroki od 1 do 5 w celu kontynuowania implementacji funcjonalności.

2. Konfiguracja środowiska testowego

Wsparcie dla testów oferowane przez Yii wymaga PHPUnit 3.5+ oraz Selenium Remote Control 1.0+. Aby dowiedzieć się jak zainstalować PHPUnit oraz Slenium Remote Control, zajrzyj do ich dokumentacji.

Jeśli używasz komend konsoli yiic webapp w celu utworzenia nowej aplikacji Yii, wygeneruje ona nastepujące pliki i katalogi za nas do pisania i wykonywania nowych testów:

testdrive/
   protected/                zawiera chronione pliki aplikacji
      tests/                 zawiera testy dla aplikacji
         fixtures/           zawiera odprzęt testowania bazy danych
         functional/         zawiera testy funcjonalne
         unit/               zawiera testy jednostkowe
         report/             zawiera containing raporty pokrycia (ang. coverage reports)
         bootstrap.php       skrypt wykonywany na samym początku
         phpunit.xml         plik konfiguracyjny PHPUnit
         WebTestCase.php     klasa bazowa dla internetowych testów funkjonalnych 

Jak widać powyżej, nasz kod testujący będzie się znajdował głównie w trzech katalogach: fixtures, functional oraz unit, a katalog report będzie używany do przechowywania wygenerowanych rapotów pokrycia.

Aby wywołać testy (zarówno testy jednostkowe jak i funkcjonalne), możemy wykonać następujące instrukcje w oknie konsoli:

% cd testdrive/protected/tests
% phpunit functional/PostTest.php    // wykonuje pojedynczy test
% phpunit --verbose functional       // wykonuje wszystkie testy w katalogu 'functional'
% phpunit --coverage-html ./report unit

W powyższych przykładzie ostatnia komenda wykona wszystkie testy w katalogu unit i wygeneruje raport pokrycia kodu w katalogu report. Zauważ, że rozszerzenie xdebug musi być zainstalowane i aktywowane w celu wygenerowania raportów pokrycia kodu.

3. Skrypt startowy testu

Zobaczmy co można znaleźć w pliku bootstrap.php. Plik ten jest szególny ze względu na to, że przypomina skrypt wejściowy i jest on punktem startowym podczas wykonywania zestawu testów.

$yiit='path/to/yii/framework/yiit.php';
$config=dirname(__FILE__).'/../config/test.php';
require_once($yiit);
require_once(dirname(__FILE__).'/WebTestCase.php');
Yii::createWebApplication($config);

W powyższym kodzie, najpierw załączamy plik yiit.php z frameworku Yii, który inicjalizuje pewne zmienne globalne i dołącza wymagane klasy podstawowe klasy testów. Następnie tworzymy instancję aplikacji sieciowej używając pliku konfiguracyjnego test.php. Jeśli sprawdzimy test.php, powinniśmy zauważyć, że dziedziczy on z pliku konfiguracyjnego main.php i dodaje komponent aplikacji fixture, którego klasą jest CDbFixtureManager. Stałe składniki (ang. fixtures) opiszemy szczzegółowo w następnym rozdziale.

return CMap::mergeArray(
    require(dirname(__FILE__).'/main.php'),
    array(
        'components'=>array(
            'fixture'=>array(
                'class'=>'system.test.CDbFixtureManager',
            ),
            /* uncomment the following to provide test database connection
            'db'=>array(
                'connectionString'=>'DSN for test database',
            ),
            */
        ),
    )
);

Jeśli wywołujemy testy, które używają bazy danych, powinniśmy dostarczyć testową bazę danych, tak aby wywołanie testu nie kolidowało z czynnościami wykonywanymi na produkcji czy też w środowisku deweloperskim. Aby tak się stało, musimy tylko odkomentować konfigurację db w powyższym kodzie i wypełnić właściwość connectionString wartością DSN (nazwa źródła danych) wskazującą na bazę testową.

Przy pomocy takiego skryptu startowego, podczas uruchamiania testów jednostkowych, otrzymamy instancję aplikacji, która jest niemal identyczna z tą dostarczaną dla żądań sieciowych. Główna różnica polega na tym, że posiada ona menedżer zarządzania stałymi
składnikami (ang. fixture manager) oraz używa bazę testową.

$Id: test.overview.txt 2997 2011-02-23 13:51:40Z alexander.makarow $

Be the first person to leave a comment

Please to leave your comment.