应该测试功能成分和管道吗?

时间:2018-01-01 12:49:44

标签: unit-testing f# functional-programming fscheck

在F#(以及大多数函数式语言)中,某些代码非常短,如下所示:

let f = getNames
>> Observable.flatmap ObservableJson.jsonArrayToObservableObjects<string>

或:

let jsonArrayToObservableObjects<'t> =
    JsonConvert.DeserializeObject<'t[]> 
    >> Observable.ToObservable

最后一个基于属性的测试我最终用于后一个函数:

 testList "ObservableJson" [
        testProperty "Should convert an Observable of `json` array to Observable of single F# objects" <| fun _ -> 
            //--Arrange--
            let (array , json) = createAJsonArrayOfString stringArray

            //--Act--
            let actual = jsonArray
                         |> ObservableJson.jsonArrayToObservableObjects<string> 
                         |> Observable.ToArray 
                         |> Observable.Wait


            //--Assert--
            Expect.sequenceEqual actual sArray
    ]

无论安排部分如何,测试都不仅仅是被测功能,因此它比被测功能更难阅读!

  • 当测试比生产代码更难阅读时,测试的价值是什么?

另一方面:

  • 我想知道多功能组合的功能是否安全不被测试?
  • 他们应该在整合和接受程度进行测试吗?
  • 如果它们很短但做复杂的操作怎么办?

2 个答案:

答案 0 :(得分:1)

取决于您对功能编程的定义&#39;是。或者甚至更精确 - 你想要与功能编程的起源保持多近 - 数学具有广义和狭义的含义。

让我们采取一些与编程相关的东西。说,映射理论。你的问题可以用这样的方式翻译:从A到B的双射,以及从B到C的双射,我是否应该证明这两者的构成也是双射?答案是双重的:你绝对应该,而且你只做一次:你的证明足以涵盖所有可能的案例。

回归编程,这意味着必须仅对管道衬里进行一次测试(证明) - 我想这是在部署到生产之前。由于您作为程序员的工作来创建具有这种质量的函数(映射),由管道运算符或其他任何东西组成,保留所需的属性。再一次,坚持使用通用参数而不是写大量类似的测试会更好。

所以,最后,我们得出一个更有价值的问题:如何保证某些操作可以保留一些财产?事实证明,承认这一事实的最简单方法是处理来自伟大的Haskell的Monoid类型:例如,Monoind代表任何关联二进制文件操作A -> A -> A以及类型A的一些标识元素。拥有这样的通用容器是非常有利可图的,并且是明确知道代码设计的内容和方式的明确方式。

答案 1 :(得分:0)

我个人不会测试它。

事实上,对测试的需求较少,而更多地依赖更严格的编译器规则,无副作用函数,不变性等是我更喜欢F#而不是C#的一个主要原因。

当然,我继续(单位)测试&#34;自定义逻辑&#34; ...例如算法代码