È un odore di prova o è anche peggio?

7

Recentemente ho esaminato alcuni testscripts che assomigliano un po 'a

...
try {
  receiveSomething();
  // something was received even though it shouldn't
  failTest();
} catch (TimeoutException e) {
  // nothing should be received
  succedTest();
}

Il problema che ho con questi tipi di test è

  1. Non sono deterministici. Non sai se nulla è stato inviato di proposito o se tutto è andato in crash.
  2. È molto difficile testare simultaneamente qualcos'altro, che potrebbe effettivamente, in questo caso, inviare qualcosa.

I miei pensieri sono da un lato, come possono essere progettati meglio questi tipi di test, e in secondo luogo può essere un'indicazione di un odore del design più grande del software che viene testato?

Modifica

Per ottenere la clairifica, questi script di test sono utilizzati per il black box-testing di software complesso basato su eventi, non per test di unità, e la mia sensazione è che l'evento 'doing nothing' sia molto ambiguo. :)

    
posta Theodor 14.02.2013 - 11:07
fonte

4 risposte

10

Da quello che hai scritto, immagino che la tua situazione sia più simile a questa

startAsynchronousComplexOperation();
try {
  receiveSomething(); // listen for events from that async operation above

  // something was received even though it shouldn't
  failTest();
} catch (TimeoutException e) {
  // nothing should be received
  succedTest();
}

e l'oggetto sotto test non è "receiveSomething", ma l'operazione asincrona. Pertanto, l'esito di tale test dipende dalla velocità della macchina di prova, se molti altri processi vengono eseguiti sulla macchina di prova, ecc. E questo non è deterministico.

IMHO, questo è davvero un problema di progettazione, e non solo un "odore di prova". Se la tua "operazione complessa" si blocca, o semplicemente "impiega troppo tempo", non solo il tuo test darà un "falso negativo". Pensa a come affrontare questa situazione nella produzione. Non c'è alcun obbligo di determinare con certezza che la tua "operazione complessa" sia ancora in vita e non si sia bloccata? Quindi potresti pensare di aggiungere qualche tipo di meccanismo "watchdog" o "keep-alive-packet-sending" al tuo programma per avere il controllo su questo. E una volta che hai a disposizione una simile meccanica, puoi usarla nei tuoi test in questo modo:

startAsynchronousComplexOperation();
while(isComplexOperationStillAlive())
{
    try {
       receiveSomething(); // listen for events from that async operation above
       // something was received even though it shouldn't
       failTest();
   } catch (TimeoutException e) {
   }
}
if(didComplexOperationCrash())
    failTest();
else
    succedTest();
    
risposta data 14.02.2013 - 14:18
fonte
12

They are not deterministic. You don't know if nothing was sent on purpose or if everything has crashed.

Non importa, nel contesto di questo test. Tutto ciò che importa è che, in base alle condizioni preliminari definite, non viene ricevuto nulla. Altri test possono simulare altre precondizioni e verificare che i loro risultati siano come attesi.

Its very hard to simultaneously test something else, which might actually, in this case, send something.

Bene! Non dovresti provare a collegare altri test a questo test. Questo test sta facendo esattamente quello che dovrebbe fare. Un insieme di precondizioni = > Un risultato.

Questa è proprio la definizione di determinismo.

    
risposta data 14.02.2013 - 12:52
fonte
1

Molto difficile rispondere a questo senza un contesto.

Il caso di test doveva essere per il punto di funzione ("Il sistema non risponderà a nessuna richiesta dopo il comando" Quiesce "emesso") allora sì, questo sarebbe un caso di prova perfettamente valido.

Anche se avrei specificato che una risposta valida è stata ricevuta immediatamente prima della richiesta di arresto, ma questi tipi di test "operativi" sono molto difficili da automatizzare in quanto è improbabile che tu possa emettere tali comandi di sistema da un'API.

    
risposta data 14.02.2013 - 11:24
fonte
1

They are not deterministic. You don't know if nothing was sent on purpose or if everything has crashed.

Un algoritmo deterministico come definito in Wikipedia è come tale:

is an algorithm which, given a particular input, will always produce the same output

Ma gli algoritmi per costruire il test non hanno molta importanza, praticamente perché si suppone che testino lo stato corretto dopo aver invocato un comportamento specifico. In altre parole, l'unica cosa che deve essere deterministica è il modulo di codice che stai testando. Il test stesso sta effettivamente definendo cosa dovrebbe essere la determinazione .

Its very hard to simultaneously test something else, which might actually, in this case, send something.

Come altri hanno sottolineato, questa è una BUONA COSA. Se ho un test per il modulo A, che ha dipendenze sui moduli B e C, allora se TestModuleA fallisce, come faccio a sapere che è effettivamente un problema nel modulo A?

Si suppone che il test verifichi semplicemente che il modulo A fornisce lo stato corretto per il richiamo di un'operazione di A. Dovresti avere test separati per le dipendenze per verificare anche il loro comportamento corretto.

    
risposta data 14.02.2013 - 13:02
fonte

Leggi altre domande sui tag