2011-08-23 10 views
40

Ho una classe caso di test PHPUnit (costituita da alcune funzioni di test). Vorrei scrivere una funzione oneTimeSetUp() da chiamare una volta per tutti i miei test nella classe (a differenza della funzione standard setUp() che viene chiamata una volta per ogni test della classe). In altre parole, sto cercando un equivalente PHPUnit allo JUnit @BeforeClass annotation.PHPUnit: come posso creare una funzione da chiamare una volta per tutti i miei test?

Stessa domanda con una funzione oneTimeTearDown().

È possibile farlo in PHPUnit?

+0

Comprendo perfettamente la necessità di farlo a volte per le prestazioni. Si consiglia di evitare questo, se possibile, in modo da non condividere lo stato tra i test. –

+2

@Greg: sono d'accordo. Tuttavia, ci sono situazioni in cui è meglio inizializzare una volta per tutti i test (per stabilire una connessione al db, ad esempio). – snakile

+0

Cerco di evitare di richiedere un server DB prendendo in giro l'adattatore Zend_Db/PDO nel mio datamapper, quindi eseguo asserzioni sullo SQL che producono le mie classi. Apprezzo a volte il suo inevitabile per test funzionali/end-to-end. –

risposta

59

Dai uno sguardo allo setUpBeforeClass() da section 6 della documentazione di PHPUnit.

Per la volta sola, è necessario utilizzare tearDownAfterClass();.

Entrambi questi metodi devono essere definiti nella classe come metodi statici.

+2

Stavo per scrivere la stessa cosa ...La tua risposta è LA risposta – Fabio

+5

Esiste un'alternativa non statica? – Martijn

+0

@Martijn sfortunatamente adesso non c'è un metodo per questo in phpunit. Fortunatamente puoi sostituire questa caratteristica mancante usando un flag "inizializzato" o un caricamento lazy in setUp(). Viene comunque eseguito prima di ogni test, ma non esegue nulla se la classe di test è già stata inizializzata. –

3

Sono arrivato a questa pagina con la stessa domanda, tuttavia la risposta accettata è stata eseguita su tutte le classi, e per me non era la risposta corretta.

Se siete come me, il vostro primo "test di integrazione" è quello di svuotare il DB ed eseguire le migrazioni. Questo ti porta a una base di dati di database per tutti i test. A questo punto cambio costantemente i file di migrazione, quindi l'impostazione della linea di base è davvero parte di tutti i test.

La migrazione richiede un po 'di tempo, quindi non voglio che venga eseguita su tutti i test.

Poi ho avuto bisogno di costruire il database testando ogni pezzo. Ho bisogno di scrivere un test d'ordine, ma prima devo creare alcuni prodotti e testarli, quindi ho bisogno di testare una funzione di importazione.

Quindi, quello che ho fatto è SUPER facile, ma non spiegato molto bene su internet. Ho creato un semplice test per configurare il database. Poi nel file phpspec.xml aggiungere una suite di test ....

<testsuite name="Products"> 
    <file>tests/in/SystemSetupTest.php</file> 
    <file>tests/in/ProductTest.php</file> 
    <file>tests/in/ProductImportTest.php</file> 
</testsuite> 

E nel la SystemSetupTest.php ....

class SystemSetupTest extends ApiTester 
{ 

    /** @test */ 
    function system_init() 
    { 
     fwrite(STDOUT, __METHOD__ . "\n"); 
     self::createEM(); //this has all the code to init the system... 
    } 
} 

eseguirlo come:

phpunit - -sestsuite Prodotti

Alla fine, è più facile. Mi consentirà di costruire correttamente il mio sistema.

Inoltre sto usando laravel 5. Quando utilizzo setUpBeforeClass() I problemi di bootstrap mi portano alla fine, che sono sicuro di poter risolvere, ma il metodo che uso sopra funziona perfettamente.

+0

Meglio di così corri prova in questo modo: './artisan migrate --datebase CONNECTION_NAME &&./Vendor/bin/phpunit'. Non è un grosso problema se si utilizza la cronologia dei comandi della shell. –

Problemi correlati