Запустите тестконтейнеры до запуска Playframework - PullRequest
0 голосов
/ 07 февраля 2020

Я хочу запустить testcontainers из docker -композитного файла (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 Testcontainer версия 0.35.0 Play slick версия 5.0.0

Когда я выполняю тест без "TestFunSpe c", docker -композиция правильно раскручивает мои сервисы. Когда я добавляю приложение воспроизведения «TestFunSpe c» в область действия, приложение пытается выполнить запуск, при этом оно пытается соединиться с postgres, который еще не существует (так как тестовые контейнеры запускаются впоследствии).

Спасибо заранее.

Обновление: подробный ответ см. В разделе ответов.

1 Ответ

0 голосов
/ 09 февраля 2020

После некоторого глубокого погружения в механизм набора тестов 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, создайте абстрактный PlayTestContainerIntegrationSpe c, который расширяет вышеупомянутую черту:

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» для конструирования игры application.

Шаг 3, создайте специальный интеграционный тест c, расширьте вышеупомянутый абстрактный PlayTestContainerIntegrationSpe c и переопределите контейнер, указав c необходимость:

class TestIntegrationSpec extends PlayTestContainerIntegrationSpec {

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

  "should test something" in {

    assert(true === true)

  }
}

Надеюсь, это поможет.

...