2011-12-06 14 views
6

Ho recentemente aderito una società dove si utilizzano TDD, ma non è ancora chiaro per me, per esempio, abbiamo una prova:Perché questo particolare test potrebbe essere utile?

[TestMethod] 
public void ShouldReturnGameIsRunning() 
{ 
    var game = new Mock<IGame>(); 
    game.Setup(g => g.IsRunning).Returns(true); 
    Assert.IsTrue(game.Object.IsRunning); 
} 

Qual è lo scopo di esso? Per quanto ho capito, questo non sta testando nulla! Dico questo perché sta prendendo in giro un'interfaccia e dicendo, restituisce true per IsRunning, non restituirà mai un valore diverso ...

Probabilmente sto pensando male, come tutti dicono che è una buona pratica ecc ecc ... o questo test è sbagliato?

+3

solito resti non sono questo inutile. – sarnold

+3

Hai due cose diverse in questa domanda: "Qual è lo scopo del TDD?" e "Qual è il punto di questo test?" - Fai attenzione a tenere separati i due nella tua testa. Il valore (o non) di TDD non può essere giudicato in modo equo da un singolo test (forse scarso). – Bevan

+0

Vorrei poterlo chiudere come un duplicato di http://stackoverflow.com/questions/tagged/tdd?sort=votes&pagesize=50 –

risposta

5

Il test non è valido. Moq è un framework utilizzato per "simulare" gli oggetti utilizzati dal metodo in prova. Se stavi testando IsRunning, potresti usare Mock per fornire una certa implementazione per quei metodi che dipendono da IsRunning, ad esempio per causare determinati percorsi di esecuzione da eseguire.

Le persone possono dirti tutto il giorno che testare prima è meglio; non ti renderai conto che lo è fino a quando non inizi a farlo da solo e ti rendi conto che hai meno bug con il codice che hai scritto per primi, il che farà risparmiare tempo a te e ai tuoi colleghi e probabilmente renderà più alta la qualità del tuo codice.

+0

hmm Ho il sospetto che ... c'è un'interfaccia dell'interfaccia IGame che non è stata testata affatto, ecco perché non ottengo l'idea di questo ... – user1082693

+0

non ha senso avere un'altra implementazione dell'interfaccia IGame, dovrebbero testare l'oggetto Game invece dell'interfaccia, giusto? Che ne dici di guidare il design del codice? Voglio dire, come dovrei definire che ci deve essere una proprietà IsRunning? – user1082693

+0

@ user1082693: giusto. Ora, se stavate testando il comportamento di un metodo basato su determinati valori di ritorno dei metodi di 'IGame', Moq sarebbe sicuramente utile - la creazione di una nuova sottoclasse di' IGame' solo a scopo di test sarebbe risultata dolorosa. Per quanto riguarda il testing di una certa proprietà, vorrei che i costrutti di codice come le interfacce e le classi astratte applicassero tali regole. –

3

Potrebbe essere che il test sia stato scritto (prima) il codice che è una buona pratica.

Potrebbe anche essere che questo è un test inutile creato da uno strumento.

+0

Non penso ci sia nessuno strumento che crea il test qui, quindi è probabilmente che hanno scritto il test prima del codice quindi .. hmmm – user1082693

+6

Dipende dalla tua definizione di "strumento"! :) – griegs

+3

+1 e potremmo indicare sia il significato popolare della parola "strumento";) –

6

Questo test sta excerising un'interfaccia e verifica che l'interfaccia esponga un getter booleano denominato IsRunning.

Questo test è stato probabilmente scritto prima che esistesse lo interface e probabilmente molto prima che esistessero anche le classi concrete di IGame. Immagino, se il progetto è di una certa maturità, ci sono altri test che esercitano le effettive implementazioni e verificano il comportamento per quel livello, e probabilmente usano il mocking nel contesto isolazionista più tradizionale piuttosto che lo stub delle forme teoriche.

