Se i test unitari riguardano solo il software 'funzionale'

9

Stiamo utilizzando StructureMap in un nuovo progetto di sviluppo software. Uno dei membri del team ha implementato un test unitario che sostanzialmente verifica la configurazione del contenitore StructureMap . Lo fa facendo quanto segue;

  • Conta il numero di istanze di assiemi configurati per le classi nel nostro spazio dei nomi dell'applicazione.
  • Definisce le istanze previste a livello di classe
  • Asserisce che le istanze previste corrispondono alle istanze totali trovate.
  • Asserisce che le istanze previste corrispondono a quelle definite nel test

Un esempio di questo è;

var repositories = container.GetAllInstances<IEnvironmentRepository>();
Assert.AreEqual(1, repositories .Count());
foundInstances = foundInstances + repositories .Count();

Abbiamo anche 'unit test' per la seguente classe;

public MyClass(IEnvironmentRepository environmentRepository)
        {

        }

In questi test, prendiamo in giro IEnvironmentRepository, quindi non lo inietteremo dal contenitore come accadrebbe nel sistema live.

Un collega ha ignorato il test dell'unità sulla configurazione della mappa di configurazione con un commento lungo la riga "Il test dell'unità verifica solo la propria configurazione". Questo era ovviamente lo scopo del test e, a mio parere, è perfettamente valido. Ho chiesto al tizio che ha ignorato il test di rimuovere la configurazione della structuremap per IEnvironmentRepository (con il test ancora ignorato) ed eseguire l'intera suite di test unitaria, sono passati tutti. Abbiamo quindi eseguito l'applicazione ed è caduta perché la configurazione del contenitore non era più valida. A mio parere, questo ha dimostrato il valore del test, il mio collega è ancora in disaccordo. Ha semplicemente affermato che non dovremmo testare la configurazione, ma ritengo che questo sia ben all'interno del mandato di un test unitario.

Quindi una serie di domande;

  • È un test di unità valido? Stiamo testando la configurazione del nostro contenitore, non che funzioni la structuremap (ma posso vedere la sovrapposizione)
  • In caso contrario, come è possibile convalidare la configurazione senza verificarla. Come puoi impedire a qualcuno di eliminare accidentalmente una riga di codice richiesta e verificarla?
  • Il test unitario MyClass risolve l'istanza di IEnvironmentRepository dal contenitore e lo inoltra?
posta ChrisBint 21.08.2017 - 14:23
fonte

6 risposte

13

Questo è un test automatico perfettamente valido. Li chiamo "test di architettura" mentre verificano la solidità dei componenti scheletrici del tuo codice base.

Il contenitore IoC è in grado di risolvere e comporre tutti gli alberi degli oggetti nell'applicazione? Può la mappa di mappatura automatica tra tutti i suoi oggetti registrati senza fallire? Lo strato centrale in un'architettura di cipolla non fa riferimento a qualcosa di esterno?

Questi test possono farti risparmiare un sacco di tempo quando un errore di configurazione si insinua, indicando il colpevole esatto. I buoni framework ti daranno messaggi di errore molto precisi su ciò che è sbagliato e li ricevi non appena esegui i test (idealmente, continuamente) invece di seppellire in profondità una traccia dello stack di runtime se sei fortunato.

Che si tratti di test unitari ... probabilmente no, ma funzionano ancora nella memoria per la maggior parte e funzionano piuttosto velocemente. Poi di nuovo, non lo so, non è che ci fosse una definizione universalmente accettata di unit test.

    
risposta data 21.08.2017 - 17:55
fonte
6

Il problema con un test come questo che verifica i componenti interni del programma, piuttosto che un suo requisito. È che il test può fallire anche se il programma funziona come richiesto.

Nel tuo caso, ogni volta che cambi la configurazione del contenitore, forse hai una nuova dipendenza che ha bisogno di iniettare, interrompi il test.

