2011-01-03 5 views
10

Sto cercando di concentrarmi un po 'sui test delle unità usando PHPunit.Test phpunit con database

ho trovato un ottimo tutorial qui http://blog.nickbelhomme.com/php/phpunit-training-course-for-free_282

ma c'è qualcosa che mi manca e non capisco ancora come fare.

Ho un modulo utente che mantiene tutte le informazioni sugli utenti. E c'è una funzione salva che salva l'utente nel database. Quindi ho un testFunction

public function testCanCreateUser() 
{ 
    $userData = array(
     'userName' => 'User1', 
     'firstName' => 'Joey', 
     'lastName' => 'Hendricks', 
     'email'  => '[email protected]', 
     'password' => 'f$tfe8F' 

    ); 
    $user = new Model_User($userData); 
    $user->save(); 

} 

La prima volta che eseguirò il mio test, funzionerà. Poiché il database è vuoto. Ma quando eseguo i miei test per la seconda volta non funzionerà poiché il mio sistema non consente lo stesso utente due volte nel db. Quindi per fare questo devo ricreare il mio database di test ogni volta prima di eseguire i miei test. Qual è il modo migliore per farlo? Oppure questo problema può essere risolto in un modo diverso?

Tnx.

risposta

21

Se si desidera testare la logica di business: Mock via la classe di database e restituire i dati falsi

Se si desidera verificare la classe che spara le istruzioni SQL (e imho si potrebbe testare anche questo da quando ho un pò voglio sapere se il mio codice funziona bene con un vero e proprio db nel backend) diventa un po 'complicato, ma ci sono modi per farlo:

  • utilizzando l'installazione () e tearDown() per ottenere uno stato consistente per i tuoi dati prima di eseguire i test è (imho) un ottimo modo per scrivere le unittest guidate da db. Può essere fastidioso scrivere un sacco di sql personalizzati a mano però.

  • Per rendere più semplice la tua vita, puoi guardare nello DbUnit extension e vedere se funziona per la tua applicazione.

  • Se davvero desidera immergersi in interazioni di database unit testing il miglior lettura sul soggetto è (secondo me) il capitolo sui db-unit testing in Sebastian Bergmanns phpqa book.

  • Se l'applicazione consente un nome di database personalizzato e l'installazione automatica di tutte le tabelle, potrebbe essere anche possibile impostare il db up una volta con molti testdata e utilizzare tali dati in tutti i test. Potresti stare attento così che quel test non si basa su dati scritti da un altro.

+2

Basta chiedersi come si sa che c'è un buon articolo nel libro di Sebastion Bergmanns mentre non è ancora uscito. Ma rimane una cosa complicata. – sanders

7

Eseguire test con un'altra copia del database vuota e/o deselezionata nei metodi setUp() o tearDown(), ma fare attenzione a non fare ciò che github did.

Se stai usando un buon database (cioè non MySQL con tabelle MyISAM) si può avvolgere di prova in una transazione e rotolare indietro dopo il test:

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

Lo svantaggio è che non si può codice di prova che utilizza le transazioni (a meno che non lo si astragga e si emuli con i punti di salvataggio, ma è così).

Idealmente si dovrebbe usare l'iniezione di dipendenza e test eseguiti su database di classe falso:

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

Penso che si possa utilizzare tearDown() metodo per pulire i dati salvati.

protected $_user; 

public function testCanCreateUser() 
{ 
    ... 

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

public function tearDown() 
{ 
    $this->_user->delete(); 
}