Domanda

Ho un collega che scrive unit test per gli oggetti che riempiono i loro campi con dati casuali.La sua ragione è che dà una più ampia gamma di sperimentazione, dal momento che metterà alla prova un sacco di diversi valori, considerando che un normale test utilizza solo un singolo valore statico.

Ho dato una serie di ragioni diverse per contro, le principali delle quali sono:

  • valori casuali significa che il test non è ripetibile (il che significa anche che se il test in modo casuale può fallire, può farlo sul server di generazione e di interrompere la compilazione)
  • se si tratta di un valore casuale e il test ha esito negativo, abbiamo bisogno di un fix oggetto e b) forza a noi stessi di test per il valore di ogni tempo, in modo che sappiamo che funziona, ma dal momento che è casuale, non sappiamo cosa il valore è stato

Un altro collega ha aggiunto:

  • Se io sono la prova di un'eccezione, di valori casuali non assicura che il test finisce in stato previsto
  • casuale di dati utilizzata per il risciacquo di un sistema e di test di carico, non per i test unitari

Qualcuno può aggiungere ulteriori motivi che posso dargli per fargli smettere di fare questo?

(O, in alternativa, è questo un accettabile metodo di scrittura di test unitari, e io e l'altra mia collega che è sbagliato?)

È stato utile?

Soluzione

C'è un compromesso.Il vostro collega è in realtà su qualcosa, ma credo che stia facendo male.Io non sono sicuro che tutto casuale test è molto utile, ma certamente non è valido.

Un programma (o unità) specificazione è un'ipotesi che non esiste qualche programma che lo incontra.Il programma in sé è poi la prova di questa ipotesi.Cosa unit test dovrebbe essere è un tentativo di fornire contro le prove per confutare che il programma funziona secondo la specifica.

Ora, è possibile scrivere i test unitari a mano, ma è davvero un lavoro meccanico.Può essere automatizzato.Tutto quello che dovete fare è scrivere la spec, e una macchina in grado di generare un sacco e un sacco di test unitari, che tenta di rompere il vostro codice.

Non so in che linguaggio stai usando, ma vedere qui:

Java http://functionaljava.org/

Scala (o Java) http://github.com/rickynils/scalacheck

Haskell http://www.cs.chalmers.se/~rjmh/QuickCheck/

.NET:http://blogs.msdn.com/dsyme/archive/2008/08/09/fscheck-0-2.aspx

Questi strumenti di prendere il vostro ben-formata spec come input e genera automaticamente come unità molti test come si vuole, con i dati generati automaticamente.Usano la "riduzione" strategie (che si può modificare), per trovare il più semplice possibile caso di prova per rompere il codice e per assicurarsi che copre i casi limite ben.

Buon test!

Altri suggerimenti

Questo tipo di test è chiamato Scimmia test.Quando è fatto bene, si può fumare fuori bug molto angoli bui.

Per affrontare le vostre preoccupazioni circa la riproducibilità:il modo giusto per avvicinarsi a questo, è quello di registrare il test non riuscito voci di generare un'unità di prova, quali sonde per il tutta la famiglia di bug specifici;e da includere nel test di unit ' l'uno specifico input (da dati casuali) che ha causato l'errore iniziale.

C'è a metà strada qui che ha un certo uso, che è il seme tuo PRNG con una costante.Che consente di generare 'casuale' di dati che è ripetibile.

Personalmente penso che ci siano luoghi in cui (costante) di dati casuali, è utile in fase di test - dopo pensi di aver fatto tutto con cura non ci sono angoli, utilizzando stimoli da un PRNG può a volte trovare altre cose.

Nel libro Bel Codice, c'è un capitolo intitolato "Belle Prove", dove si passa attraverso una strategia di sperimentazione per la Ricerca Binaria algoritmo.Un paragrafo è chiamato "Atti Casuali di Test", in cui egli crea casuale di matrici per testare l'algoritmo.È possibile leggere alcuni di questi online su Google Libri, pagina 95, ma è un grande libro che vale la pena avere.

Quindi, fondamentalmente, questo dimostra che la generazione casuale dei dati per il test è una valida opzione.

Un vantaggio per qualcuno guardando il test è che arbitraria di dati è chiaramente importante.Ho visto molti test che ha coinvolto decine e decine di pezzi di dati e può essere difficile dire che cosa deve essere così e cosa accade solo per essere in quel modo.E. g.Se un indirizzo di validazione del metodo è testato con uno specifico codice di avviamento postale e di tutti gli altri dati è casuale, allora si può essere abbastanza sicuro, il codice di avviamento postale è l'unica parte importante.

Se si sta facendo TDD, quindi direi che di dati casuali, è un ottimo approccio.Se il test è stato scritto con costanti, allora si è in grado di garantire il tuo codice funziona per il valore specifico.Se il test è casuale in mancanza del server di generazione c'è probabilmente un problema con la modalità di prova è stato scritto.

Dati casuali sarà possibile garantire alcun futuro refactoring non si basa su un costante magica.Dopo tutto, se i test sono la documentazione, quindi non la presenza di costanti implica non solo la necessità di lavorare per le costanti?

Sto esagerando però preferisco di iniettare i dati casuali nel mio test come un segno che "il valore di questa variabile non dovrebbe influenzare l'esito di questo test".

Devo dire però che se si utilizza una variabile casuale quindi la forcella di test basati su tale variabile, che poi è un odore.

  • se si tratta di un valore casuale e il test ha esito negativo, abbiamo bisogno di un fix oggetto e b) forza a noi stessi di test per il valore di ogni tempo, in modo che sappiamo che funziona, ma dal momento che è casuale, non sappiamo cosa il valore è stato

