TDD与F#和Erlang等函数式编程语言相比如何?我实际上还没有直接使用过函数式编程语言,但从我所看到的来看,你有两个方程的两侧,它们必须像代数或会计一样平衡;这似乎有点类似于TDD,其中你将期望的输出定义为Assert语句(方程的一边),而其余功能则进入与测试分离的类中(方程的另一边),只是函数式编程IMHO看起来更加简洁。这两者是否实际上存在相似之处,还是我有点想多了呢?
它们是正交的。
TDD是一种开发软件的方法,它专注于在编写生产代码之前通过针对规范编写测试来确保正确性。函数式编程是一种设计和实现软件的范式。
我认为TDD和函数式编程(FP)不同,因为TDD是一种方法论,而FP是一种编程范式。
我认为FP在实践TDD时有帮助,因为FP鼓励您在可能的情况下使事情具有确定性。确定性函数比非确定性函数更容易测试。
Chris说它们是正交的,这是正确的。然而,函数式编程的一些方面使得测试函数式程序变得更加容易。
函数式程序由函数组成,并保证该函数在所有上下文中的行为都相同。这意味着当你在单元测试中测试一个函数时,你知道它会始终以这种方式工作。你不需要测试它是否在其他环境中工作。
函数接受参数并返回结果,这是它们唯一要做的事情。这意味着你通常可以避免模拟和类似的技巧,因为你不需要验证函数是否对某个对象进行了调用。你只需要验证它针对给定的参数返回了预期的结果。
最后,有一些很棒的自动化工具可用于测试函数式程序。对于F#,我们有FsCheck(基于Haskell中已知的QuickCheck)。这些工具受益于函数式程序的各种属性。
你说得没错,编写函数式程序时,可能会使用等式推理来推导出函数的定义。然而,这种推理通常不存在于某种具体形式(比如测试)中,因此通常情况下,无法通过机器或人工检查来证明函数的正确性。当然,可以使用TDD与函数式语言一起使用(例如使用任何与F#兼容的.NET TDD库)来验证已正确推导出的函数,但也有其他测试策略可能更适用于函数式语言,例如使用QuickCheck进行随机规范检查。
我认为两者之间的相似感源于一个事实,即在两种情况下,函数都应该是确定性的。函数式编程中的函数不应该有副作用,而面向对象代码的测试函数中的副作用应该通过注入存根来消除。