2012-01-09 6 views
31

Sto cercando di eseguire QuickCheck su alcune liste nidificate, qualcosa che assomiglia a questo:Come si ottiene una riduzione (piccola) buona di QuickCheck?

type Constraint = Text 
data Value = Value [Constraint] 
data Literal = Literal Value [Value] 
type Formula = [Literal] 

Quindi una formula è una lista di letterali, ognuno dei quali contiene un predicato e alcuni argomenti; predicato/argomenti sono valori che sono una disgiunzione di vincoli in forma di stringa ciascuno. Questo ci dà una lista di liste di liste di liste, phew!

Se una delle mie proprietà QuickCheck fallisce, tendo ad ottenere una pagina incomprensibile di output. Prima di sperimentare con gli strizzacervelli, ero solito aggirarli avendo istanze arbitrarie che potevano generare solo un piccolo insieme di valori (piccoli). L'implementazione della funzione di restringimento per ciascuno dei miei tipi sembra aiutare un po ', ma non tanto quanto mi piacerebbe. Ho ancora una pagina di output.

Penso che quello che voglio da strizzacervelli è un piccolo elenco di valori letterali, in cui ogni letterale ha un piccolo elenco di valori, che a sua volta ha pochi vincoli, ognuno dei quali è il più corto possibile. Ma nei miei sforzi attuali, almeno di queste liste diventa abbastanza grande da rendere l'output orribile. Se provo a mettere a punto le mie implementazioni di strizzacervelli, scopro anche che il QC inizia a richiedere molto tempo (cercando gli shrink?), Il che smorza i miei sforzi per ridurli in modo efficace.

Come si aumentano le possibilità di comprendere i guasti di QuickCheck quando si hanno dati annidati come questo?

+1

Alcune cose che ho provato: preferendo shrinkList shrinkNothing per restringereList shrink e questa [alternativa shrinkList] (https://gist.github.com/1582767) che tenta di favorire la rimozione di più elementi. Ho il sospetto che mi stia masticando troppo e che dovrei fare qualcosa di completamente diverso, come cambiare le mie implementazioni arbitrarie, o testare in un modo diverso :-) – kowey

+0

Per ora, sto andando alla rotta pre-rimpicciolita ('prendi 5 <$> arbitrario'), che mi sembra ancora di trovare bug con – kowey

+1

Non esattamente una risposta, ma hai provato a utilizzare SmallCheck o anche LazySmallCheck invece di QuickCheck? –

risposta

1

Avevo un problema simile, ma stavo usando C e generatore di esempio fatto in casa :) Avevo un'implementazione lenta e corretta e veloce e scorretta.

Utilizzando esempi casuali, quando si trova un esempio errato, suggerirei di restringere l'esempio stesso. (Questo, ovviamente, potrebbe o dovrebbe essere fatto per programma, invece che per computer)

Se hai un predicato per questo test, e hai un esempio che non funziona, prova a eliminare gli elenchi di moduli di elementi, di tutti gli ordini (questo dovrebbe essere l'ordine di grandezza lineare delle chiamate) e per ogni tentativo se fallisce il test.

Se il problema persiste, non c'è motivo di mantenerlo nell'esempio.

Se inizia a passare, questo elemento dovrebbe rimanere nell'esempio ridotto.

(Questo è avido e non ottimale, ma non esegue in poli, invece di tempo esponenziale, e ha funzionato per me)

Per ulteriori sguardo scientifico, suggerisco capitolo "Semplificare problemi" dal libro "WHY PROGRAMS FAIL: A Guide to Systematic Debugging" di A.Zeller.

Nota: questo è in gran parte quello che fa strizzacervelli ...