Testy jednostkowe

Ponieważ framework testujący w Yii zbudowany jest na bazie PHPUnit, zalecane jest wcześniejsze przejrzenie dokumentacji PHPUnit w celu uzyskania podstawowej wiedzy o pisaniu testów jednostkowych. Poniżej podsumowujemy podstawowe zasady pisania testów jednostkowych w Yii:

W dalszej części opiszemy przede wszsytkim jak pisać testy jednostkowe dla klas modeli rekordu aktywnego. Będziemy rozszerzać nasze klasy testujące dziedzicząc z klasy CDbTestCase gdyż dostarcza ona wsparcia dla konfiguracji testów bazodanowych, o której pisaliśmy w poprzednim rozdziale.

Załóżmy, że chcemy przetestować klasę modelu komentarza Comment z przykładowego blogu. Rozpoczynamy poprzez utworzenie klasy o nazwie CommentTest i zapisania jej jako protected/tests/unit/CommentTest.php:

class CommentTest extends CDbTestCase
{
    public $fixtures=array(
        'posts'=>'Post',
        'comments'=>'Comment',
    );
 
    ......
}

W klasie tej, określamy zmienną fixtures jako tablicę opisującą konfiguracje testów, które będa używane przez ten test. Tablica reprezentuje mapowanie pomiędzy nazwami konfiguracji testów a nazwami modeli klas bądź też nazwami konfiguracji testów bazodanowych (np. pomiędzy nazwą konfiguracji testu posts a klasą modelu Post). Zauważ, iż podczas mapowania do nazw tabeli konfiguracji testu, poprzedzamy tabelę dwukropkiem (np. :Post) aby odróżnić ją od nazwy klasy modelu. Jeśli będziemy używać nazw klas modeli, odpowiadające im tabele będą traktowane jako tabele konfiguracji testu. Jak już opisaliśmy wcześniej, konfiguracje testu będą zresetowane do jakiegoś znanego stanu, za każdym razem, kiedy metoda testowa jest wywoływana.

Nazwy konfiguracji testu pozwalają nam na wygodny dostęp do danych konfiguracji testu w metodach testujących. Poniższy kod przedstawia ich typowe użycie:

// zwraca wszystkie wiersze z konfiguracji testu dla tabeli komentarzy 'Comment'
$comments = $this->comments;
// zwraca wiersz, którego aliasem jest 'sample1' w konfiguracji testu dla tabeli postów `Post` 
$post = $this->posts['sample1'];
// zwraca instancję AR reprezentującą wiersz danych z konfiguracji testu 'sample1' 
$post = $this->posts('sample1');

Uwaga: Jeśli konfiguracja testu została zdefiniowana przy użyciu nazwy tabeli
(np. 'posts'=>':Post'), wtedy zaprezetnowany powyżej 3 przykład użycia jest niepoprawny, ze względu na to, iż nie posiadamy informacji jaka klasa modelu jest powiązana z tabelą.

W dalszej części opiszemy metodę testApprove testującą metodę approve w klasie modelu komentarza Comment. Kod jest bardzo prosty: najpierw wstawiamy komentarz, który posiada status "oczekujący"; następnie sprawdzamy czy komentarz ten posiada status "oczekujący" poprzez odczytanie go z bazy danych; na końcu wołamy metodę approve i sprawdzamy czy status zmienił tak jak oczekiwaliśmy.

public function testApprove()
{
    // wstaw komentarz o statusie "oczekujący"
    $comment=new Comment;
    $comment->setAttributes(array(
        'content'=>'comment 1',
        'status'=>Comment::STATUS_PENDING,
        'createTime'=>time(),
        'author'=>'me',
        'email'=>'me@example.com',
        'postId'=>$this->posts['sample1']['id'],
    ),false);
    $this->assertTrue($comment->save(false));
 
    // zweryfijuj komentarz o statusie "oczekujący"
    $comment=Comment::model()->findByPk($comment->id);
    $this->assertTrue($comment instanceof Comment);
    $this->assertEquals(Comment::STATUS_PENDING,$comment->status);
 
    // wywołaj metodę approve() i sprawdź czy komentarz znajduje się w statusie "zatwierdzony"
    $comment->approve();
    $this->assertEquals(Comment::STATUS_APPROVED,$comment->status);
    $comment=Comment::model()->findByPk($comment->id);
    $this->assertEquals(Comment::STATUS_APPROVED,$comment->status);
}
$Id: test.unit.txt 2841 2011-01-12 21:04:12Z alexander.makarow $