当前位置: 首页 > 工具软件 > Scala Check > 使用案例 >

ScaTDD:关注Scala中的三个主要测试框架

田博远
2023-12-01
传统上,测试一直是许多Java商店进行Scala开发门户过程,这些商店希望以最小的中断或投入来发展其技术堆栈。 这篇文章希望通过经典的FizzBu​​zz测试示例涵盖 Scala环境中的三个主要测试框架Specs2ScalatestScalacheck ),以介绍如何将它们用于娱乐和盈利。 因此,FizzBu​​zz要求的简要概述是给定的数字序列:
  • 任何可被3整除的数字应返回字符串“ Fizz”
  • 任何可被5整除的数字应返回字符串“ Buzz”
  • 任何可以被3和5整除的数字都应返回字符串“ FizzBu​​zz”
  • 否则,数字应作为字符串返回

作为比较,我还为此提供了一个示例Java JUnit测试 。 实际的实现代码(包括在此处) 是微不足道的(部分是设计使然),因为它只是为了说明所使用的库。

为此,我的设置是使用Windows 7上的Eclipse v3.7.2和Scala IDE v2.0.1.v-2_09插件以及Scala 2.9.0.1版。

规格2

简而言之

  • 一个按规范编写单元和验收测试的元框架。 支持并发执行,嘲讽,报告scalatest和scalacheck功能的支持, 数据表风格的测试和基于形式规范的测试。 该项目来自最初(现已不推荐使用)的Scala Specs BDD测试框架。

链接

http://etorreborre.github.com/specs2/

v2.9.2_v1.10

Ohloh

http://www.ohloh.net/p/specs2

活跃社区

是的 。该项目于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清晰易用,并且喜欢将测试与评估为支持或反驳的表达式分开。 真好

比较

RSpecJBehaveeasyb本能JUnit
<
标尺

简而言之

  • Java和Scala的通用框架,它使用各种特征来混合许多不同的测试样式和策略。 开箱即用,支持TDD,BDD,功能,集成TestNG和JUnit测试。

链接

http://www.scalatest.org/

版本 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团队在第一次就开始运行。

比较

JUnit的TestNG的

标量

简而言之

  • 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快速检查JUnit 快速检查

结论

总之,与我以前在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

 类似资料: