2011-11-16 1 views
5

En F #, j'ai un enregistrement avec quelques champs:Dans FsCheck, comment générer un enregistrement de test avec des champs non négatifs?

type myRecord = { a:float; b:float; c:float } 

J'utilise FsCheck pour tester certaines propriétés qui utilisent cet enregistrement. Pour (un pièce) par exemple,

let verify_this_property (r:myRecord) = myFunction(r) = (r.a * r.b)/r.c 

En raison des restrictions de mise en œuvre interne de maFonction, je voudrais avoir FsCheck créer des cas de test dans lequel chacun des champs a, b, c sont limités à non -flotteurs négatifs.

Je suppose que cela nécessite la création d'un générateur pour myRecord, mais je n'ai pas trouvé d'exemples de la façon de procéder.

Quelqu'un peut-il fournir des conseils?

+0

Avez-vous soigneusement lisez [cette page Wiki FsCheck] (http://fscheck.codeplex.com/wikipage?title=Test%20Data%20Generators&referringTitle=Home)? Il a un exemple de comment écrire et enregistrer un générateur. – fmr

+2

@ fmr - Oui, j'ai lu attentivement toutes les pages Wiki FsCheck. Alors que les étapes pour écrire un générateur simple sont fournis (pas très clairement à mon humble avis), je suis incapable de déterminer comment étendre cela pour créer un générateur pour les enregistrements - d'où la question SO. –

Répondre

7

Essayez ceci:

type Generators = 
    static member arbMyRecord = 
     fun (a,b,c) -> { myRecord.a = a; b = b; c = c } 
     <!> (Arb.generate<float> |> Gen.suchThat ((<) 0.) |> Gen.three) 
     |> Arb.fromGen 

Arb.register<Generators>() |> ignore 
Check.Quick verify_this_property 

Le <!> est un infix map, utile pour le style applicatif. Ceci est un générateur équivalent:

Si vous ne voulez pas globalement enregistrer votre générateur, vous pouvez utiliser forAll:

Check.Quick (forAll Generators.arbMyRecord verify_this_property) 

CISSEMENT à titre d'exercice;)

+0

Quelle est la signification de la construction ""? Je n'ai pas vu ça avant. –

+2

@DavidH: c'est un infixe 'map', utile pour le style applicatif. Voir http://bugsquash.blogspot.com/2010/12/zipping-with-applicative-functors-in-f.html –

+0

@DavidH: expliqué un peu plus. –

3

Vous pouvez éviter de créer générateur personnalisé en utilisant FsCheck conditional properties

let verify_this_property (r:myRecord) = 
    (r.a > 0.0 && r.b > 0.0 && r.c > 0.0) ==> lazy (myFunction r = (r.a * r.b) * r.c) 

Bien que cela entraînera (essentiellement?) Exécution plus lente du test car FsCheck devra supprimer toutes les entrées de test ne conviennent pas.

Questions connexes