在游戏框架中进行 运行 测试时如何应用游戏进化?
How to apply play-evolutions when running tests in play-framework?
当 运行ning 在游戏框架中使用
进行测试时,我遇到了进化问题
- 适用于 scala 的 playframework v2.6.6
- play-slick v3.0.2
- play-slick-evolutions v3.0.2
测试看起来像这样:
class TestFooController extends PlaySpec with GuiceOneServerPerSuite {
"foo endpoint should store some data" in {
val wsClient = app.injector.instanceOf[WSClient]
val url = s"http://localhost:$port/foo"
val requestData = Json.obj("foo" -> "bar")
val response = await(wsClient.url(url).post(requestData))
response.status mustBe OK
}
}
数据库配置如下所示:
slick.dbs.default.driver="slick.driver.H2Driver$"
slick.dbs.default.db.driver="org.h2.Driver"
slick.dbs.default.db.url="jdbc:h2:mem:play"
假设有一个可以创建 table foos
的进化脚本,并且该脚本在开发模式下运行良好。
当运行测试时抛出以下错误:
play.api.http.HttpErrorHandlerExceptions$$anon: Execution exception[[JdbcSQLException: Table "foos" not found;
无法找到 table foos
,因此我假设尚未应用数据库演化。
然后我将数据库配置更改为开发模式下使用的postgresql。
slick.dbs.default.driver = "slick.driver.PostgresDriver$"
slick.dbs.default.db.driver = "org.postgresql.Driver"
slick.dbs.default.db.url = "jdbc:postgresql://localhost:5432/foo-test"
slick.dbs.default.db.user = "user"
slick.dbs.default.db.password = "password"
使用此配置,测试工作正常,数据存储在数据库中,因此数据库演化 运行 就好了。
现在的问题是,测试后没有清理数据库。我想 运行 每个测试套件都有一个干净的数据库。
总结一下。不应用 H2Db 演化,应用 postgresql 演化但不清理。
即使这在 application.test.conf
中明确定义
play.evolutions.autoApply=true
play.evolutions.autoApplyDowns=true
我也试过了
play.evolutions.db.default.autoApply=true
play.evolutions.db.default.autoApplyDowns=true
没有效果。
然后我尝试通过以下方式手动执行此操作:
def withManagedDatabase[T](block: Database => T): Unit = {
val dbapi = app.injector.instanceOf[DBApi]
val database = dbapi.database("default")
Evolutions.applyEvolutions(database)
block(database)
Evolutions.cleanupEvolutions(database)
}
然后将测试更改为:
"foo endpoint should store some data" in withManagedDatabase { _ =>
...
}
对于H2数据库配置没有效果,同样会抛出table foos
找不到的错误。对于 postgresql 数据库配置,抛出一个进化异常
play.api.db.evolutions.InconsistentDatabase: Database 'default' is in an inconsistent state![An evolution has not been applied properly. Please check the problem and resolve it manually before marking it as resolved.]
我想要在每个测试套件之前进行升级 运行ning,在之后进行升级 运行ning。如何实现?
这对我有用:
class DAOSpec extends PlaySpec with GuiceOneAppPerSuite {
val dbUrl = sys.env.getOrElse("DATABASE_URL", "postgres://foo:password@localhost:5432/foo")
val testConfig = Map("db.default.url" -> dbUrl)
implicit override def fakeApplication() = new GuiceApplicationBuilder().configure(testConfig).build()
lazy val database = app.injector.instanceOf[Database]
lazy val dao = app.injector.instanceOf[DAO]
"create" must {
"work" in Evolutions.withEvolutions(database) {
val foo = await(dao.create("foo"))
foo.id must not be null
}
}
}
您可以使用以下方法在每个套件之前应用进化并在之后进行清理:
trait DatabaseSupport extends BeforeAndAfterAll {
this: Suite with ServerProvider =>
private lazy val db = app.injector.instanceOf[DBApi]
override protected def beforeAll(): Unit = {
super.beforeAll()
initializeEvolutions(db.database("default"))
}
override protected def afterAll(): Unit = {
cleanupEvolutions(db.database("default"))
super.afterAll()
}
private def initializeEvolutions(database: Database):Unit = {
Evolutions.cleanupEvolutions(database)
Evolutions.applyEvolutions(database)
}
private def cleanupEvolutions(database: Database):Unit = {
Evolutions.cleanupEvolutions(database)
}
}
当 运行ning 在游戏框架中使用
进行测试时,我遇到了进化问题- 适用于 scala 的 playframework v2.6.6
- play-slick v3.0.2
- play-slick-evolutions v3.0.2
测试看起来像这样:
class TestFooController extends PlaySpec with GuiceOneServerPerSuite {
"foo endpoint should store some data" in {
val wsClient = app.injector.instanceOf[WSClient]
val url = s"http://localhost:$port/foo"
val requestData = Json.obj("foo" -> "bar")
val response = await(wsClient.url(url).post(requestData))
response.status mustBe OK
}
}
数据库配置如下所示:
slick.dbs.default.driver="slick.driver.H2Driver$"
slick.dbs.default.db.driver="org.h2.Driver"
slick.dbs.default.db.url="jdbc:h2:mem:play"
假设有一个可以创建 table foos
的进化脚本,并且该脚本在开发模式下运行良好。
当运行测试时抛出以下错误:
play.api.http.HttpErrorHandlerExceptions$$anon: Execution exception[[JdbcSQLException: Table "foos" not found;
无法找到 table foos
,因此我假设尚未应用数据库演化。
然后我将数据库配置更改为开发模式下使用的postgresql。
slick.dbs.default.driver = "slick.driver.PostgresDriver$"
slick.dbs.default.db.driver = "org.postgresql.Driver"
slick.dbs.default.db.url = "jdbc:postgresql://localhost:5432/foo-test"
slick.dbs.default.db.user = "user"
slick.dbs.default.db.password = "password"
使用此配置,测试工作正常,数据存储在数据库中,因此数据库演化 运行 就好了。
现在的问题是,测试后没有清理数据库。我想 运行 每个测试套件都有一个干净的数据库。
总结一下。不应用 H2Db 演化,应用 postgresql 演化但不清理。
即使这在 application.test.conf
play.evolutions.autoApply=true
play.evolutions.autoApplyDowns=true
我也试过了
play.evolutions.db.default.autoApply=true
play.evolutions.db.default.autoApplyDowns=true
没有效果。
然后我尝试通过以下方式手动执行此操作:
def withManagedDatabase[T](block: Database => T): Unit = {
val dbapi = app.injector.instanceOf[DBApi]
val database = dbapi.database("default")
Evolutions.applyEvolutions(database)
block(database)
Evolutions.cleanupEvolutions(database)
}
然后将测试更改为:
"foo endpoint should store some data" in withManagedDatabase { _ =>
...
}
对于H2数据库配置没有效果,同样会抛出table foos
找不到的错误。对于 postgresql 数据库配置,抛出一个进化异常
play.api.db.evolutions.InconsistentDatabase: Database 'default' is in an inconsistent state![An evolution has not been applied properly. Please check the problem and resolve it manually before marking it as resolved.]
我想要在每个测试套件之前进行升级 运行ning,在之后进行升级 运行ning。如何实现?
这对我有用:
class DAOSpec extends PlaySpec with GuiceOneAppPerSuite {
val dbUrl = sys.env.getOrElse("DATABASE_URL", "postgres://foo:password@localhost:5432/foo")
val testConfig = Map("db.default.url" -> dbUrl)
implicit override def fakeApplication() = new GuiceApplicationBuilder().configure(testConfig).build()
lazy val database = app.injector.instanceOf[Database]
lazy val dao = app.injector.instanceOf[DAO]
"create" must {
"work" in Evolutions.withEvolutions(database) {
val foo = await(dao.create("foo"))
foo.id must not be null
}
}
}
您可以使用以下方法在每个套件之前应用进化并在之后进行清理:
trait DatabaseSupport extends BeforeAndAfterAll {
this: Suite with ServerProvider =>
private lazy val db = app.injector.instanceOf[DBApi]
override protected def beforeAll(): Unit = {
super.beforeAll()
initializeEvolutions(db.database("default"))
}
override protected def afterAll(): Unit = {
cleanupEvolutions(db.database("default"))
super.afterAll()
}
private def initializeEvolutions(database: Database):Unit = {
Evolutions.cleanupEvolutions(database)
Evolutions.applyEvolutions(database)
}
private def cleanupEvolutions(database: Database):Unit = {
Evolutions.cleanupEvolutions(database)
}
}