2009-01-30 8 views
15

Ho creato test di unità come un matto e ho scoperto che spesso devo installare qualcosa in un test che ho appena abbattuto in un test precedente. È mai ragionevole creare qualcosa (ad esempio un record di database) in un test (ad esempio un test di inserimento) e quindi utilizzarlo per un test successivo (ad esempio un test di eliminazione)? O ogni test dovrebbe essere sempre completamente autonomo?E 'una cattiva forma per contare sull'ordine dei test dell'unità NUnit

È possibile determinare l'ordine dei test in NUnit o sono sempre eseguiti in ordine alfabetico?

Nota: si richiede specificamente l'ordine dei test entro un file di prova. Non tra i file di test o in qualsiasi altro modo a livello globale.

Update: Grazie a tutti che hanno risposto - c'erano un sacco di buone risposte e il senso del gruppo è abbastanza unanime. Ho scelto la risposta di John Nolan in quanto ha fornito la spiegazione più completa e molti link. Come avrai intuito, sono stato fortemente tentato di infrangere questa regola nonostante pensassi che potrebbe essere un po '"puzzolente" come diceva John. Grazie anche a Fortyrunner per aver aggiunto il tag unit test.

+1

Buon lavoro nel riportare indietro e spiegare il tuo pensiero aggiornato. Molto bella. –

+0

Grazie, Jon. Immagino che questa sia una comunità e le comunità richiedono un certo grado di attenzione se vogliono crescere e prosperare. –

risposta

10

Fare affidamento sull'ordine dei test indica che si sta verificando lo stato tra i test. Questo è

Un metodo di verifica più pulito è dove si dipende solo dalla singola funzionalità che si desidera controllare. Comunemente si mock gli altri oggetti necessari per il funzionamento del metodo in prova.

Un buon modo per pensare ai test delle unità in avvicinamento è il modello Arrange, Act, Assert.

Di seguito è riportato un frammento dall'eccellente gratuito di Karl Seguin eBook. Ho annotato Arrange, Act e Assert.

[TestFixture] public class CarTest 
{ 
    [Test] public void SaveCarCallsUpdateWhenAlreadyExistingCar() 
    { 
     //Arrange 
     MockRepository mocks = new MockRepository(); 
     IDataAccess dataAccess = mocks.CreateMock<IDataAccess>(); 
     ObjectFactory.InjectStub(typeof(IDataAccess), dataAccess); 
     //Act 
     Car car = new Car(); 
     Expect.Call(dataAccess.Save(car)).Return(389); 
     mocks.ReplayAll(); 
     car.Save(); 
     mocks.VerifyAll(); 
     // Assert 
     Assert.AreEqual(389, car.Id); 
     ObjectFactory.ResetDefaults(); 
    } 
} 
+0

L'istruzione ObjectFactory.ResetDefaults() è effettivamente parte dell '"Asserzione"? Ci ho pensato un po ', e penso che dovrebbe essere chiamato Arrange, Act, Assert, Clean o Arrange, Act, Assert, Reset? Qualcosa del genere, o forse: Arrange, Act, Assert, Disarrange? –

+0

Mentre per lo più sono d'accordo con te, ci sono casi in cui un test deve semplicemente fare affidamento su un altro e/o usare oggetti finti può sconfiggere il punto del processo di test. Un esempio potrebbe essere un team che richiede che le funzioni vengano suddivise in pezzi più discreti di quanto sia ragionevole, o quando si esegue il test tra le versioni del backend del database. In questi casi mi piace utilizzare variabili statiche che possono essere impostate inizialmente, quindi sono disponibili per tutte le funzioni successive. – Brain2000

+0

@ Brain2000 Suggerirei che non si tratta di test di "unità" nel senso tradizionale. Non sono abbastanza sicuro di cosa intenda per "funzioni suddivise in pezzi più discreti di quanto sia ragionevole", ma in quest'ultimo caso sembra che tu stia facendo di più sui test di interazione/integrazione. Non c'è niente di sbagliato in questi, ma svolgono diversi lavori. –

3

Non mi farei affidamento sull'ordinazione dei test. Invece, vorrei inserire il codice di configurazione comune in un metodo separato e chiamarlo sia dal test semplice che da quello più complicato. In alternativa, basta chiamare il test di inserimento stesso all'inizio del test di cancellazione.

6

Vedrei ogni test come completamente indipendente da qualsiasi altro test. Anche se fosse possibile ordinare l'ordine dei test, sarebbe un incubo di manutenzione quando i test dovessero cambiare.

11

Cerca in test fixture setups che consente di specificare le funzioni che verranno eseguite prima di qualsiasi test nell'attrezzatura. Ciò consente di eseguire una configurazione comune una sola volta e verrà sempre eseguita, indipendentemente dal fatto che si esegua un test o tutti i test nella suite.

2

Purtroppo l'ordine di esecuzione del test dell'unità non è prevedibile o almeno potrebbe essere modificato in futuro. Per esempio. il framework di test dell'unità verrà modificato in modo che ogni test venga eseguito in thread separati. Quindi dal mio punto di vista l'uso di test non è ragionevole. D'altra parte è possibile creare una serie di piccoli test indipendenti per testare piccole parti del codice e quindi creare uno o più test di grandi dimensioni che eseguiranno i test di piccole dimensioni in un ordine specifico.

8

I test di unità sono concepiti come stand alone, non come uno script sequenziale. Se effettivamente ne hai bisogno, esegui in sequenza, raccoglierli in una singola funzione di test.

Se i test delle unità soffrono di expensive set-up, è possibile che si stiano eseguendo test di integrazione quando si pensa di eseguire il test dell'unità. Se stai colpendo un database SQL nella maggior parte dei tuoi test di unità, in realtà stai eseguendo il test di integrazione con il tuo livello di accesso ai dati.

3

Consiglio vivamente di rendere indipendenti tutti i test dell'unità.

La tua logica aziendale/struttura del database, ecc. Può cambiare nel tempo, quindi dovrai eventualmente sostituire o riscrivere (o persino scartare) i test di unità esistenti - e se hai diversi altri test a seconda di quello che 'in sostituzione, questo potrebbe causare problemi inutili perché dovresti passare attraverso tutti gli altri test e controllare se funzionano ancora come previsto.

Inoltre, un test dell'unità guasto non dovrebbe essere in grado di trascinare verso il basso molti altri (che potrebbero funzionare perfettamente da soli).

2

Se si dispone di prove di stateful (un problema comune con il lavoro del database - che è quello che faccio quando non sono su SO), quindi mi sembra che evitare ordine all'interno di un file di prova non è assolutamente necessario . Tuttavia, devi riconoscere che se hai 2 test, con il test 2 a seconda del test 1 che passa, otterrai un doppio errore "catastrofico" se il test 1 fallisce, perché il test 2 non ha l'impostazione prevista (e, Inoltre, vuoi preoccuparti se il test 2 passa dopo che il test 1 non è andato a buon fine se pensi che il test 2 dipenda dal passaggio del test 1).

Ecco perché si desidera che i test siano indipendenti ogni volta che è possibile, sia intra-file che interfile.

Sarebbe molto imprudente dipendere dall'ordine tra (serie di) test in file diversi.

Problemi correlati