【问题标题】:Start testcontainers before Playframework starts up在 Playframework 启动之前启动测试容器
【发布时间】:2020-05-23 20:45:28
【问题描述】:

我想在播放应用程序(使用 slick)启动之前从 docker-compose 文件(postgres 和 kafka 实例)启动测试容器。我想要这个,所以我可以写一个端到端的测试。我似乎无法弄清楚 Play 是如何实现的。

import java.io.File
import com.dimafeng.testcontainers.DockerComposeContainer.ComposeFile
import com.dimafeng.testcontainers.{DockerComposeContainer, ForAllTestContainer}
import com.typesafe.config.ConfigFactory
import org.scalatest.{BeforeAndAfterAll, FunSpec}
import org.scalatestplus.play.guice.GuiceFakeApplicationFactory
import play.api.inject.guice.GuiceApplicationBuilder
import play.api.{Application, Configuration, Environment, Mode}

trait TestFunSpec extends FunSpec with BeforeAndAfterAll with GuiceFakeApplicationFactory {

  override def fakeApplication(): Application = new GuiceApplicationBuilder()
    .in(Environment(new File("."), getClass.getClassLoader, Mode.Test))
    .loadConfig(_ => Configuration(ConfigFactory.load("test.conf")))
    .build

}

class TestIntegrationSpec extends TestFunSpec with ForAllTestContainer {

  override val container = DockerComposeContainer(ComposeFile(Left(new File("docker-compose.yml"))))

  it("should test something") {

    assert(true)

  }
}

Scala 版本 2.12.10 测试容器版本 0.35.0 玩 slick 版本 5.0.0

当我在没有“TestFunSpec”的情况下执行测试时,docker-compose 会正确启动我的服务。当我在范围内添加播放应用程序“TestFunSpec”时,该应用程序会尝试启动,这样做时,它会尝试与尚不存在的 postgres 连接(因为之后会启动测试容器)。

提前谢谢。

更新:详细答案请参见答案部分。

【问题讨论】:

  • 你想在所有测试用例之前还是在每个测试用例之前启动它?
  • 播放应用程序启动前。所以,在所有测试用例初始化之前。

标签: scala playframework scalatest testcontainers


【解决方案1】:

在深入了解 Play 测试套件机制后,我想出了一个可行的设置。

第 1 步,使用 AppProvider 定义您的测试容器套件:

import com.dimafeng.testcontainers.{Container, ForAllTestContainer}
import org.scalatest.Suite
import org.scalatestplus.play.AppProvider

trait PlayTestContainer extends Suite with AppProvider with ForAllTestContainer {

  override val container: Container

}

第 2 步,创建一个抽象的 PlayTestContainerIntegrationSpec 扩展上述特征:

import java.io.File
import com.typesafe.config.ConfigFactory
import org.scalatest.concurrent.{IntegrationPatience, ScalaFutures}
import org.scalatest.{BeforeAndAfterAll, BeforeAndAfterEach, TestData}
import org.scalatestplus.play.PlaySpec
import org.scalatestplus.play.guice.GuiceOneAppPerTest
import play.api.inject.guice.GuiceApplicationBuilder
import play.api.{Application, Configuration, Environment, Mode}

abstract class PlayTestContainerIntegrationSpec
    extends PlaySpec
    with PlayTestContainer
    with GuiceOneAppPerTest
    with ScalaFutures
    with IntegrationPatience
    with BeforeAndAfterEach
    with BeforeAndAfterAll {

  override def newAppForTest(testData: TestData): Application = application()

  def application(): Application =
    new GuiceApplicationBuilder()
      .in(Environment(new File("."), getClass.getClassLoader, Mode.Test))
      .loadConfig(_ => Configuration(ConfigFactory.load("test.conf")))
      .build
}

如您所见,我们包含“PlayTestContainer”特征并覆盖“newAppForTest”函数以构建播放应用程序。

第 3 步,创建特定的集成测试,扩展上述抽象 PlayTestContainerIntegrationSpec,并根据您的特定需要覆盖容器:

class TestIntegrationSpec extends PlayTestContainerIntegrationSpec {

  override val container = DockerComposeContainer(ComposeFile(Left(new File("docker-compose.yml"))))

  "should test something" in {

    assert(true === true)

  }
}

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-10
    • 2020-02-18
    • 2014-10-10
    • 1970-01-01
    • 2018-01-14
    • 1970-01-01
    相关资源
    最近更新 更多