如何为功能测试的每个示例创建测试夹具
How to create test fixtures for every example of a functional test
这里是 Scala 菜鸟。
我目前尝试使用 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
案例 class 的示例设置和拆卸方法,用适当的数据填充它并保留其中的一些数据,以便该示例可以从定义的数据库状态开始。
最终我想要一个插件机制,其中插件为一组示例定义测试数据(将其视为贷款模式的应用)。
到目前为止我做了什么:
- 我尝试使用
Around
的某种风格,但我不知道如何将数据输入到示例中,因为我必须添加额外的 return 值。
- 我尝试了 specs2 的 ForEach 上下文,但这与 Play 的 WithBrowser 冲突
- 我玩过隐式 val,但我还是不知道如何使用
DelayedInit
将隐式参数添加到从构造函数转换为函数调用参数的块中
有什么想法可以继续实现以下目标吗?
- 从附加特征扩展规范或示例或 class 使用单个参数调用示例
TestData
- 这个额外的特征或 class 应该能够准备测试数据并保留其中的一部分
- 此附加特征或 class 应与
WithBrowser
兼容
一种方法是使用所谓的 "loan fixtures":
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)
}
}
等..
一种解决方案如下:
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._
为代价的,但这也避免了先前解决方案的双重嵌套。
这里是 Scala 菜鸟。
我目前尝试使用 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
案例 class 的示例设置和拆卸方法,用适当的数据填充它并保留其中的一些数据,以便该示例可以从定义的数据库状态开始。
最终我想要一个插件机制,其中插件为一组示例定义测试数据(将其视为贷款模式的应用)。
到目前为止我做了什么:
- 我尝试使用
Around
的某种风格,但我不知道如何将数据输入到示例中,因为我必须添加额外的 return 值。 - 我尝试了 specs2 的 ForEach 上下文,但这与 Play 的 WithBrowser 冲突
- 我玩过隐式 val,但我还是不知道如何使用
DelayedInit
将隐式参数添加到从构造函数转换为函数调用参数的块中
有什么想法可以继续实现以下目标吗?
- 从附加特征扩展规范或示例或 class 使用单个参数调用示例
TestData
- 这个额外的特征或 class 应该能够准备测试数据并保留其中的一部分
- 此附加特征或 class 应与
WithBrowser
兼容
一种方法是使用所谓的 "loan fixtures":
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)
}
}
等..
一种解决方案如下:
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._
为代价的,但这也避免了先前解决方案的双重嵌套。