일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 운영체제
- 보안
- 데이터베이스
- ES6
- IT
- NEST
- 탐욕기법
- 디비
- 병행제어
- DATABASE
- 노드
- 컴퓨터보안
- 백준
- node
- API문서
- node.js
- 스프링부트
- 인터럽트
- 백트래킹
- 자바스크립트
- AWS
- 되추적
- DB
- 컴퓨터
- rest docs
- 컴퓨터 보안
- OS
- access control
- 알고리즘
- S3
- Today
- Total
개발스토리
TestContainer 본문
테스트 코드를 작성하는 환경을 구축하는 것은 중요하다.
처음에 가장 어렵고, 귀찮고, 시행착오도 많이 겪는 과정이라고 생각한다.
테스트 환경을 구축하는 과정에서 많은 부분을 고려해야 하지만 특히 주의해야할 부분은 "멱등성"이다.
■ 멱등성이란 여러번 연산을 실행해도 결과가 바뀌지 않는 성질을 뜻한다.
HTTP method에서 보자면 POST를 제외하고 나머지는 멱등성을 만족한다.
POST 요청을 반복한다면, 데이터들은 계속해서 추가가 되고, 서버의 응답은 다 다른 응답을 나타낸다. 같은 내용이더라도 서로 다른 데이터이다.
PUT 요청으로 2번 데이터를 수정한다고 치면, 2번 데이터가 없는 경우에는 데이터가 생성될 수 있지만, 이미 존재하면 데이터는 수정이 된다. 계속해서 PUT 요청을 날려도 2번 데이터는 우리가 요청한 데이터 값을 가지고 있다.
DELETE는 데이터가 존재하든, 존재하지 않든 DELETE 요청을 날린 시점에서 사라지게 되므로 우리가 요청한 사항은 이루어졌음을 의미한다.
GET은 같은 데이터를 계속해서 응답하므로 이해가 쉬울 것이다.
우리는 프로젝트를 진행하면서 외부 모듈들을 많이 쓴다. 또한, 서버에 변경 코드들은 계속해서 추가가 되며
이것들을 계속해서 신경쓰며 관리하는 것은 어려우며, 하고 싶지 않을 것이다.
바로 이러한 부분에서 멱등성이 깨지기 쉽다. 멱등성이 깨지게 된다면, 우리가 생각했던 데로 서비스가 굴러가지 않는다.
또한 잘 실행되던 것들이 갑자기 에러 천국으로 변할 수도 있다.
그래서 반드시 테스트 환경 구축과 코드 작성에 있어서는 멱등성을 고려해야 한다.
TestContainer로 멱등성을 유지해보자.
우선, 테스트 환경에서 외부 의존성이 있는 것 중에 가장 기본적인 것은 DB라고 볼 수 있다.
1. 로컬 환경에서 실제 DB를 띄우는 방법
- 이 방법은 실제와 거의 유사한 환경으로 테스트를 할 수 있지만 동시에 여러 테스트가 이루어지거나, 테스트가 끝났음에도 테스트용 데이터가 남아있는 문제들로 멱등성을 관리하기가 어렵다.
- 다른 방법 중 가장 신경써야할 일이 많은 것 같음.
- 협업을 하면서 다른 사람들과 테스트를 동시 수행하면서 의도치 않은 데이터 변경이 일어날 수 있음.
2. in-memory DB를 활용하는 방법
- H2 등을 사용하고 ORM을 통해서 특정 DB와의 종속성을 해결하는 방법이다. 빠르고, 간단하지만 특정 DB에 특화된 기능을 테스트하거나 DDL을 명시할 때 실제 동작과는 다른 SQL을 작성해야한다는 문제가 있다. ( 실제 쿼리 수행과 완벽하게 동작하지 않을 수 있다 -> 가장 단점 같음 ) , 테스트 환경과 개발 환경이 같은 상황에서 테스트하는 것이 중요해보임
- 외부 db 커넥션이 없고, 테스트 수행 후 데이터 롤백이 필요없다는 장점도 있다.
- 개발 사항에 따라 스키마 초기 구성을 최신화해줘야하는데 프로젝트가 커지면 데이터 양이 너무 많다. -> 추가 관리 항목
3. Docker-Compose 활용하는 방법
- 위에 1 , 2번 방법이 아니라도 도커 이미지만 가지고 있다면 테스트 환경을 구축할 수 있다. 이 것도 간편한 방법이지만 docker-compose 파일을 관리해야하는 번거로움이 있다. 또한, random port를 통해 local 포트 충돌 방지 및 병렬 테스트를 어렵게 만든다. 또한, 도커를 올렸다가 내렸다가 하는 과정도 귀찮고, 자칫하면 백그라운드에 남아있어 리소스를 잡아먹을 수도 있다.
4. TestContainer 활용하는 방법
- 테스트 전에 H2, Oracle(예시), Docker Container를 따로 띄우지 않아도 자동으로 테스트할 때 DB Container를 띄어주고 테스트가 종료되면 컨테이너도 같이 종료시켜주는 역할을 한다. 3번 방법과 동작 원리는 같지만, 실제로 설정하는 것은 확 줄어든다.
+++
기존 방식과 다른 점은 test container가 실행된 random port로 접근해서 local port간의 충돌을 방지하고 병렬 test를 가능하게 한다는 점이다.
+++
도커를 사용하면 변화하지 않는 실행환경으로 멱등성을 확보할 수 있다.
서버에 변경을 가하고 싶은 경우에는 그냥 새로운 서버를 구축하고 이미지로 빌드하고 컨테이너를 띄어버리면 된다.
도커를 사용하지 않았을 때에 잦은 업데이트 등으로 멱등성을 보장할 수 없는 경우는 빈번히 발생할 수 있다.
단지, 도커를 자동으로 띄어주고 알아서 내려주는 것만을 장점으로 생각했지만 멱등성이라는 주요 이슈가 있다는 것을 새로 알게 되었다.
TestContainer를 도입하는 것도 괜찮을 것 같다.