Как сгладить Fuzz (Fuzz (Fuzz A))), не имея andThen в модуле тестирования fuzz? - PullRequest
3 голосов
/ 03 июля 2019

У меня есть «родительский» тип A, который содержит «дочерний» тип B.

Это упрощенная версия основных структур данных, которые есть в моем приложении.

A и B и A_id и B_id являются отдельными модулями Elm.

Если я смогу сделать это упрощение работоспособным, то, возможно, мне будет проще решить мою настоящую проблему.

В основном моя проблема заключается в том, как создать фаззер для A.

с условием, что оба A_id и B_id .. должны совместно использовать один и тот же A_id.

type A
    = A { id : A_id
        , b : B -- A contains B.
        }

type A_id
    = A_id String

type B
    = B { id : B_id } -- B contains B_id

type B_id
    = B_id ( A_id, String ) -- B_id contains A_id. The exact same A_id as its parent A

a_idFuzzer : Fuzzer A_id
a_idFuzzer =
    Fuzz.string
        |> Fuzz.map A_id

aFuzzer : Fuzzer A
aFuzzer =
    a_idFuzzer
        |> Fuzz.map
            (\a_id ->
                bFuzzer a_id
                    |> Fuzz.map
                        (\b ->
                            -- here i just need the b,
                            -- but in reality i need more children
                            -- for assembling the A data structure.
                            -- i need a C and D with a cFuzzer and a dFuzzer...
                            -- and both C and D depend on having the same A_id value.
                            -- like B does.
                            A
                                { id = a_id
                                , b = b
                                }
                        )
            )



-- im passing A_id as an argument since is generated only once on the parent ( A )
-- and is shared with this B child.

bFuzzer : A_id -> Fuzzer B
bFuzzer a_id =
    Fuzz.string
        |> Fuzz.map (\s -> B_id ( a_id, s ))
        |> Fuzz.map (\id -> B { id = id })

Так как создать этот Fuzzer A?

Для кодавыше я получаю ошибку Fuzzer (Fuzzer A) в отличие от Fuzzer A.

elm nested fuzzer error

В моем реальном приложении я получаю более сложную ошибку:

Fuzzer ( Fuzzer ( Fuzzer ( Fuzzer Exchange ))) против Fuzzer Exchange.

Мне нужно сгладить его с помощью andThen - но в тестовом пакете fuzz elm такой функции не существует - по какой-то не очень очевидной причине.

Что я пробовал:

Я борюсь с этой проблемой в течение 3 дней - кто-то в расслабленном состоянии предположил, что andthen был преднамеренно удален, и я должен использовать фаззер custom - я узнал глубже, как работают усадочные машины (я не сделалзнал их раньше) и как использовать Fuzz.custom только для проверки, если они правы.

Fuzz.custom нужны генератор и термоусадочная машина.

Я могу построить генератор и генерировать все, что мне нужно, но я не могу строить термоусадочные машины - так как B и A и C и D.. и так далее, все непрозрачные структуры данных - в своем собственном модуле - поэтому мне нужно получить все их свойства с помощью геттеров - чтобы уменьшить их.

Так что для примера выше - уменьшить B iнужно извлечь b_id и запустить его через усадку .. и затем вернуть его обратно в B, создав новый B - используя общедоступный API для B .. и у меня нет общедоступного геттераAPI для всех свойств, которые я поддерживаю B, C, D и т. д., и это просто кажется неправильным делать это (добавлять геттеры, которые мне не нужны, в приложении - только для целей тестирования)..)

Весь этот беспорядок, потому что andThen на модуле fuzz был удален ... но, возможно, есть способ, возможно, они были правы - и я не вижу решения.Ссылка на модуль фаззера: здесь

Итак, как построить фаззер для A типа данных?

Есть идеи, как справиться с этим вложенных фаззеров ?Как сгладить их обратно на один уровень?

Или, если выразить это по-другому, Как построить размытости, которые зависят друг от друга, как описано выше? (пример, который я имею в виду, был бы -например, выполнение http-запроса, который зависит от выполнения другого http-запроса до его запуска - поскольку для этого нужны данные из предыдущего запроса ... эта модель рассматривается как функциональное программирование и обычно выполняется с andThen или bind или другими компонентами.)

Любое понимание приветствуется.Спасибо:)

1 Ответ

4 голосов
/ 04 июля 2019

Я могу построить генератор и сгенерировать все, что мне нужно, но я не могу построить термоусадочные

Тогда не беспокойся. Передайте Shrink.noShrink на Fuzz.custom. Единственный недостаток будет в том случае, если у вас будет неудачный тест, и вам будет дано несколько больших значений типа A, а не (в идеале) одно маленькое.

Работая со своим сложным типом, вы лучше поймете, как сжать его значения, которые приводят к сбоям теста, в «меньшие» значения, которые по-прежнему вызывают сбой теста. В этом отношении вам будет легче генерировать «интересные» значения, которые обнаружат неудачи теста.

В следующем основном выпуске elm-test (временная шкала не установлена) в Shrinkers будут внесены значительные улучшения, включая улучшение документации, удаление отложенных списков в пользу обычных списков Elm и переименование в «Simplifier».

...