Se il test caso non registrare con precisione che cosa si prova, forse avete bisogno di ricodificare i test del caso.Ho sempre voglia di avere i log che ho come riferimento per i casi di test in modo che io so esattamente che cosa ha causato un errore se l'utilizzo di statico o di dati casuali.

Il vostro collega sta facendo fuzz-test, anche se non sa su di esso.Essi sono particolarmente utili in sistemi server.

Io sono a favore dei controlli a campione, e li scrivo.Tuttavia, se sono adeguati in un particolare ambiente di compilazione e suite di test dovrebbe essere incluso in un più sfumata domanda.

Eseguire localmente (ad esempio, durante la notte sul tuo dev casella) test randomizzati hanno trovato il bug sia ovvio e oscuro.Gli oscuri sono quelli arcano basta che penso casuale test è stato davvero l'unico obiettivo realistico per lavare fuori.Come prova, ho preso una cosa difficile da trovare bug scoperto tramite la prova randomizzata e aveva una mezza dozzina di rompere gli sviluppatori di rivedere la funzione (una decina di righe di codice) in cui esso si è verificato.Nessuno era in grado di rilevare.

Molte delle tue argomentazioni contro di dati da studi randomizzati sono sapori di "il test non riproducibile".Tuttavia, un ben scritto, randomizzato test di catturare il seme utilizzato per avviare gli studi di semi e di uscita in caso di fallimento.Oltre a consentire di ripetere il test a mano, questo permette di banalmente creazione di un nuovo test che prova il problema specifico da inserire a mano il seme per quel test.Naturalmente, è probabilmente più bello di mano il codice di una esplicita test che copre quel caso, ma la pigrizia ha la sua virtù, e questo permette anche di essenzialmente auto-generare nuovi casi di test in caso di malfunzionamento del seme.

Il punto è che fare, non posso dibattito, però, è che rompe i sistemi di creazione.Più costruire e continuous integration test di aspettare il test per fare la stessa cosa, ogni volta.Così un test che casualmente si riesce a creare il caos, in modo casuale e di errore di puntamento, le dita, i cambiamenti che erano innocui.

Una soluzione, quindi, è ancora eseguire il test randomizzati come parte della creazione e CI prove, ma esegue con un fisso di semi, per un determinato numero di iterazioni.Quindi il test si fa sempre la stessa cosa, ma ancora esplora un sacco di spazio input (se viene eseguito per più iterazioni).

Localmente, ad esempio, quando si cambia la questione di classe, si sono liberi di usarlo per ulteriori iterazioni o con altri semi.Se la prova randomizzata mai diventa sempre più popolare, si potrebbe anche immaginare una specifica suite di test che sono noti per essere casuale, che può essere eseguito con semi diversi (e quindi con l'aumento della copertura nel corso del tempo), e dove i fallimenti non significano la stessa cosa, come deterministica CI sistemi (ad es., viene eseguito non sono associati 1:1 con le modifiche del codice e quindi non punto il dito verso un cambiamento in particolare quando le cose non riescono).

C'è molto da dire per il test randomizzati, soprattutto ben scritto, così da non essere troppo veloce per chiudere i loro!

Si può generare un po ' di dati casuali di una volta (intendo esattamente una volta, non una volta all'esecuzione di test), per poi utilizzarlo in tutti i test successivi?

