我想要的是使用相同的数据库引擎,与生产中相同的进化和配置来运行我的测试.我的db是PostgreSQL 9.4,我使用Slick 3.0.0来访问它.
而这里的问题:
>在并行测试执行的情况下,我在同一个数据库上同时运行了几个演进.这会导致错误.
>在顺序测试执行的情况下,线程池有另一个错误.
这里的细节.
我使用evolutions为每个测试初始化db.为此,我准备了一个基本规范类:
class DatabaseSpecification extends PlaySpecification {
protected val defaultAppBuilder =
new GuiceApplicationBuilder()
.configure(ConfigurationLoader.loadFirst("application.test.override.conf", "application.test.conf"))
protected def afterEach(app: Application) = {
recreateDbSchema(app)
}
private def recreateDbSchema(app: Application) = {
val dbConfig = DatabaseConfigProvider.get[JdbcProfile](app)
import dbConfig.driver.api._
val recreateSchema: DBIO[Unit] = DBIO.seq(
sqlu"drop schema public cascade",
sqlu"create schema public"
)
Await.ready(dbConfig.db.run(recreateSchema), 5 seconds)
}
abstract class DatabaseContext() extends WithApplication(defaultAppBuilder.build()) {
protected val injector = implicitApp.injector
override def around[T](t: => T)(implicit evidence$2: AsResult[T]): Result = super.around {
try {
t
} finally {
afterEach(implicitApp)
}
}
}
}
其中application.test.override.conf是测试的配置文件.
还有祖先规范中的几个测试:
"save1 and query" in new DatabaseContext {
// create new user
val accountRepo = injector.instanceOf[SystemUserRepo]
val user = new SystemUser(id = 0, login = "admin", passwordHash = "", role = Role.Administrator)
val futureUserId = accountRepo.create(user)
// check if user id is greater then zero
val userId = await(futureUserId)(5 second)
userId must be_>(0)
}
"second one1" in new DatabaseContext {
1 mustEqual 1
}
如果我并行运行整个规范的测试(默认),那么获取异常数据库’default’处于不一致状态![演变尚未正确应用.请检查问题并手动解决,然后再将其标记为已解决.]
@ 6mk338l87:数据库’default’处于不一致状态!在其中一个测试中.
如果我运行它,顺序类AccountRepositoryTest扩展DatabaseSpecification {sequential …}会出现另一个异常
Task slick.backend.DatabaseComponent$DatabaseDef$$anon$2@2744dcae rejected from java.util.concurrent.ThreadPoolExecutor@16d0e521[Terminated, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 3]
java.util.concurrent.RejectedExecutionException: Task slick.backend.DatabaseComponent$DatabaseDef$$anon$2@2744dcae rejected from java.util.concurrent.ThreadPoolExecutor@16d0e521[Terminated, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 3]
at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2047)
at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:823)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1369)
at scala.concurrent.impl.ExecutionContextImpl$$anon$1.execute(ExecutionContextImpl.scala:136)
at slick.backend.DatabaseComponent$DatabaseDef$class.runSynchronousDatabaseAction(DatabaseComponent.scala:224)
at slick.jdbc.JdbcBackend$DatabaseDef.runSynchronousDatabaseAction(JdbcBackend.scala:38)
at slick.backend.DatabaseComponent$DatabaseDef$class.runInContext(DatabaseComponent.scala:201)
at slick.jdbc.JdbcBackend$DatabaseDef.runInContext(JdbcBackend.scala:38)
at slick.backend.DatabaseComponent$DatabaseDef$class.runInternal(DatabaseComponent.scala:75)
at slick.jdbc.JdbcBackend$DatabaseDef.runInternal(JdbcBackend.scala:38)
at slick.backend.DatabaseComponent$DatabaseDef$class.run(DatabaseComponent.scala:72)
at slick.jdbc.JdbcBackend$DatabaseDef.run(JdbcBackend.scala:38)
at repository.GenericCRUD$class.create(GenericCRUD.scala:50)
at repository.GenericCRUDImpl.create(GenericCRUD.scala:70)
at unit.repositories.AccountRepositoryTest$$anonfun$3$$anon$1.delayedEndpoint$unit$repositories$AccountRepositoryTest$$anonfun$3$$anon$1$1(AccountRepositoryTest.scala:39)
at unit.repositories.AccountRepositoryTest$$anonfun$3$$anon$1$delayedInit$body.apply(AccountRepositoryTest.scala:35)
它发生在第val行futureUserId = accountRepo.create(用户)上.可悲的是,我不知道为什么第二个例外会抛出.顺便说一下,我当然喜欢并行运行测试,但不知道如何实现它.
任何帮助,将不胜感激!
最佳答案 目前您应该使用顺序运行数据库测试,否则它将失败.
线程池错误来自:
protected val defaultAppBuilder =
new GuiceApplicationBuilder()
.configure(ConfigurationLoader.loadFirst("application.test.override.conf", "application.test.conf"))
它应该是一个功能:
protected def defaultAppBuilder =
new GuiceApplicationBuilder()
.configure(ConfigurationLoader.loadFirst("application.test.override.conf", "application.test.conf"))
然后它将开始工作.我们这样做,但是我们有抽象类,它有一个val应用程序,我们可以配置东西和def应用程序,它只会做一个def app = application.build(),这样我们仍然可以扩展GuiceApplictionBuilder.
目前我首先遇到了同样的错误,你肯定不希望每次测试都重复使用相同的应用程序.
所以尝试一下,你有一个非常好的功能测试套件用于游戏应用程序.
然而,我们唯一不做的是公共放弃模式,我们依靠进化来通过清理来解决这个问题.如果他们错了,我们会立即看到错误.