2013-11-24 23 views
0

为了避免X &Ÿ问题,一点背景:生成ScalaCheck测试与黄瓜JVM - 通用功能

我试图建立我要去哪里要复制的业务逻辑服务器和客户端的Web项目侧面,客户端明显在JavaScript和服务器在斯卡拉。我打算在黄瓜编写业务逻辑,以便确保测试和功能在双方上线。最后,我想要将ScalaCheck和JSCheck引入到这个生成的输入数据而不是指定的地方。

基本上,报表会的工作是这样的:

鉴于报表选择添加发电机。 当语句指定函数按顺序对这些值进行操作时。 然后语句将输入数据和最终结果数据并运行属性。

目标是使这种事情可组合,因此您可以指定几个生成器,一组操作在它们中的每一个上运行,然后是一组属性,每组都可以在输入和结果上运行。

已经在Javascript(技术上讲是Coffeescript)中完成了这一点,当然用动态语言也很简单。基本上我希望能够在我的阶步的定义做的就是这一点,原谅任意的测试数据:

class CucumberSteps extends ScalaDsl with EN 
        with ShouldMatchers with QuickCheckCucumberSteps { 
    Given("""^an list of integer between 0 and 100$""") { 
    addGenerator(Gen.containerOf[List, Int](Gen.choose(0,100))) 
    } 
    Given("""^an list of random string int 500 and 700$""") { 
    addGenerator(Gen.containerOf[List, Int](Gen.choose(500,700))) 
    } 

    When("""^we concatenate the two lists$""") { 
    addAction {(l1: List[Int], l2: List[Int]) => l1 ::: l2 } 
    } 

    Then("""^then the size of the result should equal the sum of the input sizes$""") { 
    runProperty { (inputs: (List[Int], List[Int]), result: (List[Int])) => 
     inputs._1.size + inputs._2.size == result._1.size 
    } 
    } 
} 

所以我想要做的关键是建立一个特点QuickCheckCucumberSteps,这将是API,实现addGenerator,addAction和runProperty。

这是我到目前为止已经草拟出来了,和我卡住:

trait QuickCheckCucumberSteps extends ShouldMatchers { 

    private var generators = ArrayBuffer[Gen[Any]]() 
    private var actions = ArrayBuffer[""AnyFunction""]() 

    def addGenerator(newGen: Gen[Any]): Unit = 
    generators += newGen 

    def addAction(newFun: => ""AnyFunction""): Unit = 
    actions += newFun 

    def buildPartialProp = { 
    val li = generators 
    generators.length match { 
     case 1 => forAll(li(0))_ 
     case 2 => forAll(li(0), li(1))_ 
     case 3 => forAll(li(0), li(1), li(2))_ 
     case 4 => forAll(li(0), li(1), li(2), li(3))_ 
     case _ => forAll(li(0), li(1), li(2), li(3), li(4))_ 
    } 
    } 

    def runProperty(propertyFunc: => Any): Prop = { 
    val partial = buildPartialProp 
    val property = partial { 

     ??? // Need a function that takes x number of generator inputs, 
      // applies each action in sequence 
      // and then applies the `propertyFunc` to the 
      // inputs and results. 
    } 

    val result = Test.check(new Test.Parameters.Default {}, 
          property) 

    result.status match { 
     case Passed => println("passed all tests") 
     case Failed(a, l) => fail(format(pretty(result), "", "", 75)) 
     case _ => println("other cases") 
    } 
    } 
} 

我的关键问题是这样的,我想有注释块变成一个函数,所有添加的动作,按顺序应用它们,然后运行并返回属性函数的结果。这是否可以用Scala的类型系统来表达,如果可以,我该如何开始?乐于阅读并获得这个奖励,但我至少需要一条前进的道路,因为我现在不知道如何表达它。如果我想在这里做的不清楚,很高兴在我的Javascript代码中放入。

回答

0

如果我是你,我不会把ScalaCheck生成器代码放在你的黄瓜Given/When/Then语句中:)。 ScalaCheck API调用是“测试平台”的一部分 - 所以不在测试中。试试这个(不编译/测试):

class CucumberSteps extends ScalaDsl with EN with ShouldMatchers { 
    forAll(Gen.containerOf[List, Int](Gen.choose(0,100)), 
     Gen.containerOf[List, Int](Gen.choose(500,700))) 
     ((l1: List[Int], l2: List[Int]) => { 
      var result: Int = 0 
      Given(s"""^a list of integer between 0 and 100: $l1 $""") { } 
      Given(s"""^a list of integer between 0 and 100: $l2 $""") { } 
      When("""^we concatenate the two lists$""") { result = l1 ::: l2 } 
      Then("""^the size of the result should equal the sum of the input sizes$""") { 
      l1.size + l2.size == result.size } 
     }) 
} 
+0

如果我这样做,似乎没有任何目的,我甚至不打算用黄瓜作为发电机首先打扰。我不妨在这一点上用手写下它,而不用为抽象而烦恼。我已经通过硬编码测试了这种方法,并且黄瓜的属性断言也很好。缺少的链接是我想通过允许将一堆函数组合到一个属性中创建的抽象。 – MalucoMarinero

+0

Cuc是一个框架,而不是一个生成器。 (+使用案例/需求/测试代码库,状态仪表板)。 BDD流程:概念 - >规格 - >测试定义 - >代码 - >验证 - >验证。 Cuc管理第2步到(大部分)5.规范仍然可以用纯文本编写,可能由BA/PM(不需要考虑ScalaCheck)。测试定义向代码添加代码,但预先放置ScalaCheck数据。提供BDD和测试数据生成的全部好处。至于抽象堆栈的测试函数 - 不在Q中?任何工具都需要代码/配置定义 - 简单的解决方案:调用实用程序测试fns(带有级联的位置)。 –