Myślałem, że nadszedł czas, aby wypróbować FsCheck, ale okazuje się trudniejsze niż myślałem. Istnieje wiele dokumentacji na temat Arb
, generatorów i tak dalej, ale nie ma żadnych wskazówek, jak zastosować tę wiedzę. Albo po prostu nie rozumiem.Jak używać FsCheck do generowania liczb losowych jako danych wejściowych do testów opartych na właściwościach?
Co może utrudnić zrozumienie, to to, że relacja między testami, właściwościami, generatorami, arbitrami, zmniejszaniem i, w moim przypadku, losowością (niektóre testy automatycznie generują losowe dane, inne nie) jest dla mnie niejasna . Nie mam tła Haskella, więc to też niewiele pomaga.
Teraz pytanie: jak generować losowe liczby całkowite?
Mój scenariusz testu można wyjaśnić na właściwości mnożenia, powiedzmy rozdzielność:
static member ``Multiplication is distributive`` (x: int64) y z =
let res1 = x * (y + z)
let res2 = x * y + x * z
res1 = res2
// run it:
[<Test>]
static member FsCheckAsUnitTest() =
Check.One({ Config.VerboseThrowOnFailure with MaxTest = 1000 }, ``Multiplication is distributive``)
Kiedy uruchomić to z Check.Verbose
lub integracji NUnit, mam sekwencje testowe jak:
0:
(-1L, -1L, -1L)
1:
(-1L, -1L, 0L)
2:
(-1L, -1L, -1L)
3:
(-1L, -1L, -1L)
4:
(-1L, 0L, -1L)
5:
(1L, 0L, 2L)
6:
(-2L, 0L, -1L)
7:
(-2L, -1L, -1L)
8:
(1L, 1L, -2L)
9:
(-2L, 2L, -2L)
Po 1000 testów nie uzyskał więcej niż 100L
. Jakoś sobie wyobrażałem, że to "automatycznie" wybiera losowe liczby równomiernie rozłożone w całym zakresie int64
, przynajmniej tak zinterpretowałem dokumentację.
ponieważ nie zacząłem eksperymentować i wpadł głupich rozwiązań takich jak następujących, aby uzyskać wyższe numery:
type Generators =
static member arbMyRecord =
Arb.generate<int64>
|> Gen.where ((<) 1000L)
|> Gen.three
|> Arb.fromGen
ale to staje się niezwykle wolno i wyraźnie nie jest właściwe podejście. Jestem pewien, że musi istnieć proste rozwiązanie, którego mi brakuje. Próbowałem z Gen.choose(Int64.MinValue, Int64.MaxValue)
, ale to obsługuje tylko ints, nie longs (ale nawet z tylko ints nie mogłem go uruchomić działa).
W końcu potrzebuję rozwiązania, które działa dla wszystkich podstawowych typów danych liczbowych, które obejmują ich maksima i miny, ich zera i jedynek, a także losowy wybór z tego, co jest w środku.
Myślę, że to w praktyce ogranicza maksymalną liczbę. do 100, zobacz: [fscheck Q] (http://stackoverflow.com/questions/40591229/fscheck-doesnt-generate-random-enough-data/) – s952163
@ s952163, tak, dlatego próbowałem z 'MaxTest = 1000 ', patrz powyższy kod. Ale to nie pomaga. Być może masz na myśli wartości 'StartTest' i' EndTest', ale ustawienie ich na 'Int32.MinValue/MaxValue' daje efekt, że * wszystkie * permutacje używają' Int32.MinValue' jako stałej wartości. – Abel