통합 테스트 Dockerize

대부분의 응용 프로그램은 데이터베이스, HTTP API, 메시지 에이전트, SMTP 서버 등과 통신해야 합니다. 이러한 구성 요소를 사용하여 진정한 테스트 환경을 구축하는 것은 상당히 복잡합니다.
어떤 경우, 우리는 이 구성 요소를 간단하게 모의하거나, 테스트 실행 기간에 메모리에 구성 요소를 만들 수 있다.예를 들어 H2 ouHSQLDB은 메모리에 있는 데이터베이스로 통합 테스트 기간에 사용하기로 유명하다.그러나 생산 환경에서 사용하는 테스트가 아니기 때문에 우리의 테스트는 대표성이 없어 보일 수도 있다.
오늘 Testcontainers 덕분에 Docker의 모든 기능을 사용하여 쉽게 연결할 수 있는 테스트 환경을 구축할 수 있습니다.

테스트 용기


Testcontainers를 사용하면 테스트 실행 중에 Docker 컨테이너를 쉽게 조작할 수 있습니다.Docker 클라이언트 docker-java을 사용하여 Docker 데몬 프로세스와 통신합니다.Windows를 지원하기 위해 최선을 다했지만 매일 Docker Toolbox를 사용합니다.매트릭스 호환성 here을 찾을 수 있습니다.
컨테이너를 만들 때 Testcontainers는 DOCKER_HOST, DOCKER_TLS_VERIFYDOCKER_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 코드 응답을 통해 용기가 시작되었는지 확인합니다.컨테이너가 실행되고 있다고 단언할 수 있는 다른 정책도 있습니다.
  • 대기.forLogMessage 대기 로그 메시지,
  • 대기.forListeningPort 대기 탐지 포트
  • 대기.forHealthcheck는 docker의 HEALTHCHECK 기능을 사용할 수 있습니다.
  • 용기 설정을 완성하기 위해서, 우리의 용기는 내부 포트 9200을 공개합니다. 이것은 방법 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 테스트 구성을 변경해야 합니다.

    @TestPropertySource 주석은 우리의 파일 응용 프로그램 테스트를 불러올 수 있습니다.속성 및 값이 @AutoConfigureTestDatabaseNONE은 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에서 얻을 수 있습니다


    감사합니다,, 그들과의 시간과 교정

    좋은 웹페이지 즐겨찾기