2012-02-17 14 views
31

Perché è che ogni quadro unit testing (che conosco :) richiede che il valore atteso nei test di uguaglianza è sempre il primo argomento:Test delle unità: perché l'argomento previsto è sempre il primo nei test di uguaglianza?

Assert.AreEqual(42, Util.GetAnswerToLifeTheUniverseAndEverything()); 

assertEquals(42, Util.GetAnswerToLifeTheUniverseAndEverything()); 

ecc

Sono abbastanza abituato ora, ma ogni programmatore che cerco di insegnare come unità di test fa l'errore di invertire gli argomenti, che io capisco perfettamente. Google non ha aiutato, forse uno dei collaudatori di unità hard-core qui conosce la risposta?

+0

Hai guardato i messaggi di errore predefiniti che vengono generati quando un test fallisce? Ecco perchè. O stai chiedendo perché i messaggi sono scritti in quel modo? Stai chiedendo dello "standard" C che si preoccupa di 'if (23 = a)' vs. 'if (a = 23)'? E 'questo quello che stai chiedendo? –

+1

Forse solo per comodità, l'espressione di asserzione può essere relativamente complessa, quindi mettere i risultati attesi per prima cosa rende più facile la ricerca. –

+0

@ S.Lott: so perché ho bisogno di passarli in questo ordine, voglio sapere perché la maggior parte delle interfacce di test di unità sono scritte in questo modo. –

risposta

7

penso che è solo una convenzione ormai e, come lei ha detto che è adottato da "ogni quadro unit testing (che conosco)". Se si utilizza un framework sarebbe fastidioso passare a un altro framework che utilizza la convenzione opposta. Quindi (se stai scrivendo una nuova unità di test framework per esempio) sarebbe preferibile anche per te seguire la convenzione esistente. Credo che questo deriva dal modo in cui alcuni sviluppatori preferiscono scrivere i loro test di uguaglianza:

if (4 == myVar) 

Per evitare qualsiasi cessione indesiderata, per errore, scrivendo un "=" al posto di "==". In questo caso il compilatore catturerà questo errore e eviterete un sacco di problemi nel tentativo di correggere un bug di runtime strano.

5

Nessuno lo sa ed è la fonte di confusioni senza fine. Tuttavia non tutti i quadri seguono questo modello (ad una maggiore confusione):

  1. FEST-Assert utilizza normale ordine:

    assertThat(Util.GetAnswerToLifeTheUniverseAndEverything()).isEqualTo(42); 
    
  2. Hamcrest:

    assertThat(Util.GetAnswerToLifeTheUniverseAndEverything(), equalTo(42)) 
    
  3. ScalaTest non lo fa davvero fare una distinzione:

    Util.GetAnswerToLifeTheUniverseAndEverything() should equal (42) 
    
1

Non so, ma ho partecipato a diverse discussioni animate sull'ordine degli argomenti ai test di uguaglianza in generale.

Ci sono un sacco di persone che pensano

if (42 == answer) { 
    doSomething(); 
} 

è preferibile

if (answer == 42) { 
    doSomething(); 
} 

nei linguaggi C-based. La ragione di questo è che se si mette accidentalmente un unico segno di uguale:

if (42 = answer) { 
    doSomething(); 
} 

vi darà un errore di compilazione, ma

if (answer = 42) { 
    doSomething(); 
} 

non potrebbe, e sarebbe sicuramente introdurre un bug che potrebbe essere difficile rintracciare. Quindi, chi lo sa, forse la persona/le persone che hanno creato il quadro di test unitario sono stati abituati a pensare ai test di uguaglianza in questo modo - o stavano copiando altri framework di test unitari che erano già stati impostati in questo modo.

1

