两者都是用Scala编写的针对Scala的BDD(行为驱动开发)功能单元测试框架。基于Specs 构建的还可能涉及ScalaTest框架。但是Specs提供的ScalaTest没有提供什么?有什么区别?
两者都是用Scala编写的针对Scala的BDD(行为驱动开发)功能单元测试框架。基于Specs 构建的还可能涉及ScalaTest框架。但是Specs提供的ScalaTest没有提供什么?有什么区别?
Answers:
Specs和ScalaTest都是用户满意的好工具,但是它们在几个方面有所不同。您可能希望在Scala中选择一个作为主要测试工具,但不必放弃另一个,因为您可以同时使用两者。例如,如果您喜欢ScalaTest的FeatureSpec
语法和规范的Mockito语法,则可以将这两个jar文件都放在类路径中,并同时使用它们。在这里,我将尝试捕捉规格和ScalaTest之间我注意到的主要设计哲学差异。
这些工具之间的主要哲学差异可能是规范是针对行为驱动开发(BDD)设计的,而ScalaTest更通用。ScalaTest提供的特征可以混合在一起以在测试类(包括BDD)中获得您喜欢的行为,并且如果您想要不同的东西,也可以轻松定义自己的行为。
ScalaTest支持BDD通过Spec
,FeatureSpec
,WordSpec
,FlatSpec
,和GivenWhenThen
特质,也有特点,你可以混合在得到一个不错的匹配的语法。如果您喜欢“应该”,则可以混合使用ShouldMatchers。如果您喜欢“必须”,请混入MustMatchers
。但是,如果您喜欢BDD但不喜欢匹配器语法,则可以仅使用ScalaTest的Spec特质之一,而无需混合匹配器特质。Specs具有扩展的Specification类,您必须在匹配表达式中使用单词“ must”。从这里可以明显看出,在哲学上的一个很大差异是ScalaTest为您提供了更多选择。为了使选择的空间更易于浏览,我在此处提供了一个决策树:
http://www.scalatest.org/quick_start
ScalaTest和spec之间的匹配器语法也有所不同。在ScalaTest中,我试图查看使用运算符表示法可以走多远,最后得到的匹配表达式读起来非常像英语句子,单词之间留有空格。Specs匹配器语法将更多单词与驼峰式一起使用。
Specs比ScalaTest具有更多的匹配器,我认为这反映了设计态度的不同。实际上,我实际上削减了我构建并考虑发布的匹配器语法的2/3。我将在以后的版本中添加更多匹配器,但想确保在添加之前,我知道用户确实想要一些东西。但是,ScalaTest的匹配器包括一个动态属性匹配器语法,可以弥补其中的一些不足。例如,在规格中,您可以在上编写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提供更多功能。
规格和ScalaTest之间的另一个一般设计态度差异涉及隐式转换。默认情况下,当您使用ScalaTest时,您只会获得一次隐式转换,这是使===
运算符处理所有事情的转换。(如果需要,您可以用一行代码“关闭”这种隐式转换。您需要这样做的唯一原因是,如果您尝试测试具有自己的===
运算符的东西,则会发生冲突。 )ScalaTest定义了许多其他隐式转换,但是要使用它们,您需要通过混入特征或进行导入来将它们“显式”邀请到您的代码中。上课时Specification
在规范中,我认为您默认情况下会获得数十个隐式转换。我不确定在实践中有多少重要,但是我认为人们会想要测试使用自己的隐式代码的代码,有时测试框架的隐式代码与生产代码的隐式代码之间可能会发生冲突。当发生这种情况时,我认为在ScalaTest中解决该问题可能比使用规范更容易。
我注意到的设计态度的另一个差异是操作员的舒适度。我的一个目标是,只要程序员查看别人的使用ScalaTest的测试代码,都可以在不查找ScalaTest文档的情况下猜测其含义。我希望ScalaTest客户端代码变得显而易见。目标本身体现的一种方式是,ScalaTest对运算符非常保守。我只在ScalaTest中定义了五个运算符:
===
,等于>
,表示大于<
, 少于>=
,大于或等于<=
,小于或等于。而已。因此,这些东西看起来很像什么意思。如果您在别人的代码中看到:
result should be <= 7
我的希望是,您无需运行API文档即可猜测其<=
含义。相比之下,运营商可以自由选择规格。没什么错,但这是有区别的。运营商可以使代码更简洁,但代价是你可能需要运行的文件,当你找到的东西一样 ->-
,>>
,|
,|>
,!
,或^^^
(这都在规格特殊的含义)在你同事的测试代码。
另一个哲学上的区别是,当您需要共享固定装置时,我确实尝试使ScalaTest中的功能样式更容易使用,而Specs默认情况下延续了JUnit流行的setUp
and tearDown
方法的传统,其中您重新分配了vars每次测试之前。但是,如果您想以这种方式进行测试,则在ScalaTest中也非常容易。您只需要混合BeforeAndAfter
特征。
有关ScalaTest的更多信息,您可以在以下2009年Devoxx会议上观看“ ScalaTest进阶”演讲:
http://parleys.com/play/514892260364bc17fc56bde3/chapter0/about
主要区别是(主要是从规格的角度来看:-)):
ScalaTest提供了比规范更多的“测试样式”(您可以在快速入门页上访问每个要点以获得每种样式的详细视图)
ScalaTest和规范具有一组不同的匹配器。您可以在这里比较它们的ScalaTest和此处的规格。在这方面,规范具有很多小功能,您在编写规范时可能会喜欢:xml匹配器,匹配器组成(通过转换匹配器来重用匹配器的简便方法),精确的故障,长字符串的详细区别等.. 。
Mockito在规格方面得到了很好的BDD支持:Mockito
specs拥有DataTables,可以将许多小的示例组合在一个表中(如果您可以将运算符用作表定界符)
在规范中,您可以定义嵌套为libidum的示例,并在每个级别自动清除
当然,这是一个非常局部且有偏差的比较,并且存在许多其他差异(并且库仍在不断发展……)。
归根结底,我认为这实际上取决于您的测试/指定样式。如果很简单(简单的规范结构,设置,期望等),那么这两个库将看起来非常相似。否则,他们俩都应该如何做。作为最后一个示例,您可以看看ScalaTest和specs中的 tagging :。
我希望这有帮助。
据我所知,除了一些高度专业化的功能,它取决于样式的个人喜好。
IDE支持可能是另一点
我一直试图通过JUnit使Specs与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
如果一个决定因素是编译时间,那么scalatest的性能似乎更好。
我们目前在我们的项目中使用specs2,但是在测试中编译速度很慢。我刚刚完成了转向scalatest的POC,仅通过切换某些源中的两个框架,即可看到编译时间减少了约0.82倍。