为每个测试使用不同的内存数据库 运行
Use different in-memory database for every test run
我有一个 Play 应用程序,其中包含一些涉及数据库的测试。为此,我将 Slick 配置为在测试 运行s 期间使用单独的内存中 H2 实例,例如:
slick.dbs.default.db.url="jdbc:h2:mem:play-test"
现在,ScalaTest 并行执行套件,这通常不成问题,因为会为每个套件重新创建 Play 应用程序。但是,它们都接触同一个数据库,可能会导致意外状态并导致测试失败。
在 运行 本地时运行良好,但在 CI 服务器上失败,日志表明测试执行顺序不同,如果不是并行,这本身应该不是问题,但是一次测试开始时的数据库状态不符合预期。
现在,我的一个解决方案是 运行 这些套件依次使用 Sequential
。
但在我看来,如果仍然能够并行 运行 它们会更好,但是使用不同的数据库,例如:
slick.dbs.default.db.url="jdbc:h2:mem:play-test-${UUID.generate()}"
以上语法完全是编造的,但是 Play 配置文件是否支持 UUID(或其他一些随机字符串)生成?
多亏了,我最终创建了一个特征,用随机后缀自定义我的内存 H2 名称:
trait FreshDatabase extends GuiceOneAppPerSuite {
this: TestSuite =>
val BaseName = "play-test"
val UrlConfigKey = "slick.dbs.default.db.url"
override def fakeApplication(): Application = {
val defaultUrl = super.fakeApplication().configuration.get[String](UrlConfigKey)
val random = Random.nextInt(Integer.MAX_VALUE)
val freshUrl = defaultUrl.replace(BaseName, s"$BaseName-$random")
GuiceApplicationBuilder().configure(UrlConfigKey -> freshUrl).build()
}
}
然后在相关的测试套件中使用它,例如:
class AnswerControllerSpec extends PlaySpec
with GuiceOneAppPerSuite with FreshDatabase {
// ...
}
我的application.conf
(和以前一样):
slick.dbs.default.profile="slick.jdbc.H2Profile$"
slick.dbs.default.db.driver="org.h2.Driver"
slick.dbs.default.db.url="jdbc:h2:mem:play-test"
我有一个 Play 应用程序,其中包含一些涉及数据库的测试。为此,我将 Slick 配置为在测试 运行s 期间使用单独的内存中 H2 实例,例如:
slick.dbs.default.db.url="jdbc:h2:mem:play-test"
现在,ScalaTest 并行执行套件,这通常不成问题,因为会为每个套件重新创建 Play 应用程序。但是,它们都接触同一个数据库,可能会导致意外状态并导致测试失败。
在 运行 本地时运行良好,但在 CI 服务器上失败,日志表明测试执行顺序不同,如果不是并行,这本身应该不是问题,但是一次测试开始时的数据库状态不符合预期。
现在,我的一个解决方案是 运行 这些套件依次使用 Sequential
。
但在我看来,如果仍然能够并行 运行 它们会更好,但是使用不同的数据库,例如:
slick.dbs.default.db.url="jdbc:h2:mem:play-test-${UUID.generate()}"
以上语法完全是编造的,但是 Play 配置文件是否支持 UUID(或其他一些随机字符串)生成?
多亏了
trait FreshDatabase extends GuiceOneAppPerSuite {
this: TestSuite =>
val BaseName = "play-test"
val UrlConfigKey = "slick.dbs.default.db.url"
override def fakeApplication(): Application = {
val defaultUrl = super.fakeApplication().configuration.get[String](UrlConfigKey)
val random = Random.nextInt(Integer.MAX_VALUE)
val freshUrl = defaultUrl.replace(BaseName, s"$BaseName-$random")
GuiceApplicationBuilder().configure(UrlConfigKey -> freshUrl).build()
}
}
然后在相关的测试套件中使用它,例如:
class AnswerControllerSpec extends PlaySpec
with GuiceOneAppPerSuite with FreshDatabase {
// ...
}
我的application.conf
(和以前一样):
slick.dbs.default.profile="slick.jdbc.H2Profile$"
slick.dbs.default.db.driver="org.h2.Driver"
slick.dbs.default.db.url="jdbc:h2:mem:play-test"