Java 테스트의 Docker 테스트 컨테이너

1. 소개

이 튜토리얼에서는 Java TestContainers 라이브러리를 살펴볼 것 입니다. 이를 통해 테스트 내에서 Docker 컨테이너를 사용할 수 있습니다. 결과적으로 외부 리소스에 의존하는 자체 통합 테스트를 작성할 수 있습니다.

Docker 이미지가있는 테스트에서 모든 리소스를 사용할 수 있습니다. 예를 들어 데이터베이스, 웹 브라우저, 웹 서버 및 메시지 대기열에 대한 이미지가 있습니다. 따라서 테스트 내에서 컨테이너로 실행할 수 있습니다.

2. 요구 사항

TestContainers 라이브러리는 Java 8 이상에서 사용할 수 있습니다. 또한 JUnit Rules API와 호환됩니다.

먼저 핵심 기능에 대한 Maven 종속성을 정의 해 보겠습니다.

 org.testcontainers testcontainers 1.11.4 

특수 컨테이너 용 모듈도 있습니다. 이 튜토리얼에서는 PostgreSQLSelenium을 사용 합니다 .

관련 종속성을 추가해 보겠습니다.

 org.testcontainers postgresql  1.11.4   org.testcontainers selenium  1.11.4 

Maven Central에서 최신 버전을 찾을 수 있습니다.

또한 컨테이너를 실행하려면 Docker가 필요합니다 . 설치 지침은 Docker 설명서를 참조하십시오.

테스트 환경에서 Docker 컨테이너를 실행할 수 있는지 확인하십시오.

3. 사용법

일반 컨테이너 규칙을 구성 해 보겠습니다.

@ClassRule public static GenericContainer simpleWebServer = new GenericContainer("alpine:3.2") .withExposedPorts(80) .withCommand("/bin/sh", "-c", "while true; do echo " + "\"HTTP/1.1 200 OK\n\nHello World!\" | nc -l -p 80; done");

Docker 이미지 이름을 지정 하여 GenericContainer 테스트 규칙을 구성합니다 . 그런 다음 빌더 메소드로 구성합니다.

  • withExposedPorts 를 사용 하여 컨테이너에서 포트를 노출합니다.
  • withCommand 는 컨테이너 명령을 정의합니다. 컨테이너가 시작될 때 실행됩니다.

규칙은 @ClassRule 로 주석 처리됩니다 . 결과적으로 해당 클래스의 테스트가 실행되기 전에 Docker 컨테이너를 시작합니다 . 모든 메서드가 실행 된 후 컨테이너가 삭제됩니다.

@Rule 주석 을 적용하면 GenericContainer 규칙은 각 테스트 메서드에 대해 새 컨테이너를 시작합니다. 그리고 해당 테스트 방법이 완료되면 컨테이너를 중지합니다.

IP 주소와 포트를 사용하여 컨테이너에서 실행되는 프로세스와 통신 할 수 있습니다 .

@Test public void givenSimpleWebServerContainer_whenGetReuqest_thenReturnsResponse() throws Exception { String address = "//" + simpleWebServer.getContainerIpAddress() + ":" + simpleWebServer.getMappedPort(80); String response = simpleGetRequest(address); assertEquals(response, "Hello World!"); }

4. 사용 모드

테스트 컨테이너 에는 여러 가지 사용 모드 가 있습니다. GenericContainer 를 실행하는 예를 보았습니다 .

TestContainers 라이브러리에는 특수 기능이있는 규칙 정의도 있습니다. MySQL, PostgreSQL과 같은 공통 데이터베이스의 컨테이너 용입니다. 그리고 웹 클라이언트와 같은 다른 사람들.

일반 컨테이너로 실행할 수 있지만 전문화는 확장 된 편의 방법을 제공합니다.

4.1. 데이터베이스

데이터 액세스 계층 통합 테스트를 위해 데이터베이스 서버가 필요하다고 가정 해 보겠습니다. TestContainers 라이브러리의 도움으로 컨테이너에서 데이터베이스를 실행할 수 있습니다.

예를 들어 PostgreSQLContainer 규칙을 사용 하여 PostgreSQL 컨테이너를 시작 합니다 . 그런 다음 도우미 메서드를 사용할 수 있습니다. 이들은 getJdbcUrl getUserName 메서드 이후, getPassword를 데이터베이스 연결을 위해 :

@Rule public PostgreSQLContainer postgresContainer = new PostgreSQLContainer(); @Test public void whenSelectQueryExecuted_thenResulstsReturned() throws Exception { String jdbcUrl = postgresContainer.getJdbcUrl(); String username = postgresContainer.getUsername(); String password = postgresContainer.getPassword(); Connection conn = DriverManager .getConnection(jdbcUrl, username, password); ResultSet resultSet = conn.createStatement().executeQuery("SELECT 1"); resultSet.next(); int result = resultSet.getInt(1); assertEquals(1, result); }

PostgreSQL을 일반 컨테이너로 실행할 수도 있습니다. 그러나 연결을 구성하는 것이 더 어려울 것입니다.

4.2. 웹 드라이버

또 다른 유용한 시나리오는 웹 브라우저로 컨테이너를 실행하는 것입니다. BrowserWebDriverContainer 규칙을 사용하면 docker-selenium 컨테이너 에서 ChromeFirefox 를 실행할 수 있습니다 . 그런 다음 RemoteWebDriver로 관리합니다 .

이것은 웹 애플리케이션의 UI / 수락 테스트를 자동화하는 데 매우 유용합니다.

@Rule public BrowserWebDriverContainer chrome = new BrowserWebDriverContainer() .withCapabilities(new ChromeOptions()); @Test public void whenNavigatedToPage_thenHeadingIsInThePage() { RemoteWebDriver driver = chrome.getWebDriver(); driver.get("//example.com"); String heading = driver.findElement(By.xpath("/html/body/div/h1")) .getText(); assertEquals("Example Domain", heading); }

4.3. Docker 작성

테스트에 더 복잡한 서비스가 필요한 경우 docker-compose 파일 에 지정할 수 있습니다.

simpleWebServer: image: alpine:3.2 command: ["/bin/sh", "-c", "while true; do echo 'HTTP/1.1 200 OK\n\nHello World!' | nc -l -p 80; done"]

그런 다음 DockerComposeContainer 규칙 을 사용 합니다. 이 규칙은 compose 파일에 정의 된대로 서비스를 시작하고 실행합니다.

우리는 사용 getServiceHostgetServicePost 서비스에 빌드 접속 주소 방법 :

@ClassRule public static DockerComposeContainer compose = new DockerComposeContainer( new File("src/test/resources/test-compose.yml")) .withExposedService("simpleWebServer_1", 80); @Test public void givenSimpleWebServerContainer_whenGetReuqest_thenReturnsResponse() throws Exception { String address = "//" + compose.getServiceHost("simpleWebServer_1", 80) + ":" + compose.getServicePort("simpleWebServer_1", 80); String response = simpleGetRequest(address); assertEquals(response, "Hello World"); }

5. 결론

TestContainers 라이브러리를 어떻게 사용할 수 있는지 보았습니다 . 통합 테스트를 쉽게 개발하고 실행할 수 있습니다.

주어진 도커 이미지의 컨테이너에 GenericContainer 규칙을 사용했습니다 . 그런 다음 PostgreSQLContainer, BrowserWebDriverContainerDockerComposeContainer 규칙을 살펴 보았습니다 . 특정 사용 사례에 대해 더 많은 기능을 제공합니다.

마지막으로 여기에있는 코드 샘플은 GitHub에서 찾을 수 있습니다.