Test: deterministico o non deterministico?

16

È meglio avere un

  • Test suite deterministico, che risulta negli stessi test che hanno avuto successo
  • Suite di test non deterministica, che potenzialmente potrebbe coprire più casi

Esempio: Scrivi una suite di test per testare la funzionalità del controller in un'applicazione MVC. Il controller richiede i dati dell'applicazione da un database come input durante il test. Ci sono due opzioni per fare questo:

  • Hai hardcode quale riga (s) dal database di test è selezionata come input (ad esempio la 10 ° e la 412 ° riga)
  • Si utilizza un generatore di numeri casuali per prelevare in modo pseudore i dati dal database (due righe selezionate da un generatore di numeri casuali)

Il primo è deterministico: ogni esecuzione del test per la stessa revisione del codice dovrebbe produrre lo stesso risultato. Il secondo è non deterministico: ogni run della suite di test ha la possibilità di produrre un risultato diverso. I dati raccolti casualmente potrebbero tuttavia essere una rappresentazione migliore dei casi limite dei dati. Potrebbe simulare un utente che alimenta meglio i nostri controller con dati imprevedibili?

Quali sono i motivi per scegliere l'uno rispetto all'altro?

    
posta DCKing 17.12.2013 - 14:52
fonte

4 risposte

27

Quando ogni run della suite di test ti dà la possibilità di ottenere un risultato diverso, il test è quasi del tutto inutile - quando la suite ti mostra un bug, hai un'alta probabilità che non puoi riprodurlo e quando provi per correggere il bug, non puoi provare che la tua correzione funzioni.

Quindi, quando pensi di aver bisogno di usare un qualche generatore di numeri casuali per generare i tuoi dati di test, assicurati di inizializzare sempre quel generatore di numeri casuali con lo stesso seme, o di mantenere i tuoi dati test casuali in un file prima di nutrirli nel test, in modo da poter ripetere nuovamente il test con gli stessi esatti dati dell'esecuzione precedente. In questo modo, puoi trasformare qualsiasi test non deterministico in uno deterministico.

EDIT: Usare un generatore di numeri casuali per selezionare alcuni dati di test è IMHO il più delle volte un segnale per essere troppo pigro nel scegliere buoni dati di test. Invece di lanciare 100.000 valori di test scelti a caso e sperare che questo sia sufficiente per scoprire tutti i bug gravi per caso, meglio usare il cervello, scegliere da 10 a 20 casi "interessanti" e usarli per la suite di test. Ciò non si tradurrà solo in una migliore qualità dei test, ma anche in prestazioni molto più elevate della suite.

    
risposta data 17.12.2013 - 15:13
fonte
4

Sia deterministico che non-deterministico hanno un posto

Li dividerei come segue:

Test unitari.

Questi dovrebbero avere test deterministici e ripetibili con gli stessi identici dati ogni volta. I test unitari accompagnano sezioni di codice specifiche e isolate e dovrebbero testarle in modo deterministico.

Test di stress funzionale e di input

Questi possono usare l'approccio non deterministico con i seguenti avvertimenti:

  • questo fatto è chiaramente delineato e definito
  • i valori casuali selezionati vengono registrati e possono essere riprovati manualmente
risposta data 12.12.2016 - 15:20
fonte
2

Entrambi.

I test deterministici e non deterministici hanno diversi casi d'uso e valori diversi per la tua suite. Generalmente non deterministico non può fornire la stessa precisione del test deterministico, che è lentamente cresciuto in "test non deterministici non fornisce alcun valore". Questo è falso. Possono essere meno precisi, ma possono anche essere molto più ampi, che ha i suoi vantaggi.

Facciamo un esempio: scrivi una funzione che ordina un elenco di numeri interi. Quali sarebbero alcuni dei test unitari deterministici che troveresti utili?

  • Una lista vuota
  • Una lista con un solo elemento
  • Una lista con tutti gli stessi elementi
  • Un elenco con più elementi unici
  • Una lista con più elementi, alcuni dei quali sono duplicati
  • Un elenco con NaN , INT_MIN e INT_MAX
  • Un elenco già parzialmente ordinato
  • Una lista con 10.000.000 di elementi

E questa è solo una funzione di smistamento! Certo, potresti obiettare che alcuni di questi non sono necessari o che alcuni di questi possono essere esclusi con un ragionamento informale. Ma siamo ingegneri e abbiamo visto il ragionamento informale saltare in faccia. Sappiamo di non essere abbastanza intelligenti da comprendere appieno i sistemi che abbiamo costruito o mantenere completamente la complessità nelle nostre teste. Ecco perché scriviamo test in primo luogo. L'aggiunta di test non deterministici dice solo che potremmo non essere necessariamente abbastanza intelligenti da conoscere a priori tutti i buoni test. Lanciare dati semi-casuali nella tua funzione, è molto più probabile che trovi un caso limite che ti sei perso.

Naturalmente, questo non esclude neanche i test deterministici. Il test non deterministico aiuta a trovare i bug in vaste aree del programma. Una volta individuati i bug, tuttavia, è necessario un modo riproducibile per dimostrare che è stato corretto. Quindi:

  • Utilizza test non deterministici per trova bug nel codice.
  • Utilizza i test deterministici per verifica le correzioni nel codice.

Si noti che questo significa che molti validi consigli sui test unitari non si applicano necessariamente ai test non deterministici. Ad esempio, devono essere veloci. I test di proprietà di basso livello dovrebbero essere rapidi, ma un test non deterministico come "simulare un utente che fa clic casualmente sui pulsanti sul proprio sito Web e assicurarsi di non ricevere mai un errore di 500" dovrebbe favorire la comprensibilità per eccesso di velocità. Basta fare un test del genere eseguito indipendentemente dal processo di costruzione in modo che non rallenti lo sviluppo. Ad esempio, eseguilo sulla propria casella di gestione temporanea privata.

    
risposta data 17.12.2016 - 18:20
fonte
-1

Non vuoi davvero deterministico o non deterministico.

Ciò che potresti desiderare è "sempre uguale" vs. "non sempre uguale".

Ad esempio, potresti avere un numero di build che aumenta con ogni build e quando vuoi alcuni numeri casuali, inizializzi un generatore di numeri casuali con il numero di build come seme. Quindi, ogni build, fai i tuoi test con valori diversi, dandoti più possibilità di trovare bug.

Ma una volta trovato un errore, tutto ciò che devi fare è eseguire il test con lo stesso numero di build ed è riproducibile.

    
risposta data 12.12.2016 - 22:28
fonte

Leggi altre domande sui tag