Unità che verifica più condizioni in un'istruzione IF

22

Ho una porzione di codice simile a questa:

function bool PassesBusinessRules()
{
    bool meetsBusinessRules = false;

    if (PassesBusinessRule1 
         && PassesBusinessRule2
         && PassesBusinessRule3)
    {
         meetsBusinessRules= true;
    }

    return meetsBusinessRules;
}

Credo che ci dovrebbero essere quattro test unitari per questa particolare funzione. Tre per testare ciascuna delle condizioni nella dichiarazione if e assicurarsi che restituisca false. E un altro test che si assicura che la funzione restituisca true.

Domanda: dovrebbero invece esserci dieci test unitari? Nove che controlla ciascuno dei possibili percorsi di errore. IE:

  • False False False
  • Falso Falso Vero
  • Falso Vero Falso

E così via per ogni combinazione possibile.

Penso che sia eccessivo, ma alcuni degli altri membri della mia squadra no. Il modo in cui lo guardo è se BusinessRule1 fallisce, allora dovrebbe sempre restituire false, non importa se è stato selezionato per primo o per ultimo.

    
posta bwalk2895 06.07.2012 - 21:17
fonte

8 risposte

26

Formalmente, questi tipi di copertura hanno nomi.

In primo luogo, c'è la copertura del predicato : vuoi avere un caso di test che renda vera la dichiarazione if, e quella che la rende falsa. Avere questa copertura soddisfatta è probabilmente un requisito di base per una buona suite di test.

Poi ci Copertura delle condizioni : qui si vuole verificare che ogni sotto-condizione in if abbia il valore true e false. Questo ovviamente crea più test, ma di solito cattura più bug, quindi è spesso una buona idea includere nella tua suite di test se hai tempo.

I criteri di copertura più avanzati sono solitamente definiti Copertura delle condizioni combinatorie : qui l'obiettivo è di avere un caso di test che attraversa tutte le possibili combinazioni di valori booleani nel test .

È meglio del semplice predicato o copertura delle condizioni? In termini di copertura, ovviamente. Ma non è gratuito. Ha un costo molto elevato nella manutenzione del test. Per questo motivo, la maggior parte le persone non si preoccupano della copertura combinatoria completa. Di solito testare tutti i rami (o tutte le condizioni), sarà abbastanza buono per catturare insetti. Aggiungere i test aggiuntivi per i test combinatori di solito non cattura più bug, ma richiede un grande sforzo per creare e mantenere. Lo sforzo extra di solito rende questo non vale il payoff molto piccolo, quindi non lo consiglierei.

Parte di questa decisione dovrebbe essere basata su quanto pensi che il codice sia rischioso. Se ha molto spazio per fallire, vale la pena provare. Se è un po 'stabile e non cambierà molto, dovresti considerare di concentrare le tue attività di testing altrove.

    
risposta data 06.07.2012 - 21:26
fonte
8

In definitiva, dipende da te (team r), dal codice e dall'ambiente di progetto specifico. Non esiste una regola universale. Tu (r team) dovresti scrivere tutti i test di cui hai bisogno per sentirti a tuo agio che il codice sia effettivamente corretto . Quindi se i tuoi compagni di squadra non sono convinti da 4 test, forse hai bisogno di altro.

Il tempo di OTOH per scrivere i test unitari di solito è una risorsa scarsa. quindi cerca di trovare il modo migliore per trascorrere il tempo limitato che hai . Per esempio. se hai un altro metodo importante con copertura dello 0%, potrebbe essere meglio scrivere un paio di test unitari per coprire quello, piuttosto che aggiungere test aggiuntivi per questo metodo. Naturalmente, dipende anche da quanto fragile sia l'implementazione di ciascuno. Pianificare molte modifiche a questo particolare metodo nel prevedibile futuro può giustificare una copertura aggiuntiva del test unitario. Quindi potrebbe essere su un percorso critico all'interno del programma. Questi sono tutti fattori che solo tu (r team) puoi valutare.

Personalmente, di solito, sono contento dei 4 test che definisci, ovvero:

  • true false false
  • false true false
  • false false true
  • true true true

più uno:

  • true true false