Il valore di questo tipo di test è che obbliga a pensare a come una forma o un oggetto verrà utilizzato. Qualcosa sulla falsariga di "Non so esattamente cosa farà ancora un gioco, ma so che vorrò verificare se è in esecuzione ...". Quindi questo tipo di test è più per guidare le decisioni di progettazione, oltre che per validare il comportamento.

Non è il test più prezioso del pianeta, ma serve il suo scopo secondo me.

Modifica: Ero sul treno ieri sera mentre stavo scrivendo questo, ma volevo rispondere al commento di Andrew Whitaker direttamente nella risposta.

Si potrebbe sostenere che la firma nell'interfaccia stessa sia sufficiente per l'applicazione del contratto desiderato. Tuttavia, questo dipende in realtà da come trattate le vostre interfacce e in ultima analisi come convalidate il sistema che state provando a testare.

Potrebbe esserci un valore tangibile nel dichiarare esplicitamente questa funzionalità come test. Stai verificando esplicitamente che questa è una funzionalità desiderata per un IGame.

Prendiamo un caso d'uso, diciamo che come designer sai che vuoi esporre un getter pubblico per IsRunning, così lo aggiungi all'interfaccia.Ma diciamo che un altro sviluppatore ottiene questo e vede una proprietà, ma non vede alcun utilizzo di esso in nessun'altra parte del codice, si potrebbe presumere che sia idonea alla cancellazione (o alla rimozione del codice, che normalmente è una buona cosa) senza danno. L'esistenza di questo test, tuttavia, afferma esplicitamente che questa proprietà dovrebbe esistere.

Senza questo test, uno sviluppatore potrebbe modificare l'interfaccia, rilasciare l'implementazione e il progetto si compilerebbe ed eseguirà apparentemente correttamente. E sarebbe molto più tardi che qualcuno potrebbe notare che l'interfaccia è stata cambiata.

Con questo test, anche se sembra che nessuno lo stia utilizzando, la suite di test avrà esito negativo. La natura autodocumentante del test ti dice che ShouldReturnGameIsRunning(), che per lo meno dovrebbe generare una conversazione se IGame dovrebbe davvero esporre un getter IsRunning.

+1

cool ho capito ... chiederò loro domani, quindi dovrebbe essere probabilmente guidare il design, e poi dovrei creare più test per testare la logica, giusto? – user1082693

+0

@ 32bitkid: questa potrebbe essere solo la mia opinione, ma non è un overkill di prova per questo?Non definirebbe semplicemente una firma per il metodo nell'interfaccia per creare il "contratto" per cui questo test sta provando? –

+1

@AndrewWhitaker. Penso che dipenda da come pensi di convalidare il sistema che stai provando a testare. Potrebbe esserci qualche valore nel dichiarare esplicitamente questo come test che questa è una funzionalità desiderata per un 'IGame'. Se fosse solo la firma, se da un lato lo si utilizza in qualsiasi luogo potrebbe apparire come se potesse essere rimosso senza danno. Questo test afferma esplicitamente che questa proprietà dovrebbe esistere. In caso contrario, anche se nessuno lo sta utilizzando, i test non riusciranno a risolvere –

1

Un'altra possibilità è che il codice sia stato scritto da qualcuno che, al momento, non capiva come utilizzare quel particolare modello di derisione e scriveva uno o più test semplici da imparare. Kent Beck ha parlato di quel tipo di "test di apprendimento" nel suo libro TDD originale.

0

Questo test avrebbe potuto avere un punto nel passato. Avrebbe potuto testare una classe concreta. Avrebbe potuto testarne uno astratto, perché a volte ha senso prendersi gioco di una classe astratta che si desidera testare. Posso vedere come un seguace (meno informato (come me)) del modo di fare TDD avrebbe potuto lasciare un piccolo casino come questo. La pulizia del codice morto e del codice di test guasto, non si adatta perfettamente al naturale flusso di lavoro del rosso, del verde, del refattore (poiché non infrange alcun test!). Tuttavia, la cronologia non è una giustificazione per un test che non fa altro che confondere il lettore. Quindi, sii un buon boyscout e rimuovilo.

0

a mio parere onesto questo è solo spazzatura, prova solo che moq funziona come previsto

Problemi correlati