Integration Test Using TestContainers
Spring Boot 와 RDBMS 환경에서 개발하면서 Test 를 작성할 때, 테스트 환경의 경우 주로 H2 를 사용한다. H2 는 몇 줄만 추가해주면 Test 환경에서 사용이 가능하기 때문에 설정이 매우 쉽다. 하지만 production 환경에서는 MySQL, PostgreSQL, MS SQL, Oracle 등 H2 와는 다른 Database 를 사용하고 있다면 이슈가 발생할 수 있다.
기본적으로 지원되는 문법이 다르거나 Database Engine 이 동작하는 방식이 달라서 Test 를 신뢰할 수 없다. 이것은 본질적으로 Test Code 를 작성하는 의미를 지키기 힘들어진다.
H2 에서 compatible 모드를 지원하지만 본질적으로 완전하게 동일한 환경을 보장할 수 없다.
아래 링크를 통해서 확인할 수 있다.
http://www.h2database.com/html/features.html#compatibility
모든 database engine 들은 조금씩 다르게 동작합니다. H2 는 ANSI 표준을 지원하고 다른 database 와 호환되도록 노력합니다. 하지만 여전히 차이가 존재합니다.또한, Transaction 도 다르게 동작한다. ACID 의 개념을 빠뜨릴 수 없는데 MySQL 의 경우 default Isolation Level 은 REPEATABLE READ 이지만 H2 default Isolation Level 은 READ COMMITED 이다. Phantom Read 이슈가 발생하게 된다.
물론 설정을 REPEATABLE READ 로 변경하고 Production 환경과 최대한 비슷하게 설정하고나서 H2 사용을 고려해 볼 수 있다. 하지만, 쉽게 설정할 수 있다는 H2 의 장점이 없어진다.
따라서 Production 환경과 최대한 동일한 환경으로 쉽고 빠르게 설정하여 테스트를 진행할 수 있도록 TestContainers 를 사용하자.
TestContainers 는 Java library 이다. Integration test 를 복잡한 설정 없이 Docker container 를 통해서 빠르고 쉽게 할 수 있다. RDBMS 뿐만 아니라, Kafka, Nginx 등 Message Queue, Web Server 그리고 Custom Image 나아가 docker-compose 또한 사용할 수 있다.
그렇다면 이제 간단하게 기본 동작 방식과 간단한 팁을 예제를 통해서 확인해보자.
Local 개발환경은 docker compose 를 이용하여 MySQL 5.7 version 의 container 를 사용한다고 가정한다. 한글과 이모지를 사용할 수 있도록 character-set 과 collation 을 utf8mb4 로 설정해주고, init.sql 파일을 이용하여 처음 schema 와 기본 data 를 load 할 수 있도록하기 위해서 skip-character-set-client-handshake 커맨드를 사용했다.
기본적인 MySQL 기반 JPA Spring Boot Application 을 아래와 같이 만들었다.
그리고 testcontainers 의존성을 추가 해준다. junit-jupiter, mysql
Writer 1 : N Book 관계의 Entity 로 Book 에서 Writer 로 단방향 관계를 맺어주었다.
그리고 간단하게 Service, Repository 작성하였다.
아래와 같이 testcontainers 를 이용하여 Integration test code 를 작성했다.
test 환경 profile yaml 파일이다.
Jupiter / Junit5 2 가지 동작 방식
따라서, 하나의 test method 가 시작되기전에 container 가 시작되고 test method 가 동작하고 종료되면 해당 container 도 종료된다. 따라서 test method 가 많아질수록 container boot time 이 증가된다.
Reuse 를 통한 컨테이너 부트 타임 줄이기
Singleton Container Pattern
추상 클래스 활용
인터페이스 활용
참고
https://github.com/ndgndg91/testcontainers-demo
http://www.h2database.com/html/features.html#compatibility
https://www.h2database.com/html/advanced.html#acid
https://www.testcontainers.org/
https://www.testcontainers.org/test_framework_integration/junit_5/
https://github.com/testcontainers/testcontainers-java
https://www.youtube.com/watch?v=v3eQCIWLYOw
https://bsideup.github.io/posts/local_development_with_testcontainers/
https://pawelpluta.com/optimise-testcontainers-for-better-tests-performance/
댓글
댓글 쓰기