Ruby -> Haskell 单元和自动化验收测试
Posted
技术标签:
【中文标题】Ruby -> Haskell 单元和自动化验收测试【英文标题】:Ruby -> Haskell Unit and Automated Acceptance Testing 【发布时间】:2013-08-18 10:30:23 【问题描述】:我是一名具有多种语言背景的程序员,但最近专注于 Ruby/Rails,并且有兴趣学习一些 Haskell。我也曾在 Closure 中玩过一些游戏(不过是非常基本的东西)。
我目前开发新 Ruby 应用程序的首选方法是从使用 Gherkin/Cucumber 之类的业务价值语言的高级测试开始,然后使用 RSpec 或 Minitest 之类的工具开发较小规模的组件。 (目前)开发新的 Haskell 应用程序最常见的类似工具集和策略是什么?
响应者:请耐心等待我的投票和回答接受。为了进行任何评估,我实际上必须在 Haskell 中做一些工作。谢谢。
【问题讨论】:
我认为一般而言,您在 Haskell 中发现的 TDD 方法比 Ruby 少,特别是编译器删除了很多需要在 Ruby 中进行单元测试的内容。我发现this answer 在查看 Haskell 的测试框架时很有用,“Real World Haskell”有第 12 章关于测试和 QA,推荐使用 QuickCheck 和 HPC。 @kieran 感谢您的链接。如果该语言删除了很多测试要求,那就太好了,但我认为这只是意味着需要更少的单元测试,而不是 TDD 失去了它的价值。另外,AAT 呢? HSpec 提到了“验收测试驱动计划”,但我没有看到任何类似 Cucumber 或 Fitness 的内容。我在 Github 上看到了一个 cucumber-haskell 项目,但它看起来像是一项正在进行的早期工作。 是的,我肯定没有看到过类似 Haskell 的 fitmente 的东西,这就是为什么我只是评论而不是回答的原因。我喜欢 TDD w/fitnesse 用于我在 .NET 中的工作,但我在 Haskell 周围进行黑客攻击的经验远不是一个面向测试的系统,而是更喜欢将小型、类型/数据驱动的正确函数组合成更大的系统,其中纯度等. 保证文章的正确性。认为值得一提的可能是不同的方法,但无论哪种方式,我都很感兴趣地看着这个问题 Haskell 的低级 TDD 的一个问题是,要编写有意义的测试,您需要知道所测试的类型。对于 Haskell 中通用功能的基本单元(特别是如果您正在设计让类型来表达尽可能多的代码属性),找出类型通常是最难的部分!找到正确的类型后,代码几乎会自行编写,这是一种常见的体验。如果是这种情况,那么组件开发的很大一部分(了解类型)是编写测试的先决条件。 【参考方案1】:通常,Haskell 应用程序的真实来源是类型系统。您可以使用 quickcheck 和 hspec 来确保您的代码执行您的想法,但这只是一种帮助。
【讨论】:
马克+1。这是迄今为止最常见的设计方法:在类型系统中设计业务逻辑;然后将无法以类型表示的不变量编码为 QuickCheck 属性。对于剩下的任何事情,使用 HUnit 等进行单元测试。 我的问题主要是关于 AAT,它本质上是用例测试或可执行文档。此类测试的主要用途是提供开发人员和利益相关者同意的“完成”定义(尽管这可能是一个人的 2 个不同角色)。 AAT 通常是用对非程序员来说有意义的语言编写的,并且覆盖案例可能涉及与用户和/或其他系统的多次交互,并且可能涉及对持久数据的多次更改(文件、数据库等) 对于较低层次的 TDD,我显然还没有做过任何 Haskell 编程,所以不应该过多争论,但是... 关于 TDD 的普遍看法是它的价值不会因有一个有用的类型系统。 1) 无论类型系统如何,程序员仍然会犯各种错误。 2) 进行测试可以提高对代码重构的信心,这是不可能的。 3) TDD 与帮助开发良好的 API 和获得测试覆盖率一样重要。我敢肯定还有很多我没有想到的论点。 关于 TDD:(0) 许多动态语言专家没有意识到像 GHC 这样的类型系统可以强制执行多少。 (我也不是。) (1) 也适用于测试,但表达类型/证明具有静态的优势,因此可以排除一大类错误; (2) 之前尝试过使用 Ruby 进行编程,相比使用测试来尝试覆盖类型系统排除的所有错误代码路径,我觉得依靠纯度和丰富的类型系统(如果需要,可以在以后进行测试)更有信心。 (3) 类型和/或证明驱动的开发满足相同的目标,静态保证有助于避免虚假 API。【参考方案2】:对于 Haskell 中基于故事的自动化验收测试,您有两个主要选择:
chuchu(Haskell 本身的一个不完整的 Cucumber/Gherkin 实现,Hackage page) Cucumber 使用 Wire 协议和用 Ruby 编写的测试当然,HSpec 承担了基于规范的验收测试角色。
通过使用基于属性的测试而不是 TDD 以及 QuickCheck 和 Smallcheck 等库,您可以获得更好的结果。
【讨论】:
【参考方案3】:据我所知,Haskell 没有 Cucumber 类似物。最接近您正在寻找的可能是 HSpec,它是 RSpec-ish。
这是一个例子,verbatim from the HSpec site:
import Test.Hspec
import Test.QuickCheck
import Control.Exception (evaluate)
main :: IO ()
main = hspec $ do
describe "Prelude.head" $ do
it "returns the first element of a list" $ do
head [23 ..] `shouldBe` (23 :: Int)
it "returns the first element of an *arbitrary* list" $
property $ \x xs -> head (x:xs) == (x :: Int)
it "throws an exception if used with an empty list" $ do
evaluate (head []) `shouldThrow` anyException
哪个产生
Prelude.head
- returns the first element of a list
- returns the first element of an *arbitrary* list
- throws an exception if used with an empty list
【讨论】:
以上是关于Ruby -> Haskell 单元和自动化验收测试的主要内容,如果未能解决你的问题,请参考以下文章