Standard di codifica dei test unitari

21

Di solito quando parliamo di standard di codifica ci riferiamo al codice del programma stesso, ma per quanto riguarda i test unitari? Esistono alcune linee guida sugli standard di codifica che sono esclusive dei test unitari? Quali sono?

    
posta EpsilonVector 31.10.2010 - 18:33
fonte

6 risposte

11

In cima alla mia testa, posso pensare a tre differenze nello stile di codifica per il codice di test.

Nei metodi di test di denominazione, seguo il modello di shouldDoSomethingWhenSomeConditionHolds .

All'interno del test, è consuetudine seguire il seguente schema di spaziatura:

@Test
shouldReturnAccountBalenceWhenGetBalenceIsCalled() {
    // Some lines 
    // of setup code
    // go here.

    // The action being tested happens after a blank line.

    // An assertion follows another blank line.
}

Alcuni insistono su una sola asserzione per test, ma questo è tutt'altro che universale.

Il DRY (Do not Repeat Yourself) è meno importante nel codice di test che nel codice di produzione. Mentre alcuni codici ripetuti devono essere inseriti in un metodo setUp o in una classe testUtils, il tentativo di azzerare la ripetizione nel codice di test porterà a test strettamente accoppiati e inflessibili, il che scoraggia il refactoring.

    
risposta data 31.10.2010 - 19:33
fonte
16

Roy Osherove consiglia il seguente schema per la denominazione dei test:

NameOfMethodUnderTest_StateUnderTest_ExpectedBehavior() 

Vedi link

    
risposta data 31.10.2010 - 19:53
fonte
5

La cosa principale è ricordare che i test unitari sono essenzialmente mini-specifiche. Ciò significa che l'accento deve sempre essere sulla leggibilità.

In primo luogo, ciò significa che i nomi devono comunicare chiaramente ciò che è sotto test e ciò che viene affermato.

In secondo luogo, tuttavia, che a volte viene dimenticato, è che le specifiche dovrebbero fare proprio questo: specificare il comportamento. Cioè, i test unitari non dovrebbero contenere la logica - o potenzialmente cadranno nella trappola di ripetere la funzionalità del programma piuttosto che testarla.

A volte i test coinvolgeranno oggetti che sono complessi da configurare, dovresti sforzarti di mantenere questa logica di configurazione separata dai tuoi test usando qualcosa come oggetto madre o costruttore di dati di test .

Concludo con alcuni consigli sui libri:

xTest di test di identità: codice test di refactoring: libro eccellente, alcuni dicono che è un po 'secco ma non lo faccio Penso di sì. Fornisce molti dettagli su molti modi diversi di organizzare i test e su come mantenerli mantenibili. Rilevante se stai usando qualcosa come NUnit ecc.

The Art of Unit Test: con esempi in .Net : il miglior libro sul nitty-grinty di scrivere e mantenere i test. Nonostante sia davvero nuovo, trovo le sezioni di derisione un po 'datate, dato che la sintassi AAA ora è piuttosto standard piuttosto che un altro modo di farlo.

Crescere il software orientato agli oggetti, guidato dai test : questo libro è semplicemente fantastico! Di gran lunga il miglior libro di test unitario e l'unico avanzato che mette il test unitario come cittadino di prima classe nel processo di progettazione. Stavo leggendo questo quando era una beta pubblica e lo raccomandavo da allora. Eccellente esempio di lavoro reale utilizzato in tutto il libro. Consiglierei comunque di leggere il libro di Roy prima.

    
risposta data 31.10.2010 - 19:55
fonte
3

Non inserire la logica nei test dell'unità. Ad esempio, supponiamo che stai testando un metodo di aggiunta, potresti avere qualcosa di simile a questo:

void MyTest_SaysHello()
{
   string name = "Bob";
   string expected = string.Format("Hello, {0}", name);
   IMyObjectType myObject = new MyObjectType();
   string actual = myObject.SayHello(name);
   Assert.AreEqual(expected, actual);
}

In questo caso particolare, probabilmente stai ripetendo la stessa logica di ciò che è nel test, quindi stai essenzialmente testando "1 + 1 == 1 + 1", piuttosto che "1 + 1 == 2", che è il "vero" test. Quindi quello che vorresti fosse il tuo codice di prova è:

void MyTest_SaysHello()
{
   string expected = "Hello, Bob";
   IMyObjectType myObject = new MyObjectType();
   string actual = myObject.SayHello("Bob");
   Assert.AreEqual(expected, actual);
}
    
risposta data 31.10.2010 - 20:37
fonte
0

Nomi di metodi lunghi e descrittivi. Ricorda che i metodi di test non vengono mai richiamati dal codice (vengono chiamati dall'unità di test runner che li rileva e li chiama tramite la reflection), quindi va bene impazzire e hanno nomi di metodi lunghi 50-80 caratteri. Convenzione di denominazione specifica (cammello-caso, underscore, "dovrebbe", "deve", "quando", "dato", ecc.) Non è veramente importante purché il nome risponda a tre domande:

  • cosa è in prova?
  • quali sono le condizioni?
  • qual è il risultato atteso?

I metodi di test dovrebbero essere brevi .

I metodi di prova dovrebbero avere una struttura semplice e lineare . Nessun costrutto if o loop.

I metodi di prova dovrebbero seguire lo schema "organizza-act-assert" .

Ogni test dovrebbe testare una cosa . Questo di solito significa un assert per test. Un test come { Do A; Assert B; Assert C; } dovrebbe essere refactored in due: { Do A; Assert B; } e { Do A; Assert C; }

Evita dati casuali o cose come "DateTime.Now"

Assicurati che tutti i membri del dispositivo di prova siano riportati al loro stato originale alla fine del test (ad esempio utilizzando un teardown )

Anche se rimuovi la duplicazione spietatamente nel tuo codice di produzione, la duplicazione del codice nei dispositivi di prova è un problema molto più piccolo.

    
risposta data 07.03.2011 - 23:51
fonte
-1

Un po 'simile a quello che Farmboy ha già menzionato, Il mio formato del nome del metodo

 <MethodName>Should<actionPerformed>When<Condition>

es

 GetBalanceShouldReturnAccountBalance() {
    
risposta data 01.11.2010 - 03:58
fonte

Leggi altre domande sui tag