两者都是用 Scala 编写的支持 BDD (行为驱动开发)的 Scala 单元测试框架。而 眼镜 是建立在也可能涉及到 ScalaTest框架。但是 Specs 提供了哪些 ScalaTest 没有的东西呢?有什么区别吗?
据我所知,除了一些高度专业化的功能,它归结为个人喜好根据风格。
主要的区别是(主要从规格的角度来看: ——) :
ScalaTest 提供了比 specs 更多的“测试样式”(您可以访问 动作快点页面上的每个项目符号点,以获得每种样式的详细视图)
ScalaTest 和 specs 有一组不同的匹配器。您可以比较它们在 ScalaTest 中的 给你和在 specs 中的 给你。在这方面,specs 有很多你在编写规范时可能会喜欢的小特性: xml 匹配器、匹配器组合(一种通过转换来重用匹配器的简单方法)、精确失败、长字符串的详细差异... ..。
Mockito 已经在规范中得到了很好的 BDD 支持: 莫基托
Specs 有 数据表,它允许将大量的小示例分组到一种表中(如果你可以容忍操作符被用作表分隔符的话)
在规范中,您可以定义在每个级别嵌套为 libidum 和 automatically cleaned-up的示例
This is certainly a very partial and biased comparison and many other differences exist (and the libraries are still evolving, ...).
最后,我认为这真的取决于您的测试/指定风格。如果它很简单(简单的规范结构、设置、期望... ...) ,那么两个库看起来就非常相似。否则,两者都会对事情应该如何进行有各自的看法。作为这方面的最后一个例子,您可以看一下标记: 在 ScalaTest和 规格中。
希望这个能帮上忙。
Specs 和 ScalaTest 都是用户满意的好工具,但它们在几个方面有所不同。您可能希望选择其中一个作为 Scala 中的主要测试工具,但是不必放弃另一个,因为您可以同时使用这两个工具的各个部分。例如,如果您喜欢 ScalaTest 的 FeatureSpec语法和 specs 的 Mockito 语法,那么您可以将这两个 jar 文件放在您的类路径中,并同时使用它们。在这里,我将尝试并捕捉我注意到 specs 和 ScalaTest 之间的主要设计哲学差异。
FeatureSpec
这两个工具在哲学上的主要区别可能在于 specs 是为行为驱动开发(bDD)设计的,而 ScalaTest 更为通用。ScalaTest 提供了一些特性,您可以将这些特性混合在一起,以获得您在测试类中喜欢的行为,包括 BDD,如果您想要一些不同的东西,您还可以轻松地定义自己的行为。
ScalaTest 通过它的 Spec、 FeatureSpec、 WordSpec、 FlatSpec和 GivenWhenThen特性来支持 BDD,并且还有一些特性可以混合使用以获得一个很好的匹配器语法。如果你喜欢“应该”,你可以加入“应该匹配者”。如果你喜欢“必须”,你混合在 MustMatchers。但是如果您喜欢 BDD 但是不喜欢 matcher 语法,那么您可以只使用 ScalaTest 的 Spec trait 中的一个,而不需要混合使用 matcher trait。Specs 有一个您可以扩展的规范类,您必须在匹配器表达式中使用单词“ must”。一个很大的哲学差异在这里很明显,那就是 ScalaTest 给了你更多的选择。为了使这个选择空间更容易导航,我在这里提供了一个决策树:
Spec
WordSpec
FlatSpec
GivenWhenThen
MustMatchers
Http://www.scalatest.org/quick_start
在 ScalaTest 和 specs 之间,matcher 语法也是不同的。在 ScalaTest 中,我试图看看运算符表示法能走多远,最后得到的匹配表达式读起来非常像英语句子,单词之间有空格。Specs matcher 语法将单词更多地与驼峰大小写一起运行。
Specs 比 ScalaTest 有更多的匹配器,我认为这反映了设计态度的不同。我实际上删除了大约2/3我构建并考虑发布的 matcher 语法。我将在未来的版本中添加更多的匹配器,但是我想在添加之前确保我知道用户真正想要的东西。然而,ScalaTest 的匹配器包含一个动态属性匹配器语法来弥补这一缺陷。例如,在 Specs 中,你可以在 java.io.File上写:
java.io.File
file must beDirectory
这将调用 isDirectory并确保它为 true。ScalaTest 目前没有任何针对 java.io.Files的特殊匹配器,但是在 ScalaTest,你可以像这样使用一个动态检查:
isDirectory
java.io.Files
file must be a ('directory)
在 be之后传入符号时,它将使用反射来查找(在本例中)名为 directory的方法或字段或名为 isDirectory的方法。还有一种静态化的方法,定义一个 BePropertyMatcher(通常只需要2到3行代码)。所以基本上在 ScalaTest 中,我尝试用更少的 API 提供更多的功能。
be
directory
BePropertyMatcher
Specs 和 ScalaTest 之间的另一个通用设计态度差异 包含隐式转换。默认情况下,当您使用 ScalaTest 时,您只能获得一个隐式转换,即对所有内容都使用 ===运算符的转换。(如果需要,可以用一行代码“关闭”这个隐式转换。您需要这样做的唯一原因是,如果您试图测试具有自己的 ===操作符的内容,那么您将得到一个冲突。)ScalaTest 定义了许多其他的隐式转换,但是要使用它们,您需要通过混合 trait 或执行导入来显式地“邀请”它们进入您的代码。当你在 specs 中扩展类 Specification的时候,我认为默认情况下你会得到几十个隐式转换。我不确定这在实践中会有多大影响,但我认为人们会想要测试使用他们自己隐含的代码,而且有时候在测试框架的隐含和生产代码的隐含之间可能会有冲突。当这种情况发生时,我认为在 ScalaTest 中解决这个问题可能比在 specs 中更容易。
===
Specification
另一个不同的设计态度,我已经注意到是与操作员的舒适度。我的一个目标是,任何程序员在查看使用 ScalaTest 的其他人的测试代码时,都能够猜出其含义,而无需在 ScalaTest 文档中查找任何东西。我希望 ScalaTest 客户端代码非常明显。这个目标的一个体现就是 ScalaTest 对于操作符非常保守。我在 ScalaTest 中只定义了5个运算符:
>
<
>=
<=
就是这样。所以这些东西看起来很像是什么意思。如果你在别人的代码中看到:
result should be <= 7
我希望您不需要运行 API 文档来猜测 <=的含义。相比之下,使用操作符的 specs 要自由得多。这没什么不对,但这是不同的。操作符可以使代码更简洁,但是折中的做法是,当您在同事的测试代码中发现诸如 ->-、 >>、 |、 |>、 !或 ^^^(这些代码在 Specs 中都有特殊含义)之类的内容时,您可能必须运行文档。
->-
>>
|
|>
!
^^^
另一个哲学上的不同之处在于,当你需要共享一个 fixture 时,我确实尝试在 ScalaTest 中使用函数式样式稍微容易一些,而 Specs 在默认情况下延续了由 JUnit 推广的 setUp和 tearDown方法的传统,在每次测试前重新分配 vars。然而,如果你想用这种方式进行测试,在 ScalaTest 中也是非常容易的。你只需要融入 BeforeAndAfter特性。
setUp
tearDown
BeforeAndAfter
想要更深入地了解 ScalaTest,你可以看看我在2009年 Devoxx 会议上的演讲“ Get Higher with ScalaTest”:
http://parleys.com/play/514892260364bc17fc56bde3/chapter0/about
IDE 支持可能是另一个要点
我一直试图通过 JUnit 让 Specs 与 Eclipse 一起工作,我发现官方解决方案有点“古怪”。规格设置: 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
如果一个决策因素是编译时间,则 Scalatest 似乎表现得更好。
我们目前在项目中使用 specs2,但是在测试中遇到了编译速度慢的问题。我刚刚完成了一个关于移动到 scalatest 的 POC,通过切换一些源代码中的两个框架,我看到编译时间下降了大约0.82倍。