Penso che sia perché JUnit è stato il precursore della maggior parte dei framework di testing unitario (non che fosse il primo framework di testing unitario, ma ha dato il via a un'esplosione nei test unitari). Da quando JUnit lo ha fatto in quel modo, tutti i quadri successivi hanno copiato questo modulo ed è diventato una convenzione.

perché JUnit è stato così? Non lo so, chiedi a Kent Beck!

21

Sembra che la maggior parte dei quadri primi usati prevede prima attuale (per qualche motivo sconosciuto, però, lancio dei dadi forse?). Tuttavia, con lo sviluppo dei linguaggi di programmazione e con l'aumento della fluidità , l'ordine è stato annullato. Le interfacce più fluenti di solito cercano di imitare il linguaggio naturale e le strutture di test delle unità non sono diverse.

Nell'asserzione, vogliamo assicurare che alcuni oggetti soddisfano alcune condizioni. Questa è la forma del linguaggio naturale, come se si dovesse spiegare il tuo codice di prova si sarebbe probabilmente dire

"In questo test, mi assicuro che il valore calcolato è pari a 5"

invece di

"In questo test, mi assicuro che 5 sia uguale al valore calcolato".

La differenza potrebbe non essere enorme, ma spingiamola ulteriormente. Considera questo:

Assert.That(Roses, Are(Red)); 

Suoni di destra. Now:

Assert.That(Red, Are(Roses)); 

Hm ..? Probabilmente non saresti troppo sorpreso se qualcuno ti dicesse che le rose sono rosse. Altrimenti, rosso sono rose, solleva domande sospette. Yoda, qualcuno?

That doesn't sound natural at all

Yoda di fare un punto importante - invertì l'ordine ti costringe a think.

diventa ancora più innaturale quando le tue affermazioni sono più complesse:

Assert.That(Forest, Has.MoreThan(15, Trees)); 

Come ti invertire quello? Più di 15 alberi sono stati trovati dalla foresta?

Questa affermazione (scioltezza come fattore trainante per la modifica) sia in qualche modo riflette nel cambiamento che NUnit ha attraversato - in origine (Assert.AreEqual) ha usato previsto prima attuale (vecchio stile). Estensioni fluide (o per utilizzare la terminologia NUnit, basata sul vincolo - Assert.That) hanno invertito questo ordine.

0

Beh, hanno dovuto scegliere una convenzione. Se vuoi invertire, prova i giocatori di Hamcrest. Servono per aumentare la leggibilità. Ecco un esempio di base:

import org.junit.Test; 
import static org.junit.Assert.assertThat; 
import static org.hamcrest.core.Is.is; 

public HamcrestTest{ 
    @Test 
    public void matcherShouldWork(){ 
     assertThat( Math.pow(2, 3), is(8) ); 
    } 
} 
+0

Non sono sicuro di come sia più leggibile che un semplice '' assert 8 == Math.pow (2, 3) '' come faresti in py.test! – Meitham

+0

1) non è possibile confondere l'ordine di ciò che è il valore atteso rispetto al valore effettivo 2) è possibile estendere gli abbinamenti in modo da poter aggiungere più "verbi" ad Hamcrest come si potrebbe aggiungere per renderlo 'assertThat (Math.pow (2, 3), è (relativamentePrimeTo (49))); ' – ArtB

0

Sicuramente ha senso logico per mettere il valore atteso prima, in quanto è il primo valore di nota.

Pensateci nel contesto dei test manuali. Un test manuale avrà il valore previsto scritto, con il valore effettivo registrato successivamente.

+0

" senso logico "? La frase "Mi aspetto la risposta alla domanda" qual è il significato della vita? " uguale a 42 "è organizzato logicamente, con senso logico. – Draghon

+0

Sì, la frase è organizzata correttamente. Sto parlando più del concetto di aspettativa. Un'aspettativa viene logicamente prima di tutto. Guarda la definizione di aspettativa di Google: "una forte convinzione che qualcosa accadrà o sarà il caso." * succederà *. cioè accadrà * dopo * l'attesa è impostata. – amarsha4

Problemi correlati