2011-12-17 14 views
7

Ho scritto un modulo per macchine a stati finiti per un piccolo gioco di calcio al quale lavoro attualmente. Fornisce un'interfaccia per l'impostazione di un FSM (fondamentalmente i suoi stati e transizioni). Per ogni stato, è possibile fornire funzioni che verranno attivate all'entrata e all'uscita o mentre l'FSM rimane nello stesso stato, quindi queste funzioni restituiscono alcuni messaggi. Fornisce anche un'interfaccia reattiva (Yampa) che produce lo stato variabile nel tempo e raccoglie i messaggi che si verificano nel tempo. Il codice è qui Data/FSM.hs.Haskell: Come testare un FSM (reattivo) con quickcheck?

Sto cercando un buon approccio per testare questo modulo. Dato che è puro, ho pensato di provare Quickcheck. Non ho esperienza con quickcheck, quindi qualsiasi suggerimento sarebbe apprezzato! La mia comprensione di base finora: uno fornirebbe alcune funzioni che costruiscono gli FSM in modo più o meno casuale, e quindi eseguiranno alcune (ancora più o meno casuali) transizioni su di esse. Ma non riesco a vedere come costruire un test in questo modo ...

+0

Beh, che tipo di test vuoi scrivere? Quali proprietà o comportamenti devono essere verificati? –

+0

Beh, forse il problema è che non lo so davvero ... Per qualcosa di semplice come "per ogni fsm valido, qualsiasi elenco finito di transizioni porta a uno stato 'Niente' o stato 'Giusto s' dove s è uno stato in fsm ", ok. Ma cose più complicate come "per ogni fsm valido e elenco di transizioni e percezioni (variabili nel tempo), ogni raccolta di messaggi lungo il percorso di transizione dovrebbe essere presa", non saprei come formalizzarlo. Saprei come impostare i test unitari, ma con quickcheck sono un po 'perso. – martingw

+0

Il collegamento è morto (https://patch-tag.com/r/martingw/Rasenschach/snapshot/current/content/pretty/Data/FSM.hs) e non è presente alcun archivio che possa trovare – icc97

risposta

4

Prima di tutto, QuickCheck è probabilmente il più adatto per la verifica di proprietà generali ampie. Dati dati arbitrari di qualche tipo, eseguire alcune operazioni, quindi utilizzare un predicato per assicurarsi che il risultato abbia una proprietà relativa all'input. Le cose che coinvolgono dettagli precisi del comportamento passo-passo potrebbero non funzionare bene in questo stile e non dovresti sentirti obbligato a fare tutto in QuickCheck!

Detto questo, basandoti sull'esempio più complesso che hai fornito in un commento, hai considerato semplicemente la generazione dell'output atteso insieme agli FSM e agli input? Se è possibile produrre un risultato desiderato che è corretto per costruzione, è possibile eseguire l'FSM sull'input e confrontare il risultato effettivo con la versione costruita.

Potrebbe essere utile evitare di pensare alle proprietà QuickCheck come testare una funzione su alcuni input, ma piuttosto come verificare se uno o più valori soddisfano alcuni predicati espressi in termini della funzione sottoposta a test. Questa raccolta di valori (che può includere più input, output, qualunque cosa sia necessaria) è ciò che viene effettivamente generato in modo casuale da QuickCheck.

+0

Quindi probabilmente un mix è l'approccio migliore: testare un risultato specifico per uno specifico fsm e inserire HUnit per situazioni passo-passo e quickcheck per proprietà più generiche? – martingw

+1

@martingw: Penso che un mix sia il miglior approccio predefinito, sì. Sono abbastanza sicuro che ci siano anche cose su Hackage che forniscono cablaggi di test unificati per HUnit, QuickCheck e forse altre cose. Probabilmente direi che il QuickCheck dovrebbe essere preferito, quando possibile, ma funziona meglio quando tutto quello che stai testando è che ottieni da A a B, non i dettagli del percorso intrapreso. –