如何在绒毛测试模块中不使用andThen的情况下弄平绒毛(绒毛(绒毛A))?

时间:2019-07-03 18:45:54

标签: elm elm-test

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

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

AB以及A_idB_id都是独立的elm模块。

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

基本上,我的问题是如何为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

elm nested fuzzer error

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

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

我基本上需要使用andThen对其进行展平-但由于某些不太明显的原因,在模糊Elm测试包中不存在此类功能。

我尝试过的事情:

我正在解决这个问题3天-闲散的人建议andthen被故意移除,而我应该使用custom绒毛机-我更深入地学习了收缩机的工作原理(i以前不了解它们)以及如何使用Fuzz.custom只是为了测试它们是否正确。

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

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

因此,对于上面的示例-要缩小B,我需要提取b_id并使其通过收缩器运行..然后通过创建一个新的{将其放回B {1}}-使用B的公共api ..对于我在BBC上保留的所有属性,我没有公共的getter api等等。这样做似乎是错误的(添加我不需要在应用程序中使用的吸气剂-仅用于测试目的。)

所有这些混乱情况是因为模糊模块上的D已被删除...但是也许有办法,也许它们是正确的-我没有看到解决方案。 链接到模糊器模块:here

那么如何为andThen数据类型构建模糊器?

有什么想法如何处理这个嵌套的模糊器?如何将它们压平到一个水平?

或者用不同的措辞表述,如何构建像上面那样相互依赖的模糊测试?(我想到的一个例子是-运行依赖于另一个http请求的http请求可以在开始之前完成-因为它需要来自上一个请求的数据..该模型可以从功能编程的角度来看,通常使用AandThen或其他东西完成。)

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

1 个答案:

答案 0 :(得分:4)

  

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

那就别打扰了。将Shrink.noShrink传递到Fuzz.custom。唯一的缺点是,如果您的测试失败,则会得到A类型的多个大值,而不是(理想情况下)一个小的值。

使用复杂类型时,您将更好地了解如何将其导致测试失败的值缩小为仍能导致测试失败的“较小”值。为此,您会更好地生成“有趣的”值以查找测试失败。

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

>