Elm 在模糊测试模块中,如何在没有和的情况下展平模糊(Fuzz(Fuzz A))?

Elm 在模糊测试模块中,如何在没有和的情况下展平模糊(Fuzz(Fuzz A))?,elm,elm-test,Elm,Elm Test,我有一个“父”a类型,其中包含“子”B类型 这是我应用程序中主要数据结构的简化版本 A和B和A\u id和B\u 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

我有一个“父”
a
类型,其中包含“子”
B
类型

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

A
B
A\u id
B\u 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 })
那么如何创建这个
模糊器A

对于上面的代码,我得到了
Fuzzer(Fuzzer A)
错误,而不是
Fuzzer A

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

Fuzzer(Fuzzer(Fuzzer(Fuzzer交换)))
vs
Fuzzer交换

我基本上需要用
将其展平,但fuzz-elm测试包中不存在这样的函数,原因不太明显

我的尝试:

我与这个问题斗争了3天-有人提出了
,然后故意删除了
,我应该使用
自定义
模糊器-我更深入地了解了收缩器是如何工作的(我以前不知道它们),以及如何使用
Fuzz.custom
来测试它们是否正确

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

我可以建造发电机,生成我所需要的一切,但我不能建造收缩器——因为B、A、C和D。。所有这些都是不透明的数据结构——在它们自己的模块中——所以我需要用getter获取它们的所有属性——以便缩小它们

因此,对于上面的示例-要收缩
B
,我需要提取
B_id
,并通过收缩器运行它。。然后通过使用
B
的公共api创建一个新的
B
,将其放回
B
。。我没有为我保存的所有属性提供公共getterapi,
B
C
D
等等。。这样做似乎是错误的(为了在应用程序中添加我不需要的getter——只是为了测试目的…)

所有这些混乱都是因为模糊模块上的
被删除了。。。但也许有一种方法,也许他们是对的——我没有看到解决办法。
链接到fuzzer模块:

那么,如何为
a
数据类型构建模糊器呢

你知道如何处理嵌套的模糊程序吗?如何将它们展平到一个水平

或者换一种说法,如何构建如上所述的相互依赖的模糊?(我脑海中的一个例子是——就像运行一个依赖于另一个http请求完成的http请求,然后才能启动一样——因为它需要来自前一个请求的数据。这个模型被认为是函数式编程,通常使用
绑定
或其他东西来完成。)

如有任何见解,我们将不胜感激。谢谢:)

我可以制造发电机,生成我需要的一切,但我不能制造收缩器

那就不用麻烦了。传给。唯一的缺点是,当您的测试失败时,您将获得多个类型为
a
的大值,而不是(理想情况下)一个小值

在处理复杂类型时,您将更好地了解如何将导致测试失败的值收缩为仍然导致测试失败的“较小”值。对于这一点,您将更好地生成查找测试失败的“有趣”值

在elm测试的下一个主要版本(未设置时间线)中,将对收缩器进行重大改进,包括更好的文档、删除惰性列表以支持常规elm列表,以及重命名为“Simplier”