데보션앱 소개페이지 바로가기

인재 DB 등록 시 유의사항

CLOSE

채용공고 지원 시 유의사항

CLOSE
로그인 선택

신고하기

CLOSE
신고사유 (대표 사유 1개)
상세내용 (선택)
0/200
  • 신고한 게시글은 더 이상 보이지 않습니다.
  • 이용약관과 운영정책에 따라 신고사유에 해당하는지 검토 후 조치됩니다.
  • 허위 신고인 경우, 신고자의 서비스 이용이 제한될 수 있으니 유의하시어 신중하게 신고해 주세요.
(이 회원이 작성한 모든 댓글과 커뮤니티 게시물이 보이지 않고, 알림도 오지 않습니다.)

Integration Testing made Easy with Testcontainers and Docker

sunny79 23.02.27
1996 27 5

테스트의 변화

  • 모노리스 아키텍처에서 마이크로 서비스로 마이그레이션이 많아짐에 따라 테스트에 대한 내용도 달라지고 있다.

  • 모노리스에서는 아래와 같은 삼각형 형태의 테스트 분포가 일반적이다.

  • 단위테스트가 제일 많고, integraion, integrated 순으로 분포된다.


  • 마이크로 서비스는 몇개의 단위테스트 만으로도 전체 어플리케이션의 로직을 커버할 수 있을 만큼 단위가 작다(이론적으로).

  • 하지만 외부 dependency가 커짐에 따라 integration 테스트의 양은 증가한다.

  • 따라서 테스트의 분포는 아래와 같은 육각형 형태가 된다.



왜 testcontainers 를 사용해야 할까?

  • Microservice 아키텍처로 인해 통합테스트의 비율이 커지고 있다.

  • Mocks를 이용한 테스트도 좋지만, 실제로 통합테스트를 하기 전까지는 코드가 실제로 작동하는지 알 수 없다.

  • Testcontainers를 이용하면 프로그래밍을 통해 통합테스트에 필요한 외부 dependencies를 마련할 수 있다.

  • Testcontainers 와 Docker 덕분에 유래없이 통합테스트를 쉽게 구현할 수 있다.

Testcontainers 데모

  • pom.xml에 dependency들을 추가한다.


  • 데모에 사용되는 어플리케이션은 GameApp으로 wallet 정보는 postgres에, user와 items는  couchbase에 저장한다.


  • Test 클래스에 "@Testcontainers" 어노테이션을 추가한다.

  • "@Container" 어노테이션은 테스트 첫 실행시 postgres와 couchbase 컨테이너를 생성하고, 해당 저장소는 모든 테스트들이 공유한다.

  • "@DynamicPropertySource"를 통해 properties를 정의할 수 있다.

    • Testcontainers는 random port를 할당하기 때문에, port 설정은 신경쓰지 않는다.

  • image.png

  • 테스트 실행시 아래와 같이 postgres와 couchbase container가 생성되고, 테스트가 끝나면 사라진다.

  • image.png

  • 하나의 microservice에 postgres와 couchbase 두개의 database를 사용한 것은 microservice에 어울리지 않는다.

  • 두개의 microservice로 나누어 보자. 하나는 wallet를 저장하는 postgres를 사용하고, 다른 하나는 couchbase를 이용해 game user를 저장한다.

  • 소스를 분리하고, wallet microservice의 도커 이미지를 만들어, dockerhub의 denisros/wallet_mciroservice 레포지토리에 푸쉬하였다.

  • 테스트에서는 game user를 만들고, wallet microservice를 호출하여 해당 user의 wallet를 생성한다.

  • image.png

  • wallet microservice 와 postgres 사이에 통신이 가능해야 하므로, network 를 생성한다.

  • wallet microservice를 GenericContainer를 이용해 생성하고, 연결할 postgres의 DATASOURCE_URL를 postgres container의 network alias를 이용해 설정한다.

    • 같은 network를 통해 직접 접근하므로, 5432 디폴트 postgres포트를 이용한다.

  • image.png

  • walletMicroservice는 8080을 expose하는데, 테스트시 host와 매핑되는 랜덤포트를 얻기위해 walletMicroservice.getMappedPort(8080)를 이용한다.

  • image.png

  • 테스트 실행 시 wallet microservice, postgres, couchbase 컨테이너 역시 실행되는 것을 확인할 수 있다.


정리

  • 데모는 단순하지만, 복잡한 시나리오에서도 역시 testcontainers를 사용할 수 있다.

  • microservice간의 통신은 가능한 asynchronous 하게 한다. 예를 들면 kafka topic를 이용한다. Testcontainers에서는 kafka를 지원한다.


Reference

sunny79 님의 최신 블로그

더보기

관련 블로그