per garantire che l'unico modo per ottenere un valore di ritorno di true sia soddisfare tutte e 3 le regole aziendali. Ma alla fine, se i tuoi compagni di squadra insistono sul fatto di avere percorsi combinatori coperti, potrebbe essere più economico aggiungere quei test extra che continuare l'argomento molto più a lungo: -)

    
risposta data 06.07.2012 - 21:35
fonte
3

Se vuoi essere sicuro, ti occorrono otto test unitari usando le condizioni rappresentate da una tabella di verità a tre variabili ( link ).

Non puoi mai essere sicuro che la logica aziendale stabilisca sempre che i controlli siano eseguiti in tale ordine e desideri che il test conosca il meno possibile l'effettiva implementazione.

    
risposta data 06.07.2012 - 21:28
fonte
2

Sì, dovrebbe esserci la combinazione completa in un mondo ideale.

Quando fai il test unitario, dovresti davvero cercare di ignorare come il metodo fa il suo lavoro. Basta fornire i 3 ingressi e verificare che l'uscita sia corretta.

    
risposta data 06.07.2012 - 21:27
fonte
1

Lo stato è malvagio. La seguente funzione non ha bisogno di un test unitario perché non ha effetti collaterali ed è ben chiaro cosa fa e cosa non fa. Perché provarlo? Non ti fidi del tuo cervello ??? Le funzioni statiche sono fantastiche!

static function bool Foo(bool a, bool b, bool c)
{
    return a && b && c;
}
    
risposta data 07.07.2012 - 06:45
fonte
1

So che questa domanda è abbastanza vecchia. Ma voglio dare un'altra prospettiva al problema.

Per prima cosa, i tuoi test unitari dovrebbero avere due scopi:

  1. Crea la documentazione per te e per i tuoi compagni di squadra, quindi dopo un determinato periodo di tempo puoi leggere il test dell'unità e assicurarti di capire what's the class' intention e how the class is doing its work
  2. Durante lo sviluppo, il test unitario assicura che il codice che stiamo scrivendo stia facendo il suo lavoro come previsto nella nostra mente.

Quindi, ricapitolando il problema, vogliamo testare un complex if statement , per l'esempio dato, ci sono 2 ^ 3 possibilità, che è una quantità importante di test che possiamo scrivere.

  • Puoi adattare a questo fatto e scrivere 8 test o utilizzare test parametrizzati
  • Puoi anche seguire le altre risposte e ricordare che i test dovrebbero essere chiari con l'intenzione, in questo modo non abbiamo intenzione di fare confusione con troppi dettagli che nel prossimo futuro potrebbero rendere più difficile capire what is doing the code

D'altra parte, se sei nella posizione in cui i tuoi test sono ancora più complessi dell'implementazione, è perché l'implementazione dovrebbe essere ridisegnata (più o meno a seconda del caso) piuttosto che il test stesso.

Per le affermazioni complesse if, ad esempio, puoi pensare su modello di responsabilità della catena , implementando ogni gestore in questo modo:

If some simple business rule apply, derive to the next handler

Quanto sarebbe semplice testare varie regole semplici, invece di una regola complessa?

Spero che aiuti,

    
risposta data 29.03.2018 - 16:07
fonte
0

Questo è uno di quei casi in cui Qualcosa come Quickcheck ( link ) sarà tuo amico. Invece di scrivere tutti i casi N a mano, il computer genera tutti (o almeno un gran numero) di possibili casi di test e conferma che tutti restituiscono un risultato ragionevole.

Programmiamo i computer per vivere qui, perché non programmare il computer per generare i casi di test per te?

    
risposta data 16.02.2014 - 05:20
fonte
0

Potresti rifattorizzare le condizioni in condizioni di guardia:

if (! PassesBusinessRule1) {
    return false;
}

if (! PassesBusinessRule2) {
    return false;
}

if (! PassesBusinessRule3) {
    return false;
}

Non penso che questo riduca il numero di casi, ma la mia esperienza è che è più facile suddividerli in questo modo.

(Nota che sono un grande fan "single point of exit", ma faccio un'eccezione per le condizioni di guardia, ma ci sono altri modi per strutturare il codice in modo da non avere ritorni separati.)

    
risposta data 16.02.2014 - 08:15
fonte

Leggi altre domande sui tag