2012-01-10 93 views
3

我已经得到了以下类,我想写一些Spec测试用例,但我真的很陌生,我不知道如何开始。我的班级喜欢这样:斯卡拉规格单元测试

class Board{ 

    val array = Array.fill(7)(Array.fill(6)(None:Option[Coin])) 

    def move(x:Int, coin:Coin) { 
    val y = array(x).indexOf(None) 
    require(y >= 0) 
    array(x)(y) = Some(coin) 
    } 

    def apply(x: Int, y: Int):Option[Coin] = 
    if (0 <= x && x < 7 && 0 <= y && y < 6) array(x)(y) 
    else None 

    def winner: Option[Coin] = winner(Cross).orElse(winner(Naught)) 

    private def winner(coin:Coin):Option[Coin] = { 
    val rows = (0 until 6).map(y => (0 until 7).map(x => apply(x,y))) 
    val cols = (0 until 7).map(x => (0 until 6).map(y => apply(x,y))) 
    val dia1 = (0 until 4).map(x => (0 until 6).map(y => apply(x+y,y))) 
    val dia2 = (3 until 7).map(x => (0 until 6).map(y => apply(x-y,y))) 

    val slice = List.fill(4)(Some(coin)) 
    if((rows ++ cols ++ dia1 ++ dia2).exists(_.containsSlice(slice))) 
     Some(coin) 
    else None 
    } 

    override def toString = { 
    val string = new StringBuilder 
    for(y <- 5 to 0 by -1; x <- 0 to 6){ 
     string.append(apply(x, y).getOrElse("_")) 
     if (x == 6) string.append ("\n") 
     else string.append("|") 
    } 
    string.append("0 1 2 3 4 5 6\n").toString 
    } 
} 

谢谢!

+1

您可以查看specs2的文档:http://etorreborre.github.com/specs2/ – 2012-01-10 15:10:13

+0

假设您查看了specs2文档。考虑到你的Board类,你想通过编写测试来确认你的代码的行为如你所期望的那样通过调用方法并检查状态或返回值是否如你所期望的那样。看看这里的一些例子https://github.com/mongodb/casbah/tree/master/casbah-gridfs/src/test/scala另请看这个视频http://www.youtube.com/watch?v = lMyNRUuEvNU – foolshat 2012-01-10 15:26:33

+0

谢谢,我看了一下,但还是不明白!你可以给我一个板级的例子吗? class BoardSpec扩展SpecificationWithJUnit { } – user1137701 2012-01-10 15:39:14

回答

-1

我建议你把所有的代码都扔出去 - 好吧,保存在某个地方,但是使用TDD从零开始。

Specs2网站有很多关于如何编写测试的例子,但是使用TDD - 测试驱动设计 - 来做到这一点。至少可以说,在事实之后添加测试并不理想。

因此,想想你想要处理的最简单的功能最简单的情况,写一个测试,看到它失败,编写代码来修复它。必要时重构,并重复下一个最简单的情况。

如果您需要一般TDD的帮助,我衷心赞同Clean Coders上提供的有关TDD的视频。至少,请看第二部分,鲍勃·马丁写下了从设计到结束的全班TDD风格。

如果您知道如何进行一般测试但对Scala或Specs感到困惑,请更具体地了解您的问题。

+0

事情是我不能扔掉那个代码...这个porgram正在工作,但我需要一些测试用例 – user1137701 2012-01-10 15:48:25

+0

@ user1137701如果你要成为一名程序员,最好习惯扔掉代码并重做它。上面的类很小,重写所有它应该很容易。但是,做你想做的事情。我不会改变我的建议,因为你不需要它。 – 2012-01-10 19:29:17

4

我只能用丹尼尔的建议,因为使用TDD最终会得到更实用的API。

我也认为你的应用程序可以很好地测试specs2和ScalaCheck的混合。这里一个规范的草案,让你开始:

import org.specs2._ 
    import org.scalacheck.{Arbitrary, Gen} 

    class TestSpec extends Specification with ScalaCheck { def is = 

    "moving a coin in a column moves the coin to the nearest empty slot" ! e1^ 
    "a coin wins if"             ^
     "a row contains 4 consecutive coins"        ! e2^ 
     "a column contains 4 consecutive coins"       ! e3^ 
     "a diagonal contains 4 consecutive coins"       ! e4^ 
                     end 

    def e1 = check { (b: Board, x: Int, c: Coin) => 
     try { b.move(x, c) } catch { case e =>() } 
     // either there was a coin before somewhere in that column 
     // or there is now after the move 
     (0 until 6).exists(y => b(x, y).isDefined) 
    } 

    def e2 = pending 
    def e3 = pending 
    def e4 = pending 

    /** 
    * Random data for Coins, x position and Board 
    */ 
    implicit def arbitraryCoin: Arbitrary[Coin]  = Arbitrary { Gen.oneOf(Cross,  Naught) } 
    implicit def arbitraryXPosition: Arbitrary[Int] = Arbitrary { Gen.choose(0, 6) } 
    implicit def arbitraryBoardMove: Arbitrary[(Int, Coin)] = Arbitrary { 
     for { 
     coin <- arbitraryCoin.arbitrary 
     x <- arbitraryXPosition.arbitrary 
     } yield (x, coin) 
    } 
    implicit def arbitraryBoard: Arbitrary[Board] = Arbitrary { 
     for { 
     moves <- Gen.listOf1(arbitraryBoardMove.arbitrary) 
     } yield { 
     val board = new Board 
     moves.foreach { case (x, coin) => 
      try { board.move(x, coin) } catch { case e =>() }} 
      board 
     } 
    } 


    } 

    object Cross extends Coin { 
    override def toString = "x" 
    } 
    object Naught extends Coin { 
    override def toString = "o" 
    } 
    sealed trait Coin 

e1财产我实现是不是真实的东西,因为它并没有真正检查我们感动的硬币到最近空插槽,这就是你的代码和API的建议。您还需要更改生成的数据,以便生成交替xo的板。这应该是学习如何使用ScalaCheck的好方法!

+0

嗨Eric,非常感谢!我如何开始这段代码?我试图运行JUNIT-Test,但是然后得到结果,没有发现JUNIT测试 – user1137701 2012-01-11 11:07:48

+0

我正在使用直接支持specs2的Intellij。如果你使用的是eclipse,你需要扩展org.specs2.SpecificationWithJUnit(如果这不起作用,你需要添加@RunWith(classOf [JUnitRunner])注解(JUnitRunner在org.specs2中。亚军包)) – Eric 2012-01-11 20:49:21

+0

嘿埃里克,我试图用这个,但然后得到这个错误:java.lang.ClassCastException:TestSpec不能转换为org.scalatest.Suite – user1137701 2012-01-17 11:58:41