3

我有“父”A类型,其中包含“子”B类型。

这是我的应用程序中主要数据结构的简化版本。

AB和都是独立的 elm 模块A_idB_id

如果我可以使这种简化工作,那么可能更容易解决我的实际问题。

基本上我的问题是如何为A.

条件是两者A_idB_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.

榆树嵌套模糊器错误

在我的实际应用程序中,我得到了更复杂的错误:

Fuzzer ( Fuzzer ( Fuzzer ( Fuzzer Exchange )))Fuzzer Exchange

我基本上需要将其展平andThen- 但在 fuzz elm 测试包中不存在这样的功能 - 出于一些不太明显的原因。

我尝试了什么:

我正在与这个问题作斗争 3 天 - 有人在 slack 建议andthen故意将其移除,我应该使用custom模糊器 - 我更深入地了解了收缩器的工作原理(我以前不知道它们)以及如何使用Fuzz.custom只是测试它们是否正确。

Fuzz.custom 需要一个生成器和一个收缩器。

我可以构建生成器并生成我需要的一切,但我不能构建收缩器 - 因为 B 和 A 以及 C 和 D.. 等等都是不透明的数据结构 - 在它们自己的模块中 - 所以我需要得到它们的所有带有吸气剂的属性 - 为了缩小它们。

所以对于上面的例子 - 要缩小B我需要提取并通过一个缩小器运行它.. 然后通过创建一个新的b_id来放回它- 使用公共 api .. 我没有公共的 getter api我保留的属性,等等..这样做似乎是错误的(添加我在应用程序中不需要的getter - 仅用于测试目的..)BBBBCD

所有这些混乱都是因为andThen在 fuzz 模块上被删除了......但也许有办法,也许他们是对的 - 我没有看到解决方案。链接到模糊器模块:这里

那么如何为A数据类型构建一个模糊器呢?

任何想法如何处理这个嵌套的模糊器?如何将它们展平回到一个级别?

或者换一种说法,如何构建像上面那样相互依赖的模糊?(我想到的一个例子是 - 就像运行一个依赖于另一个 http 请求在它开始之前完成的 http 请求 - 因为它需要来自前一个请求的数据.. 这个模型被认为是函数式编程并且通常完成与andThenbind或东西。)

任何见解都值得赞赏。谢谢 :)

4

1 回答 1

4

我可以构建生成器并生成我需要的一切,但我无法构建收缩器

那就别打扰了。传给. Shrink.noShrink_ Fuzz.custom唯一的缺点是当你的测试失败时,你会得到几个大的类型值,A而不是(理想情况下)一个小的值。

当您使用复杂类型时,您将更好地了解如何将导致测试失败的值缩小为仍然导致测试失败的“较小”值。就此而言,您将更好地生成发现测试失败的“有趣”值。

在 elm-test 的下一个主要版本(未设置时间线)中,Shrinkers 将有相当大的改进,包括更好的文档、删除惰性列表以支持常规 Elm 列表以及重命名为“Simplifier”。

于 2019-07-04T03:11:10.700 回答