Posso sicuramente vedere il valore nella creazione di dati casuali per verificare quei casi che non hai pensato, ma hai ragione, avendo unità di test che possono casualmente passare o non è una brutta cosa.

Si dovrebbe chiedere a voi stessi ciò che è l'obiettivo della vostra prova.
Unit test sono sulla verifica di logica, il flusso del codice e oggetto di interazioni.Usando valori casuali cerca di raggiungere un obiettivo diverso, riducendo, così, il test di messa a fuoco e la semplicità.È accettabile per motivi di leggibilità (generazione UUID, id, chiavi,etc.).
In particolare per i test di unità, non riesco a ricordare ancora una volta che questo metodo è stato di successo i problemi di ricerca.Ma ho visto molte determinismo problemi (nei test), cercando di essere intelligente, con valori casuali e soprattutto con date casuale.
Fuzz testing è un valido approccio per test di integrazione e end-to-end di test.

Se si utilizza casuale di ingresso per il test è necessario per accedere agli ingressi, in modo da potete vedere che cosa sono i valori.In questo modo se c'è un qualche caso limite si incontra, si può scrivi la prova a riprodurlo.Ho sentito le stesse ragioni da parte di persone che non usano input casuale, ma una volta che si hanno spaccato i valori effettivi utilizzato per una particolare esecuzione di test quindi non è tanto di un problema.

La nozione di "arbitrario" di dati è anche molto utile come un modo per indicare qualcosa che è non importante.Ci sono alcune prove di accettazione che mi vengono in mente dove c'è un sacco di rumore di dati che è di alcuna rilevanza per il test a portata di mano.

A seconda dell'oggetto/app, dati casuali sarebbe un posto nei test di carico.Penso che più importante sarebbe quello di utilizzare i dati in modo esplicito le prove le condizioni al contorno dei dati.

Abbiamo appena imbattuto in questo oggi.Volevo pseudo-casuale (così sarebbe come dati audio compressi in termini di dimensioni).Io TODO piacerebbe che anche io volevo deterministico.rand() è stato diverso su OSX che su Linux.E se non mi ri-seminato, potrebbe cambiare in qualsiasi momento.Così abbiamo cambiato per essere deterministico, ma ancora pseudo-casuali:la prova è ripetibile, per quanto utilizza fisso di dati (ma più comodamente scritto).

Questo è stato NON prova da qualche casuale forza bruta attraverso percorsi di codice.Ecco la differenza:ancora deterministico, ancora ripetibile, ancora utilizzando i dati che sembra reale di input per eseguire una serie di interessanti i controlli sui casi limite, in una logica complessa.Ancora unit test.

Fa che ancora qualificarsi è casuale?Parliamo di più di birra.:-)

Posso prevedere tre soluzioni per il test dei dati del problema:

  • Prova con dati fissi
  • Prova con dati casuali
  • Generazione casuale di dati una volta, quindi utilizzarlo come dati fissi

Mi sento di raccomandare facendo tutto quanto sopra.Che è, scrivere ripetibili gli unit test sia con alcuni casi limite, ha lavorato con il cervello, e alcuni dati randomizzati che si genera solo una volta.Quindi scrivere una serie di randomizzati test che si esegue così.

Randomizzati prove non dovrebbe mai essere previsto per la cattura di una cosa che il test ripetibili perdere.Si dovrebbe mirare a coprire il tutto con il test ripetibili, e considerare randomizzati prove di un bonus.Se trovano qualcosa, dovrebbe essere qualcosa che si poteva ragionevolmente prevedibile;un vero e proprio stravagante.

Come è possibile che il tuo ragazzo eseguire nuovamente il test quando non è riuscito a vedere se ha risolto?I. e.perde la ripetibilità dei test.

Mentre penso che probabilmente c'è un qualche valore in lanciando un carico di dati casuali in test, come già detto in altre risposte non cade più, sotto il titolo di test di carico di qualsiasi altra cosa.È praticamente un "test-da-la speranza" pratica.Penso che, in realtà, il tuo ragazzo è semplicemente non thinkng su ciò che egli sta cercando di test, e per la mancanza di pensiero sperando casualità finalmente trappola di qualche misterioso errore.

Così l'argomento vorrei usare con lui è che lui è di essere pigri.O, per dirla in altro modo, se non prende il tempo di capire cosa sta cercando di test probabilmente dimostra che egli non riesce a capire il codice che sta scrivendo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top