2010-07-31 9 views
12

Diciamo che sto iniziando a fare un gioco con TDD. E 'un buon primo test?Primo test TDD senza alcuna eccezione assert/prevista. Ne vale la pena?

[TestMethod] 
public void Can_Start_And_End_Game() 
{ 
    Tetris tetris = new Tetris(); 
    tetris.Start(); 
    tetris.End(); 
} 

mi costringe in sostanza di definire 3 cose: la classe e le sue TetrisStart() e End() metodi, ma oltre a questo è abbastanza inutile. Potrebbe avere il suo interesse immediatamente poiché con loro posso definire quella classe e quei metodi, ma in seguito probabilmente non servirà a nessun tipo di scopo. Il suo unico scopo potrebbe forse mostrare che deve essere possibile iniziare una partita e terminarla senza ottenere un'eccezione nel mezzo.

Cosa ne pensi?

+0

in Java, metodi non sono capitalizzati. Quindi 'tetris.start()' e 'tetris.end()' –

+3

Sicuro. Ma in C# lo sono. –

+0

Tecnicamente questo è un test di integrazione perché stai testando più di una cosa. Dovresti avere test per Start, test per End e questo test di integrazione. –

risposta

19

mi costringe in sostanza di definire 3 cose: la classe di Tetris e metodi suo inizio() e end(),

Vero.

ma oltre a questo è abbastanza inutile.

Falso.

tardi probabilmente non servirà alcun tipo di scopo

False, anche.

Il suo scopo ... [è] per mostrare che deve essere possibile avviare un gioco e terminarla senza ottenere un'eccezione in mezzo

E questo è ENORME. Epico. Monumentale.

In effetti, quel test fallirà così spesso che crescerai fino a odiarlo. Ogni eccezione non gestita, non rilevata da tutti i tipi di luoghi casuali nel tuo programma fallirà questo test. Costruirai un'accurata registrazione e debug a causa di questo test.

Questo test è EPIC.

+0

Wow, non ci avevo pensato. –

+0

EPIC !!!!!!!!!!! – strager

+2

"Questo test è EPIC" +1 :) – Skilldrick

1

Penso che lo scopo del test può essere resa più chiara con la cattura di eventuali eccezioni e in modo esplicito il fallimento della prova se happpens:

[TestMethod] 
public void Can_Start_And_End_Game() 
{ 
    try 
    { 
     Tetris tetris = new Tetris(); 
     tetris.Start(); 
     tetris.End(); 
    } 
    catch (Exception ex) 
    { 
     Assert.Fail("Unexpected exception thrown: " + ex.ToString()); 
    } 
} 
+2

C'è un metodo 'Assert.DoesNotThrow' che fa questo. – strager

+0

Non è ridondante come dire "lascia x = x" o "if (true == true)"? Ho pensato che fosse la convenzione xunit che l'idea "DoesNotThrow" è sempre implicita e compresa, con o senza asserzioni di qualsiasi tipo, indipendentemente dal nome del metodo. – apollodude217

3

Io non sono un grande fan di questo test. Sì, ha aiutato a definire l'interfaccia, ma non è molto forte per definire (e testare) il comportamento.

Penso che potrebbe essere meglio avere un test che gestisca l'avvio. Probabilmente affermerebbe le impostazioni di default o i valori di punteggio. Poi avrei test aggiuntivi per vedere se è possibile terminare una partita.

Idealmente ogni metodo di test esegue un comportamento.

+3

+1. Un buon test ha un'unica affermazione in esso; questo non ha nessuno. – TrueWill

1

Sì, il test conferma che nessuna eccezione è stata generata nel costruttore, il Start() e il metodo Stop().

Vedo poco valore in un blocco try/catch aggiuntivo all'interno del test per rilevare le eccezioni. Lo strumento che esegue il test prenderà e segnalerà quelli. Usando il principio TSTTCPW il test può fare a meno del blocco try/catch.

È possibile rendere il test un po 'più significativo aggiungendo asserzioni alla fine, ad esempio convalidando il valore delle proprietà sull'oggetto tetris.

Fare attenzione alla differenza tra la scrittura di un test unitario e l'uso di TDD. Il valore deriva dalla comprensione di questa differenza.

7

Non stai guidando lo sviluppo della classe Tetris con questo test - hai deciso quale dovrebbe essere la sua API, che va bene, ma perché non scrivere un test che testa qualcosa che dovrebbe effettivamente fare?

I test devono informare l'API, non viceversa (imho).

+0

Penso che l'hai inchiodato. Ma dai anche un'occhiata alla risposta di S. Lott. –

+0

@devoured - Grazie. In realtà preferisco S. Lott's :) – Skilldrick

1

Come ha detto S. Lott, questo test copre un TON di terreno. E 'così "vale la pena" che vale la pena di spezzare in almeno 3 test e l'aggiunta di affermazioni appropriate per ciascuna:

[TestMethod] 
public void Test_Contructor() 
{ 
    Tetris tetris = new Tetris(); 
    // make assertions 
} 

[TestMethod] 
public void Test_Start() 
{ 
    // setup 
    Tetris tetris = new Tetris(); 

    // exercise 
    tetris.Start(); 

    // make assertions 
} 

[TestMethod] 
public void Test_End() 
{ 
    // setup 
    Tetris tetris = new Tetris(); 
    tetris.Start(); 

    // exercise 
    tetris.End(); 

    // make assertions 
}