2011-01-03 34 views
10

Próbuję skupić się nieco na testowaniu jednostkowym za pomocą PHPunit.Testowanie phpunit z bazą danych

Znalazłem bardzo dobry tutorial tutaj http://blog.nickbelhomme.com/php/phpunit-training-course-for-free_282

Ale jest coś, czego brakuje, a nie jeszcze zrozumieć, jak to zrobić.

Mam moduł użytkownika, który przechowuje wszystkie informacje o użytkownikach. I jest funkcja save, która zapisuje użytkownika w bazie danych. Tak więc mam testFunction

Pierwszy raz, kiedy poprowadzę mój test to wil pracy. Ponieważ baza danych jest pusta. Ale kiedy uruchomię moje testy po raz drugi, nie będzie działać, ponieważ mój system nie pozwala temu samemu użytkownikowi dwukrotnie w db. Tak więc, aby to zrobić, muszę odtworzyć moją bazę testową za każdym razem, zanim uruchomię testy. Jaki jest najlepszy sposób na zrobienie tego? Czy ten problem można rozwiązać na inny sposób?

Tnx.

Odpowiedz

21

Jeśli chcesz sprawdzić swoją logikę biznesową: Mock dala klasa Database i powrót fałszywych danych

Jeśli chcesz przetestować klasę, która wyzwala SQL (i imho mogłeś sprawdzić, czy też od Jakbym chce wiedzieć, czy mój kod działa poprawnie z prawdziwym db w backend) robi się trochę skomplikowane, ale istnieją sposoby, aby to zrobić:

  • Korzystanie setup () i tearDown(), aby uzyskać spójny stan danych przed uruchomieniem testów, to (imho) świetny sposób na zapisywanie unittests opartych na db. Może być denerwujące, aby ręcznie napisać dużo niestandardowego sql.

  • Aby ułatwić sobie życie, można zajrzeć do DbUnit extension i sprawdzić, czy to działa dla Twojej aplikacji.

  • Jeśli naprawdę chcą zanurzyć się w interakcjach baz danych test jednostkowy najlepszą przeczytać na ten temat jest (IMHO) rozdział na db-test jednostkowy w Sebastian Bergmanns phpqa book.

  • Jeśli twoja aplikacja zezwala na niestandardową nazwę bazy danych i automatyczną konfigurację wszystkich tabel, może być również możliwe ustawienie bazy danych raz z dużą ilością danych testowych i użycie tych danych we wszystkich testach. Możesz być ostrożny, więc jeden test nie opiera się na danych zapisanych przez inny.

+2

Zastanawiasz się, skąd wiesz, że w książce Sebastion Bergmanns jest dobry artykuł, podczas gdy jeszcze go nie ma. Ale pozostaje to rzeczą skomplikowaną. – sanders

7

Wykonaj testy z inną kopią bazy danych, która jest pusta i/lub wyczyszczona w metodach setUp() lub tearDown(), ale uważaj, aby nie robić tego, co github did.

Jeśli używasz dobrą bazę (czyli nie MySQL z tabel MyISAM) można owinąć testu w transakcji i zwinąć ją z powrotem po teście:

function setUp() { $this->db->exec("BEGIN"); } 
function tearDown() { $this->db->exec("ROLLBACK"); } 

Minusem jest to, że nie można kod testowy, który wykorzystuje transakcje (chyba że je zredukujesz i naśladujesz z punktami zapisywania, ale to jest niepewne).

Idealnie należy użyć iniekcji zależność i testy zakończą się na fałszywej klasy bazy danych:

$fakedb = new DatabaseThatDoesntReallySaveThings(); 
$user = new Model_User($fakedb, $userData); 
$user->save(); 
$this->assertTrue($fakedb->wasAskedToSaveUser()); 
2

myślę, że można użyć tearDown() metodę czyszczenia zapisanych danych.

protected $_user; 

public function testCanCreateUser() 
{ 
    ... 

    $this->_user = new Model_User($userData); 
    $this->_user->save(); 
} 

public function tearDown() 
{ 
    $this->_user->delete(); 
} 
Powiązane problemy