122

两者都是用 Scala 编写的支持 BDD(行为驱动开发)的 Scala 单元测试框架。而Specs 的构建也可能涉及到ScalaTest框架。但是 Specs 提供的 ScalaTest 没有提供什么?有什么区别?

4

5 回答 5

175

Specs 和 ScalaTest 都是用户满意的好工具,但它们在几个方面有所不同。您可能希望选择一个作为您在 Scala 中的主要测试工具,但不必放弃另一个,因为您可以同时使用两者。例如,如果您喜欢 ScalaTest 的FeatureSpec语法和 specs 的 Mockito 语法,您可以将这两个 jar 文件放在您的类路径中并同时使用它们。在这里,我将尝试捕捉我注意到的规范和 ScalaTest 之间的主要设计理念差异。

这些工具之间的主要哲学差异可能是规范是为行为驱动开发 (BDD) 设计的,而 ScalaTest 更通用。ScalaTest 提供了可以混合在一起的特征,以在测试类中获得您喜欢的行为,包括 BDD,如果您想要不同的东西,您还可以轻松定义自己的行为。

ScalaTest 通过它的Spec, FeatureSpec, WordSpec, FlatSpec, 和GivenWhenThentraits 支持 BDD,并且还具有可以混合使用的特征以获得良好的匹配器语法。如果你喜欢“应该”,你可以混入 ShouldMatchers。如果你喜欢“必须”,你可以混入MustMatchers. 但是,如果您喜欢 BDD 但不喜欢匹配器语法,则可以只使用 ScalaTest 的 Spec 特征之一,而无需混合匹配器特征。Specs 有一个可以扩展的 Specification 类,并且必须在匹配器表达式中使用“必须”一词。在这里显而易见的一个重大哲学差异是 ScalaTest 为您提供了更多选择。为了使这个选择空间更容易导航,我在这里提供了一个决策树:

http://www.scalatest.org/quick_start

ScalaTest 和规范之间的匹配器语法也不同。在 ScalaTest 中,我试图看看我可以用运算符符号走多远,最后得到的匹配器表达式读起来很像英语句子,单词之间有空格。Specs 匹配器语法更多地将单词与驼峰式大小写一起运行。

Specs 比 ScalaTest 有更多的匹配器,我认为这反映了设计态度的不同。实际上,我大约削减了我构建并考虑发布的匹配器语法的 2/3。我将在未来的版本中添加更多匹配器,但我想确保在添加之前我知道用户确实想要一些东西。然而,ScalaTest 的匹配器包括一个动态属性匹配器语法,弥补了一些不足。例如,在 Specs 中,您可以写在java.io.File

file must beDirectory

这将调用isDirectory并确保它是真的。ScalaTest 目前没有任何特殊的匹配器java.io.Files,但在 ScalaTest 中,您可以使用如下动态检查:

file must be a ('directory)

每当您在 after 中传递符号时be,它将使用反射来查找(在这种情况下)名为的方法或字段directory或名为的方法isDirectory。还有一种方法可以使这个静态化,通过定义 a BePropertyMatcher(通常只需要 2 或 3 行代码)。所以基本上在 ScalaTest 中,我尝试用更少的 API 提供更多的功能。

specs 和 ScalaTest 之间的另一个一般设计态度差异涉及隐式转换。默认情况下,当您使用 ScalaTest 时,您只会获得一次隐式转换,这是将===运算符放在所有内容上的转换。(如果需要,您可以使用一行代码“关闭”这种隐式转换。您需要这样做的唯一原因是,如果您尝试测试具有自己的===运算符的东西,并且您会遇到冲突。 ) ScalaTest 定义了许多其他隐式转换,但是要使用它们,您需要通过混合特征或执行导入来显式地将它们“邀请”到您的代码中。当您扩展课程时Specification在规范中,我认为默认情况下您几乎可以获得几十个隐式转换。我不确定这在实践中有多重要,但我认为人们会想要测试使用他们自己的隐式的代码,有时测试框架的隐式和生产代码的隐式之间可能会发生冲突。当发生这种情况时,我认为在 ScalaTest 中解决问题可能比规范更容易。

我注意到的另一个设计态度差异是操作员的舒适度。我的一个目标是,任何查看他人使用 ScalaTest 的测试代码的程序员都能够猜出其含义,而无需在 ScalaTest 文档中查找任何内容。我希望 ScalaTest 客户端代码显而易见。实现目标的一种方式是 ScalaTest 对运算符非常保守。我在 ScalaTest 中只定义了五个运算符:

  • ===, 这意味着等于
  • >,这意味着大于
  • <, 少于
  • >=, 大于或等于
  • <=, 小于或等于。

就是这样。所以这些东西看起来很像什么意思。如果你在别人的代码中看到:

result should be <= 7

我希望你不需要跑到 API 文档来猜测这<=意味着什么。相比之下,规范对操作员来说要自由得多。这没什么错,但它是一个区别。->-运算符可以使代码更简洁,但代价是,当您在同事的测试代码中发现诸如、>>||>!^^^(它们在 Specs 中都有特殊含义)之类的东西时,您可能不得不跑到文档 中。

另一个哲学上的区别是,当您需要共享固定装置时,我确实尝试让 ScalaTest 中使用函数式样式变得稍微容易一些,而 Specs 默认情况下延续了JUnit 普及的方法的传统,在该方法中您重新分配setUpvarstearDown每次测试前。但是,如果您想以这种方式进行测试,在 ScalaTest 中也很容易。你只需要混合BeforeAndAfter特征。

要更深入地了解 ScalaTest,您可以在此处观看我在 2009 Devoxx 会议上发表的“Get Higher with ScalaTest”演示:

http://parleys.com/play/514892260364bc17fc56bde3/chapter0/about

于 2010-02-26T19:26:31.790 回答
49

主要区别是(主要从规格的角度来看:-)):

  • ScalaTest 提供了比规范更多的“测试风格”(您可以访问快速入门页面上的每个项目符号以获取每种风格的详细视图)

  • ScalaTest 和规范有一组不同的匹配器。你可以在这里比较它们的 ScalaTest 和这里的规格。在这方面,specs 有很多你在编写规范时可能会喜欢的小特性:xml 匹配器、匹配器组合(一种通过转换匹配器来重用匹配器的简单方法)、精确的失败、长字符串的详细差异、.. .

  • Mockito 在规范中得到了很好的 BDD 支持:Mockito

  • specs 有数据表,它允许在一个表中分组很多小例子(如果你能忍受运算符被用作表分隔符)

  • 在规范中,您可以定义嵌套为 libidum 并在每个级别自动清理的示例

这当然是一个非常片面和有偏见的比较,并且存在许多其他差异(并且库仍在发展,......)。

归根结底,我认为这实际上取决于您的测试/指定风格。如果它很简单(简单的规范结构、设置、期望等),那么这两个库将看起来非常相似。否则,双方都对应该如何做事有自己的看法。作为最后一个示例,您可以查看标记:在ScalaTestspecs中。

我希望这有帮助。

于 2010-02-10T14:16:28.350 回答
5

据我所知,除了一些高度专业化的功能外,这取决于风格的个人喜好。

于 2010-02-08T16:06:37.270 回答
2

IDE支持可能是另一点

我一直试图让 Specs 通过 JUnit 与 Eclipse 一起工作,我发现官方解决方案有点“hacky”。规格设置:http ://code.google.com/p/specs/wiki/RunningSpecs#Run_your_specification_with_JUnit4_in_Eclipse

ScalaTest 的集成(也通过 JUnit)似乎不那么老套了。尽管如此,我还没有让它们中的任何一个像 JUnit 和 Java 一样工作。

ScalaTest 设置:http ://groups.google.com/group/scalatest-users/web/running-scalatest-from-eclipse

于 2010-09-16T22:00:14.920 回答
0

如果一个决定因素是编译时间,scalatest 似乎表现更好。

我们目前在我们的项目中使用 specs2,但在测试中编译时间很慢。我刚刚完成了关于迁移到 scalatest 的 POC,仅通过在我们的一些源代码中切换 2 个框架,编译时间就下降了大约 0.82 倍。

于 2015-12-15T11:29:58.990 回答