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:
Test jednostkowy napisany jest w postaci klasy XyzTest
, która dziedziczy z CTestCase
lub CDbTestCase, gdzie Xyz
oznacza klasę, która będzie testowana. Na przykład,
aby przetestować klasę postu Post
, nazwiemy odpowiadający jej test umownie PostTest
.
Klasa bazowa CTestCase przeznaczona jest dla ogólnych testów jednostkowych,
zaś klasa CDbTestCase jest bardziej odpowiednia dla testowania klas modeli
rekordu aktywnego. Ponieważ PHPUnit_Framework_TestCase
jest klasą rodzica dla obu klas, możemy używać wszystkich metod dziedziczonych z tej klasy.
Klasa testu jednostkowego jest zapisana w pliku PHP o nazwie XyzTest.php
.
Zgodnie z przyjętą konwencją plik testu jednostkowego może zostać zapisany
w katalogu protected/tests/unit
.
Klasa testująca zawiera głównie zestaw metod nazwanych wg wzorca testAbc
, gdzie Abc
często jest nazwą testowanej metody klasy.
Metoda testująca zazwyczaj zawiera sekwencję wyrażeń z asercjami (np. assertTrue
,
assertEquals
), które służą jako punkty kontrolne podczas sprawdzania zachowania
obiektu klasy.
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);
}
Found a typo or you think this page needs improvement?
Edit it on github !
Signup or Login in order to comment.