통합 테스트 Dockerize
어떤 경우, 우리는 이 구성 요소를 간단하게 모의하거나, 테스트 실행 기간에 메모리에 구성 요소를 만들 수 있다.예를 들어 H2 ouHSQLDB은 메모리에 있는 데이터베이스로 통합 테스트 기간에 사용하기로 유명하다.그러나 생산 환경에서 사용하는 테스트가 아니기 때문에 우리의 테스트는 대표성이 없어 보일 수도 있다.
오늘 Testcontainers 덕분에 Docker의 모든 기능을 사용하여 쉽게 연결할 수 있는 테스트 환경을 구축할 수 있습니다.
테스트 용기
Testcontainers를 사용하면 테스트 실행 중에 Docker 컨테이너를 쉽게 조작할 수 있습니다.Docker 클라이언트 docker-java을 사용하여 Docker 데몬 프로세스와 통신합니다.Windows를 지원하기 위해 최선을 다했지만 매일 Docker Toolbox를 사용합니다.매트릭스 호환성 here을 찾을 수 있습니다.
컨테이너를 만들 때 Testcontainers는
DOCKER_HOST
, DOCKER_TLS_VERIFY
및 DOCKER_CERT_PATH
변수를 사용하여 Docker 데몬에 연결합니다.예를 들어, 이러한 환경 변수는 JVM에서 쉽게 다시 쓸 수 있습니다.컨테이너 만들기
컨테이너는 개체GenericContainer로 표시됩니다.이미지, Dockerfile 또는 동적으로 작성된 Dockerfile에서 컨테이너를 작성할 수 있습니다.이 밖에 Docker Compose file에서 용기를 만들 수 있다.
예를 들어, 이미지 docker.elastic.co/elasticsearch/elasticsearch:6.1.1에 따라 생성된 Elasticsearch 서버입니다.
GenericContainer container = new GenericContainer("docker.elastic.co/elasticsearch/elasticsearch:6.1.1")
.withEnv("discovery.type", "single-node")
.withExposedPorts(9200)
.waitingFor(
Wait
.forHttp("/_cat/health?v&pretty")
.forStatusCode(200)
);
우리는 사용 방법 withEnv
이 용기에 환경 변수를 제공하는 것이 상당히 쉽다는 것을 볼 수 있다.이런 상황에서 변수 발견이다.값이 있는 단일 노드를 입력합니다.다음은
/_cat/health
API에 대한 HTTP 호출과 200 코드 응답을 통해 용기가 시작되었는지 확인합니다.컨테이너가 실행되고 있다고 단언할 수 있는 다른 정책도 있습니다.withExposedPorts
으로 현저하게 설정한 것입니다.이것은 Testcontainers가 이 용기의 포트를 무작위 포트에 비추는 것을 의미한다.방법 getMappedPort
을 사용하여 매핑된 포트를 검색할 수 있습니다. 그렇지 않으면 방법 setPortBindings
을 사용하여 포트 귀속을 정의할 수 있습니다.여기서 포트 9200을 컨테이너에서 포트 9200으로 노출합니다.container.setPortBindings(Arrays.asList("9200:9200"));
그렇습니다!Elasticsearch 서버가 준비되었습니다.시작하려면 start 메서드를 실행하십시오.container.start();
시작할 때, Testcontainers는 docker 버전이나 등록된 docker 등록표에 대한 연결과 같은 일련의 검사를 실행합니다.회사 에이전트 다음에 일을 하면 차단될 수 있기 때문에 파일testcontainers를 만들어서 검사를 비활성화할 수 있습니다.테스트 자원 디렉터리에는 다음과 같은 속성이 포함되어 있습니다.check.disable=true
마지막으로, 우리는 stop 방법으로 용기를 멈출 수 있다.container.stop();
그러면 컨테이너가 중지되고 연결된 볼륨이 제거됩니다.이것은 매우 좋다. 왜냐하면 그것은 권현공을 방지할 수 있기 때문이다.테스트 기간
Testcontainers의 가장 큰 장점은 JUnit 프레임워크와의 통합이다.사실 GenericContainer 객체는 JUnit rules입니다.이것은 그들의 생명주기가 테스트 생명주기에 직접 귀속된다는 것을 의미한다.따라서
@Rule
또는 @ClassRule
JUnit 주석을 사용하면 우리의 용기는 테스트가 시작되기 전에 초기화되고 테스트 실행이 끝날 때 정지됩니다.@ClassRule
public static GenericContainer redis = new GenericContainer("redis:3.0.2")
.withExposedPorts(6379);
그럼에도 불구하고 이것은 Testcontainers가 JUnit 4 의존항을 첨부한다는 것을 의미하며, 테스트가 JUnit 5으로 실행된다면 매우 짜증날 수 있습니다.사실 JUnit은 규칙 개념을 Extension으로 대체했다.2018년 11월 1.10.0 버전 발표 이후 Testcontainers supports now JUnit 5, 전용 라이브러리 junit jupiter의 @Testcontainers
과 @Container
주석의 도움으로 확장을 사용할 수 있습니다.<dependency>
<groupId>testcontainers</groupId>
<artifactId>junit-jupiter</artifactId>
<version>1.10.2</version>
</dependency>
사전 구성된 컨테이너
Docker와 마찬가지로 Testcontainers 생태계는 매우 풍부하다.MySql, PostgreSQL, Oracle database, Kafka, Neo4j, Elasticsearch 등 미리 설정된 용기를 찾을 수 있습니다.
@Rule
public KafkaContainer kafka = new KafkaContainer();
maven repository에서 직접 목록을 조회할 수 있습니다.구체적인 사례
Testscontainers를 Spring PetClinic application에 사용한 구체적인 예시를 살펴보겠습니다.Spring Boot, Spring MVC, Spring JPA 등 여러 Spring 구성 요소를 기반으로 한 프레젠테이션입니다.이 프로그램은 애완동물 진료소를 관리하는 데 목적을 두고 있으며, 애완동물 주인과 수의사를 포함한다.
컨트롤러 레이어가 엔티티를 생성하고 읽을 HTTP 끝점을 공개합니다.그리고 지구층은 관계 데이터베이스와 통신한다.응용 프로그램은 HSQLDB 또는 MySql 데이터베이스와 통신하도록 구성할 수 있습니다.
지구층은 통합 테스트를 사용하는데 이 테스트는 메모리에 있는 HSQL 데이터베이스를 사용하고 지구층 자체는 MySql 데이터베이스를 사용한다.
요구 사항
우선 테스트를 수행하는 시스템에 Docker를 설치해야 합니다.그리고 프로젝트에 Testcontainers 의존 항목을 추가해야 합니다.이런 상황에서 우리는 아래의 내용을pom에 추가하기만 하면 된다.xml 파일:
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<version>1.10.2</version>
<scope>test</scope>
</dependency>
데이터베이스 구성
기본 데이터베이스 설정은 응용 프로그램에서 완성됩니다.속성 파일.
database=hsqldb
spring.datasource.schema=classpath*:db/${database}/schema.sql
spring.datasource.data=classpath*:db/${database}/data.sql
보시다시피 이것은 메모리의 HSQLDB 데이터베이스입니다. 이 모드의 모드를 사용하여 초기화합니다.sql 파일.그리고 데이터로 데이터베이스를 채운다.sql 파일.이것은 기본 항목 설정입니다.
응용 프로그램 테스트를 만들어야 합니다.속성 파일은 MySql 데이터베이스에 대한 연결을 구성합니다.
spring.datasource.url=jdbc:mysql://localhost/petclinic
spring.datasource.username=petclinic
spring.datasource.password=petclinic
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
다음은 테스트 클래스 ClinicServiceTests.java
을 배워보겠습니다.이런 종류의 지구층을 포함하는 모든 집적 테스트우선, 테스트를 데이터베이스로 연결할 수 있도록 Spring 테스트 구성을 변경해야 합니다.
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<version>1.10.2</version>
<scope>test</scope>
</dependency>
database=hsqldb
spring.datasource.schema=classpath*:db/${database}/schema.sql
spring.datasource.data=classpath*:db/${database}/data.sql
spring.datasource.url=jdbc:mysql://localhost/petclinic
spring.datasource.username=petclinic
spring.datasource.password=petclinic
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
@TestPropertySource
주석은 우리의 파일 응용 프로그램 테스트를 불러올 수 있습니다.속성 및 값이 @AutoConfigureTestDatabase
인 NONE
은 Spring이 내장된 데이터베이스를 만드는 것을 막습니다
MySql 컨테이너
테스트 요구에 맞는 MySql 데이터베이스를 만듭니다.이 예에서 Testcontainers 기능을 사용하여 동적으로 생성된 Dockerfile에서 Docker 이미지를 만듭니다.첫 번째 단계로 Docker Hub에서 MySql official image:
추출현재, 우리는 데이터베이스와 연결된 사용자를 만들어야 합니다.이것은 Docker 이미지의 환경 변수를 사용하여 수행되는
다음에 우리는 데이터베이스 모델을 만들고 데이터베이스를 채워야 합니다.그림 문서에서 디렉터리는docker entrypoint initdb입니다.시작할 때 d을 스캔하면 모든 파일이 입니다.sh,.sql.sql.gz 확장을 실행합니다.따라서 우리는 파일을 모드에 넣기만 하면 된다.ql와 데이터.이 디렉터리의 sql
withClasspathResourceMapping
, 파일 모드를 사용합니다.ql와 데이터.sql은 클래스 경로에 볼륨으로 있는 용기입니다.그런 다음 Dockerfile Fabric에 액세스할 수 있습니다
마지막으로 기본 MySql 포트를 공개해야 합니다: 3306
불행하게도 setPortBindings를 사용하여 포트 연결을 직접 설정할 수 없습니다.우리는 만들 때 용기를 사용자 정의하는 방법 withCreateContainerCmdModifier
을 사용해야 합니다.마지막으로, 우리는 용기가 시작되었는지 확인하기 위해 탐지 포트를 기다리고 있습니다
봐라!몇 줄의 코드를 통해 우리는 용기의 생명주기를 관리하지 않고 MySql 데이터베이스를 쉽게 설정할 수 있다.@ClassRule
주석은 모든 테스트에서 용기를 한 번만 시작합니다.테스트 실행 시간을 연장했습니까?사실 Docker 컨테이너를 사용하는 데는 907밀리초, HSQLDB 메모리 데이터베이스를 사용하는 데는 860밀리초밖에 걸리지 않습니다.이 절에서 보여준 원본 코드는 github에서 얻을 수 있습니다
감사합니다,, 그들과의 시간과 교정
Reference
이 문제에 관하여(통합 테스트 Dockerize), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/vga/dockerize-your-integration-tests--4edm텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)