Inoltre, se si aggiunge il requisito di dipendenza extra, ma si dimentica di aggiungerlo al contenitore e modificare il test del contenitore. tutto passerà, ma il tuo programma si bloccherà.

Un test automatico migliore sarebbe quello di avviare il programma e vedere se si blocca.

Dovresti rilevare questi tipi di errori durante l'integrazione o il test dell'interfaccia utente anche se cadono attraverso i test delle unità.

Detto questo, la crescente complessità della configurazione dei container è un rompicapo. Forse alcuni test "cattivi" ne valgono la pena.

    
risposta data 21.08.2017 - 23:07
fonte
1

Codice test test unitario. Qualunque cosa al di fuori di questo è "altro" test automatico: chiamalo come vuoi. Sembra che tu stia testando la configurazione qui. Se la configurazione può cambiare a seconda dell'ambiente, non appartiene a un test di unità. Considera l'aggiunta di un attributo test per indicare che il test è di un tipo diverso rispetto agli altri test.

    
risposta data 21.08.2017 - 14:45
fonte
0

La responsabilità del contenitore per le dipendenze è per incollare moduli diversi in un'unica applicazione .

Se scrivi test automatici per la tua applicazione - dovresti avere pochi "test di integrazione (o accettazione) che eseguono test" da capo a capo ", che testeranno l'intera pipeline della tua applicazione, che tutti i moduli coinvolti in caso di test particolare sono incollati correttamente .

Quindi questi test di integrazione falliranno se il contenitore di iniezione delle dipendenze non è stato configurato correttamente. Il che rende inutili test unitari per il contenitore, perché il test di integrazione dovrebbe mostrare possibili errori nella configurazione del contenitore.

Non è necessario coprire tutti i possibili casi di test nei test di integrazione, solo un caso di test per funzionalità che copre interamente dall'interfaccia utente al database.

Se i casi di test di integrazione non coprono l'istanziazione di alcune dipendenze particolari, è sufficiente aggiungerne uno.

Con i test di integrazione puoi cambiare liberamente i contenitori senza riscrivere i test unitari per la loro configurazione.

    
risposta data 23.08.2017 - 06:45
fonte
0

IMO, le risposte sono:

  1. È un test di unità valido - Stiamo testando la configurazione del nostro contenitore, non che la structuremap funzioni (ma posso vedere la sovrapposizione)

    • È un test unitario valido per structuremap , non per il tuo progetto, perché un test unitario verifica un codice specifico, prendendo in giro tutte le dipendenze, se necessario, per testare la logica implementata. La logica di configurazione è implementata all'interno di structuremap, quindi questa libreria deve essere ben testata e deve contenere test unitari come quello che hai citato, e altro: dovrebbe contenere centinaia di test come questo, dinamicamente prendendo in giro diverse configurazioni in fase di esecuzione e test per vedere se il contenitore si comporta come dovrebbe.
  2. In caso contrario, come è possibile convalidare la configurazione senza testarla. Come si può impedire a qualcuno di eliminare accidentalmente una riga di codice richiesta e verificarla?

    • È possibile testare manualmente la configurazione nell'ambiente necessario, ed è anche possibile creare un'automazione per questo (test automatico), che verifica la configurazione specifica di cui si ha bisogno (non c'è bisogno di prendere in giro roba in fase di runtime).
  3. Il test dell'unità MyClass deve risolvere l'istanza di IEnvironmentRepository dal contenitore e passare questo?

    • No, questo è un test unitario perfetto, perché prendi in giro la dipendenza e collaudi la logica di MyClass in modo isolato.
risposta data 23.08.2017 - 16:39
fonte
-1

UnitTest verifica comportamento desiderato di un'unità in separazione .

Questo significa che qualsiasi tipo di configurazione è non nell'ambito di UnitTests .

Tuttavia dovresti avere test automatici per le tue configurazioni, ma questi non sono UnitTests ...

    
risposta data 21.08.2017 - 16:23
fonte

Leggi altre domande sui tag