Quali sono le migliori pratiche per testare programmi con comportamento stocastico?


14

Nel lavoro di ricerca e sviluppo, mi trovo spesso a scrivere programmi con un certo grado di casualità nel loro comportamento. Ad esempio, quando lavoro nella programmazione genetica, scrivo spesso programmi che generano ed eseguono codice sorgente casuale arbitrario.

Un problema con il test di tale codice è che i bug sono spesso intermittenti e possono essere molto difficili da riprodurre. Questo va oltre la semplice impostazione di un seme casuale sullo stesso valore e l'inizio dell'esecuzione.

Ad esempio, il codice potrebbe leggere un messaggio dal buffer dell'anello kernal e quindi eseguire salti condizionali sul contenuto del messaggio. Naturalmente, lo stato del buffer dell'anello sarà cambiato quando si tenta in seguito di riprodurre il problema.

Anche se questo comportamento è una caratteristica , può innescare altri codici in modi inaspettati, e quindi spesso rivela bug che i test unitari (o tester umani) non trovano.

Esistono buone pratiche stabilite per testare sistemi di questo tipo? In tal caso, alcuni riferimenti sarebbero molto utili. In caso contrario, qualsiasi altro suggerimento è il benvenuto!


5
Non puoi deridere anche il buffer dell'anello del kernel? E altri aspetti casuali del tuo codice?
Jonathan Merlet,

1
@JonathanMerlet Potenzialmente, ma il problema è che, quando distribuito, il codice avrà accesso al buffer dell'anello reale (in effetti, a un sistema operativo reale). Quindi, se provo solo su una versione simulata, allora sto solo rinviando la scoperta di questi bug fino a dopo.
John Doucette,

Mi sembra che il problema non sia correlato al comportamento casuale del programma (poiché questo può essere controllato dal seme casuale) ma a stati particolari di questo "buffer dell'anello del kernel". Quindi la tua domanda è in realtà "come testare un programma che dipende dallo stato esterno", giusto?
AakashM,

@AakashM, sì, è un modo migliore per esprimerlo. Per essere più specifici, un programma con uno stato esterno, che accede stocasticamente o altera lo stato esterno.
John Doucette,

Risposte:


7

È utile aggiungere hook, come suggerito, per ricreare stati esatti. Strumenta anche il sistema in modo che possa scaricare i suoi "semi" (nel tuo caso, incluso il seme PRNG e il buffer dell'anello del kernel, e qualsiasi altra fonte di input non deterministico).

Quindi esegui i tuoi test con input casuali veri e stile di regressione con casi interessanti scoperti in precedenza.

Nel caso particolare del tuo accesso al kernel, ti consiglio di prendere in giro in ogni caso. Usa la simulazione per forzare le classi di equivalenza che hanno meno probabilità di apparire in pratica, nello spirito di "vuoto" e "pieno" per i contenitori, oppure "0, 1, 2 ^ n, 2 ^ n + 1, molti" per cose numerabili. Quindi puoi testare con il finto e con la cosa reale, sapendo che hai gestito e testato i casi che hai pensato finora.

Fondamentalmente, ciò che sto suggerendo equivale a un mix di input deterministici e non deterministici, con quelli deterministici che sono un mix di quelli che riesci a pensare e quelli che ti hanno sorpreso.


6

Una cosa ragionevole da fare è seminare il generatore di numeri casuali con un valore costante per i test, in modo da ottenere un comportamento deterministico.


1
Questo; o deridere del tutto il prng
jk.

1
Grazie per il suggerimento! Lo faccio già per i test unitari, ma non posso testare manualmente tutti i possibili programmi.
John Doucette,

2
ma questo significa che non puoi verificare se la casualità funziona correttamente.
Louis Rhys,

2

Penso che i test statistici siano l'unico modo. Proprio come i numeri casuali vengono "testati" per casualità da test statistici, quindi devono essere algoritmi che utilizzano comportamenti casuali.

È sufficiente eseguire l'algoritmo più volte con input uguale o diverso e confrontarlo tra loro. Il problema con questo approccio è il massiccio aumento del tempo di calcolo necessario per completare il test.


Non necessariamente, poiché è possibile scegliere un piccolo set di input "spanning" ed eseguire più volte su di essi - il numero di input necessari per accertare l'affidabilità potrebbe essere inferiore. Questo set di "spanning" dovrebbe inserire tutti i rami del codice, inizializzare tutti gli oggetti, ecc.
Daniel Moskovich,

2

Non sono uno specialista in questo settore, ma esiste una letteratura scientifica relativa ai test del programma stocastico.

Se non è possibile creare facilmente classi di test, è possibile utilizzare un test statistico, come ha detto #Euphoric. Borning et al. confrontare un approccio tradizionale e uno statistico. Una generalizzazione dei test statistici suggeriti da @Euphoric potrebbe essere quella discussa da Whittaker. Ha suggerito di creare un modello stocastico del comportamento desiderato (stocastico, nel tuo caso) e quindi generare casi di test specifici da questo modello (vedere il suo documento dedicato ).


Grazie! Sembra molto utile. Per quelli al di fuori delle istituzioni accademiche, una versione prestampata del documento può essere estratta dal repository di codice google dell'autore qui: team4model.googlecode.com/svn/trunk/resources/paper/…
John Doucette,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.