如何为功能测试的每个示例创建测试装置

时间:2019-01-06 13:19:02

标签: scala playframework functional-testing specs2

这里是scala noob。

我目前正在尝试使用specs2为基于Play(Scala)的Web应用程序创建功能测试。示例本身很简单,即:

class SignInSpec extends PlaySpecification {

  // bring the workflow steps in scope and instrument browser with them    
  import utils.WorkflowSteps.AuthSteps

  "An activated user".should {
    "be able to sign in to the admin console" in new WithDbData(webDriver = WebDriverFactory(FIREFOX)) {

      // this should be: browser.signIn(testData.manager)
      // with the manager already persisted in the database
      browser.signIn(Manager(None, "me@home.com", "12341234", "John", "Doe", List("admin")))
    }
  }
}

我想要实现的是为每个示例提供一组定义的测试数据,其中一些数据已经保存在数据库中。因此,我需要一个围绕每个示例的设置和拆卸方法,以准备一个TestData案例类,并用适当的数据填充并保留其中的一些数据,以便该示例可以从定义的数据库状态开始。 最终,我需要一种插件机制,其中插件定义了一组示例的测试数据(可以将其视为借用模式的应用)。

我到目前为止所做的:

  • 我尝试使用Around的某种形式,但是我不知道如何将数据输入示例中,因为我必须添加其他返回值。
  • 我尝试了specs2的ForEach上下文,但这与Play的WithBrowser冲突
  • 我玩过隐式val,但是我也不知道如何向使用DelayedInit从构造函数转换为函数调用参数的块中添加隐式参数

有什么想法可以实现以下目标吗?

  • 从附加特征或类中扩展规范或示例,该特征或类使用单个参数TestData来调用示例
  • 此附加特征或类应该能够准备测试数据并保留其中的一部分
  • 此附加特征或类别应与WithBrowser兼容

2 个答案:

答案 0 :(得分:0)

一种方法是使用所谓的“贷款装置”:

     def withTestData(test: TestData => Unit) = {
       val data = setupTestData() 
       try { 
         test(data)
       } finally {
         destroyTestData(data)
       }
     }



    "An activated user" should "be able to sign in to the admin console" in withTestData { data =>
       new WithDbData(webDriver = WebDriverFactory(FIREFOX)) {
         browser.signIn(data.manager)
       }
     }

等..

答案 1 :(得分:0)

以下是一种解决方案:

 case class TestData(manager: Manager) extends WithDbData(webDriver = WebDriverFactory(FIREFOX))


 class SignInSpec extends PlaySpecification with ForEach[TestData] {

   // bring the workflow steps in scope and instrument browser with them    
   import utils.WorkflowSteps.AuthSteps

   "An activated user".should {
     "be able to sign in to the admin console" in { data: TestData =>
        import data._

        browser.signIn(manager)
     }
   }

   def foreach[R : AsResult](f: TestData => R): Result = ???
 }

这是以必须import data._为代价的,但这也避免了先前解决方案的双重嵌套。