是否可以使用Cucumber-jvm Scala避免可变状态?

时间:2013-01-18 18:32:46

标签: scala cucumber-jvm

使用Cucumber测试时,表示为GivenWhenThen的功能通常实现为三种不同的方法。这些方法通常需要共享值,这似乎是可变变量的实现方式。

采用以下简单示例:

功能:

Given the digit 2
When it is multiplied by 3
Then the result is 6

黄瓜方法:

class CucumberRunner extends ScalaDsl with EN with ShouldMatchers {

  var digitUnderTest: Int = -1

  Given("""^the digit (\d)$""") { digit: Int =>
    digitUnderTest = digit
  }

  When("""^it is multiplied by 3$""") {
    digitUnderTest = digitUnderTest * 3
  }

  Then("""^the result is (\d)$""") { result: Int =>
    digitUnderTest should equal (result)
  }
}

是否有任何方法,可能是内置于Scala测试或Cucumber-jvm for Scala,允许我不将digitUnderTest表示为可变变量?

2 个答案:

答案 0 :(得分:2)

查看javascala中的cucumber-jvm示例,我怀疑它提供了一种方法,可以将数据从一步传递到另一步,而不会暂时将其存储在变量中。

由于你无法在scala中重新分配val,我能想到的最接近可变var的东西就是拥有一个包含临时测试数据的全局地图。

class CucumberRunner extends ScalaDsl with EN with ShouldMatchers {

  Given("""^the digit (\d)$""") { digit: Int =>
    GlobalTestData.save("my_unique_key_1", digit)
  }

  When("""^it is multiplied by 3$""") {
    GlobalTestData.load("my_unique_key_1") match {
      case Some(obj) => {
        val result = obj.asInstanceOf[Int] * 3
        GlobalTestData.save("my_unique_key_2", result)
      }
      case None => // throw exception or fail test
    }
  }

  Then("""^the result is (\d)$""") { result: Int =>
    GlobalTestData.load("my_unique_key_2") match {
      case Some(obj) => obj.asInstanceOf[Int] should equal (result)
      case None => // throw exception or fail test
    }
  }
}

然后是GlobalTestData

object GlobalTestData {
  val map = scala.collection.mutable.Map.empty[String, Any];

  def save(key: String, value: Any) {
    map.put(key, value)
  }

  def load(key: String): Option[Any] = map.get(key)
}

在这种情况下,您需要仔细生成密钥,以便它们在各个步骤中相同。当然,您可以使用一些val来保存这些键的值。

同样在此特定功能中,为什么不合并GivenWhen步骤:

When the digit 2 is multiplied by 3
Then the result is 6

这样您就可以在GlobalTestData中保存一个广告位。

答案 1 :(得分:0)

虽然在ScalaDSL for CucumberJVM中,步骤是函数f:List[Any] => Anycurrent implementation会丢弃每一步执行的结果,这意味着您无法使用上一步的结果下一个。

目前,分享一步结果的唯一方法是通过一些共享状态,在步骤定义类或更全局的上下文,如zihaoyu建议 (顺便说一句,我们在大型项目中也使用共享的可变映射方法)