Я использую FsCheck для тестирования на основе свойств, поэтому я определил набор генераторов для пользовательских типов. Одни типы состоят из других, и для всех есть генераторы. Определив генератор для буквенно-цифрового типа, я хочу определить генератор для типа RelativeUrl, а RelativeUrl представляет собой список из 1-9 буквенно-цифровых значений, разделенных косой чертой. Вот определение, которое работает (Alpanumeric имеет свойство «Value», которое преобразует его в String):
static member RelativeUrl() =
Gen.listOfLength (System.Random().Next(1, 10)) <| Generators.Alphanumeric()
|> Gen.map (fun list -> String.Join("/", list |> List.map (fun x -> x.Value)) |> RelativeUrl)
Несмотря на то, что это довольно просто, мне не нравится, что я использую метод Random.Next вместо использования генераторов случайных чисел FsCheck. Поэтому я попытался переопределить его следующим образом:
static member RelativeUrl_1() =
Arb.generate<byte>
|> Gen.map int
|> Gen.suchThat (fun x -> x > 0 && x <= 10)
|> Gen.map (fun length -> Gen.listOfLength length <| Generators.Alphanumeric())
|> Gen.map (fun list -> String.Join("/", list))
Компилятор принимает это, но на самом деле это неправильно: «список» в последнем выражении — это не список буквенно-цифровых значений, а Gen. Следующая попытка:
static member RelativeUrl() =
Arb.generate<byte>
|> Gen.map int
|> Gen.suchThat (fun x -> x > 0 && x <= 10)
|> Gen.map (fun length -> Gen.listOfLength length <| Generators.Alphanumeric())
|> Gen.map (fun list -> list |> Gen.map (fun elem -> String.Join("/", elem |> List.map (fun x -> x.Value)) |> RelativeUrl))
Но это тоже не работает: я получаю Gen of Gen of RelativeUrl, а не Gen of RelativeUrl. Так как же правильно комбинировать генераторы на разных уровнях?
System.Random
нельзя использоватьGen.choose
? - person Mark Seemann   schedule 31.03.2016choose
вместоRandom
, мгновенно сэмплируя его, но это противоречит цели, потому что этотchoose
не будет частью результирующего генератора, а будет работать как своего рода служебная функция. Не лучше, чемRandom
, правда. - person Fyodor Soikin   schedule 31.03.2016System.Random
в генераторах, потому что это разрушит воспроизводимость (т. Е. Одно и то же семя каждый раз возвращает разные результаты) и сделает сжатие невозможным (или, по крайней мере, недетерминированным). - person Kurt Schelfthout   schedule 01.04.2016Gen.choose
вместо Random. Если вы подключите его вместо Random в первом блоке кода OP, это будет бесполезно, не так ли? - person Fyodor Soikin   schedule 01.04.2016Gen.choose |> Gen.sample
, это не лучше, чем Random. Но не думайте, что @MarkSeemann имел в виду именно это :) Путаница повсюду... но я думаю, что мы все говорим об одном и том же. - person Kurt Schelfthout   schedule 01.04.2016