- 任何可被3整除的数字应返回字符串“ Fizz”
- 任何可被5整除的数字应返回字符串“ Buzz”
- 任何可以被3和5整除的数字都应返回字符串“ FizzBuzz”
- 否则,数字应作为字符串返回
作为比较,我还为此提供了一个示例Java JUnit测试 。 实际的实现代码(包括在此处) 是微不足道的(部分是设计使然),因为它只是为了说明所使用的库。
为此,我的设置是使用Windows 7上的Eclipse v3.7.2和Scala IDE v2.0.1.v-2_09插件以及Scala 2.9.0.1版。
- 一个按规范编写单元和验收测试的元框架。 支持并发执行,嘲讽,报告scalatest和scalacheck功能的支持, 数据表风格的测试和基于形式规范的测试。 该项目来自最初(现已不推荐使用)的Scala Specs BDD测试框架。
链接
http://etorreborre.github.com/specs2/
版
v2.9.2_v1.10
Ohloh
活跃社区
是的 。该项目于2007年中期以Specs(v1)的形式启动,随后在2010年演变为Specs2的更通用的框架。该项目有许多提交者(尽管主要由Eric Torreborre推动),并支持诸如Google Group,该项目的博客和企业支持。
例
package org.scalabound.scatdd.specs2
import org.scalabound.scatdd.FizzBuzz
import org.junit.runner.RunWith
import org.specs2.runner.JUnitRunner
// package unitTest { |> Scala IDE will not pick the class up as runnable if I sub-package it like this :-(
@RunWith(classOf[JUnitRunner])
class FizzBuzzJUnitSpec extends org.specs2.mutable.Specification {
"Multiples of both three and five" should {
"print 'FizzBuzz'" in { FizzBuzz.eval(15) must_== "FizzBuzz" }
}
"Multiples of three only" should {
"print 'Fizz'" in { FizzBuzz.eval(12) must_== "Fizz" }
}
"Multiples of five only" should {
"print 'Buzz'" in { FizzBuzz.eval(10) must_== "Buzz" }
}
"Non multiples of five or three" should {
"print the number back" in { FizzBuzz.eval(11) must_== "11" }
}
}
// package acceptanceTest { |> Scala IDE will not pick the class up as runnable if I sub-package it like this :-(
@RunWith(classOf[JUnitRunner])
class FizzBuzzUATSpec extends org.specs2.Specification { def is =
"This specification is to check the FizzBuzz evaluator" ^
p^
"The FizzBuzz evaluator should" ^
"process a multiple of both three and five to return FizzBuzz" ! e1^
"process a multiple of three only to return Fizz" ! e2^
"process a multiple of five only to return Buzz" ! e3^
"process a non multiple of three or five to return the input" ! e4^
end
def e1 = FizzBuzz.eval(15) must_== "FizzBuzz"
def e2 = FizzBuzz.eval(12) must_== "Fizz"
def e3 = FizzBuzz.eval(10) must_== "Buzz"
def e4 = FizzBuzz.eval(11) must_== "11"
}
@RunWith(classOf[JUnitRunner])
class FizzBuzzDataTableSpec extends org.specs2.Specification with org.specs2.matcher.DataTables { def is =
"Fizz Buzz testing with DataTables" ! e1
// note: when the first column of a DataTable is a String, '!!' needs to be used instead of '!'
// see: http://etorreborre.github.com/specs2/guide/org.specs2.guide.Matchers.html#DataTables
def e1 =
"spec name" || "input val" | "expected output" |
"Multiple of both three and five" !! 15 ! "FizzBuzz" |
"Multiple of three only" !! 12 ! "Fizz" |
"Multiple of five only" !! 10 ! "Buzz" |
"Non multiple of five or three" !! 11 ! "11" |> {
(a, b, c) => FizzBuzz.eval(b) must_== c // (a, b, c) is a structural match on the table
}
}
反馈
通常,我遇到的痛点是使用Scala IDE而不是Specs2。 具体来说,我本来希望在同一源文件中包含不同类型的测试,但要通过不同的子包来区分它们。 不幸的是,Scala IDE并未拾取子软件包,因此这不是入门。 一个小怪异的事情是无法重新排列我对DataTable规范测试的论据。
更新 :感谢Eric Torreborre ,使用!!解决了这个问题! 代替! 当字符串类型用于数据表的第一列时! 虽然这是一个小麻烦。
否则,Specs 2看起来很成熟,并具有良好的工具支持,很可能会成为我选择的“包装”测试框架。 我发现规范的默认API清晰易用,并且喜欢将测试与评估为支持或反驳的表达式分开。 真好
比较
RSpec , JBehave , easyb , 本能 , JUnit
<
标尺
简而言之
- Java和Scala的通用框架,它使用各种特征来混合许多不同的测试样式和策略。 开箱即用,支持TDD,BDD,功能,集成TestNG和JUnit测试。
链接
版本 v1.7.2
Ohloh
http://www.ohloh.net/p/scalatest
活跃社区
是的 。 这是Bill Venners在2001年从名为SuiteRunner的项目中衍生出来的第二代框架。通过以下网址可以访问维护活跃的论坛组:http://www.scalatest.org/community
例
package org.scalabound.scatdd.scalatest
import org.junit.runner.RunWith
import org.scalatest.FunSpec
import org.scalatest.junit.JUnitRunner
import org.scalabound.scatdd.FizzBuzz
@RunWith(classOf[JUnitRunner])
class FizzBuzzScalaTest extends FunSpec {
describe('A FizzBuzz processor') {
it('should return 'FizzBuzz' from a mulitple of three and five') { assert(FizzBuzz.eval(15) == 'FizzBuzz') }
it('should return 'Fizz' from a multiple of three only') { assert(FizzBuzz.eval(12) == 'Fizz') }
it('should return 'Buzz' from a multiple of five only') { assert(FizzBuzz.eval(10) == 'Buzz') }
it('should return the stringified input from a non multiple of three or five') { assert(FizzBuzz.eval(11) == '11') }
}
}
反馈
我只使用了一种规格类型,看起来既清晰又简洁。 该API所规定的语言( describe..it .. )非常简单,在第一个站点上一点也不尴尬。 我还希望测试和断言之间有一个更清晰的区别(这是个人喜好)。 尽管如此,仍然很难找到一个更简单,更“友好”的框架来使Java团队在第一次就开始运行。
比较
标量
简而言之
- Scala和Java的基于规范的测试生成框架。 该库最初是由Haskell中的QuickCheck启发的。
链接
https://github.com/rickynils/scalacheck#readme
版
v2.9.0-1-1.9
Ohloh
http://www.ohloh.net/p/scalacheck
活跃社区
是的 ,但主要源于里卡德·尼尔森(Rickard Nilsson)。 该项目似乎没有任何论坛支持。
更新:感谢@Daniel索布拉尔存在(实际上)一个谷歌组,支持ScalaCheck的在这里 !
例
package org.scalabound.scatdd.scalacheck
import org.scalabound.scatdd.FizzBuzz
import org.scalacheck.ConsoleReporter.testReport
import org.scalacheck.Prop.forAll
import org.scalacheck.Prop.propBoolean
import org.scalacheck.ConsoleReporter
import org.scalacheck.Test
object FizzBuzzScalaCheck {
val propFizzBuzzCheck = forAll { n: Int =>{
if(n % 15 == 0) FizzBuzz.eval(n) == 'FizzBuzz'
else if(n % 3 ==0) FizzBuzz.eval(n) == 'Fizz'
else if(n % 5 ==0) FizzBuzz.eval(n) == 'Buzz'
else '' + n == FizzBuzz.eval(n)
}
}
def main(args : Array[String] ) = {
ConsoleReporter.testStatsEx('blah', testReport(Test.check(propFizzBuzzCheck)))
}
}
反馈与其他框架相比,该框架花了我一段时间才能开始运行(请记住,虽然我在几分钟之内就与其他框架一起运行了!)。 我痛苦的主要根源是:
- 没有明显的现成的 JUnit支持
- 我最初是作为Scala应用程序(即对App进行了扩展的东西)运行测试的,尽管不断
GenException(java.lang.NullPointerException)from the ConsoleReporter whenever I tried to run my tests.
- 每当我尝试向隐含运算符添加太多条件时,我发现生成的测试不足以验证我的属性(因此,我呈现的示例有些笨拙 )。
说了这么多,我仍然觉得这个框架是独特的,确实很有价值。 在几次测试运行中,我记录了生成的输入,Scalacheck确实很棒(生成和传递的输入范围相当大)。 这可能是三个框架中最具挑战性的框架,但同时也提供了我当然想一次又一次使用的功能。 下次我可能会通过Specs运行它!
比较
结论
总之,与我以前在Java中亲自使用的比较框架相比,所有这三个框架都更加清晰(或更具表达力)。 如果我想让一个团队“逃避” Scala,我会选择ScalaTest。 如果我与一个对Scala稍微满意的团队一起工作,我会选择Specs2路线。 无论如何,我都会尝试使用ScalaCheck进行测试生成(尽管最好通过其他框架之一将其抽象化)。 无论哪种方式,我都可以理解为什么使用Scala测试框架有助于在团队中摇摆观点,以使团队朝着企业中的Scala迈进。 我希望此反馈有用且不要太干。 与以往一样,最好的“验证”是您自己走这条路(除非ScalaCheck会为您做这件事!)。 祝您的TDD一切顺利,并祝您黑客愉快!
参考: ScaTDD:我们的JCG合作伙伴 Kingsley Davies在Scalabound博客上关注了Scala中的三个主要测试框架 。
翻译自: https://www.javacodegeeks.com/2012/05/scatdd-casting-eye-over-three-major.html