나는 테스트를 많이 접하지 않았다.
다만 여러 서적을 읽고 강의를 들으면서 공부하다 보면 반드시 나오는 주제가 있는데, 바로 테스트이다.
테스트는 코드의 품질에도 깊은 연관이 있고 잘 짜인 테스트 케이스는 소프트웨어의 성공으로 이끌 수 있기 때문이다.
이번에 데이터베이스 연동에 대한 테스트는 단지 강의를 듣고 내용을 정리하는 것이다. 깊은 지식을 포함하지 않고 다른 개발자가 어떻게 데이터베이스 연동을 테스트하는지 엿보는 시간이다.
카테고리에 맞게 스프링 부트를 사용하며 아마 기본 전략으로 Junit5를 사용하는 것으로 알고 있다.
1. 기본 설정
스프링 부트는 매우 많은 관례를 포함하고 있다. 그중 하나가 설정 파일에 대한 부분이다.
resources 폴더에 있는 appication.properties는 스프링의 설정을 쉽고 편하게 설정할 수 있도록 도와준다.
테스트에 있어서 application.properties [ap]의 우선순위를 알아보자.
테스트를 진행할 때 스프링은 main 하위에 있는 ap파일대신 test 하위의 ap파일을 우선적으로 적용한다.
따라서 데이터베이스 연동 정보 및 관련 설정이 main 밑 ap파일에 있는 것보다 테스트를 위한 설정을 별도로 하는 것을 추천한다.
2. @SpringBootTest
스프링의 기능을 사용하지 않는 작은 단위테스트인 경우에는 사용하지 않지만 스프링의 기능을 포함하여 테스트할 때 사용되는 어노테이션이다.
@SpringBootTest는 @SpringBootApplication를 찾아 사용을 한다. 이 과정에서 @SpringBootApplication에 적용된 스프링 설정 파일이 적용되어 사용되는 것이다.
3. 테스트간 영향을 미치지 않는 방법
데이터베이스 관련 테스트는 데이터를 저장하고 수정하고 삭제한다. 이 과정이 다른 테스트에게 영향을 미치면 당연히 안된다. 이번에 알아볼 것은 격리성에 대한 부분이다.
하나의 애플리케이션에는 반드시 2개 이상의 데이터베이스가 존재한다.
운영하기 위한 데이터베이스와 테스트를 위한 데이터베이스이다.
회사의 보안에 따라 개인 로컬 환경의 데이터베이스까지 허용되는 경우는 별로 없을 듯싶다.
그렇다면 데이터베이스 테스트를 위해선 테스트 환경에서 사용될 데이터베이스를 만드는 것을 우선적으로 해야 한다.
이후는 우리는 각 테스트마다 롤백을 통해 테스트 이후 데이터를 되돌리면 된다.
이를 위해서 @BeforeEach, @AfterEach는 매우 편리함을 제공해 줄 수 있다.
@BeforeEach는 각각의 테스트 케이스를 실행하기 직전에 호출된다. 따라서 트랜잭션의 시작 부분을 추가한다.
@AfterEach는 각각의 테스트 케이스가 완료된 직후 호출된다. 따라서 트랜잭션의 롤백을 진행하면 된다.
* 스프링 부트를 사용하면 트랜잭션 매니저를 자동으로 등록해주기 때문에 별도의 설정 또한 필요 없다.
더욱 편리하게 사용하기 위해선 선언적 트랜잭션 방식을 테스트에 적용하는 것이다.
테스트 클래스에 @Transactional을 붙이게 되면 기존의 방식과 다른 방식으로 동작한다.
기존 @Transactional은 성공시 커밋되는데 테스트에서 사용할 시 트랜잭션 안에서 실행하고 테스트가 정상 종료될 시 자동으로 롤백한다.
추가적으로 내 생각인데 이 과정에서 커넥션 동기화가 제대로 이루어지지 않는 테스트 코드가 있다면 문제가 발생할 것 같다.
그렇게 생각한 이유는 트랜잭션 매니저를 통해 데이터베이스 연결 세션을 관리하여 사용하는데, 로직 중간에 새로운 커넥션을 얻어 사용하는 순간 커넥션 동기화가 되지 않아 심하면 블락 상태까지 될 거라는 생각이 든다.
물론 JdbcTemplate, 상위 클래스들은 연결을 얻는 과정에 대해 트랜잭션 동기화 매니저를 통해 얻도록 구성되어 있겠지만 레거시 프로젝트는 순수 JDBC를 사용해 커넥션을 얻는 것들도 있을 것이고, 이러한 프로젝트에서 커넥션 동기화를 위한 코드 변경이 필요할 것이다.
4. 중간 검증이 필요하다면?
격리성이 만족된 테스트는 데이터를 롤백하기 때문에 눈으로 확인하지 못한다. 물론 로그를 통해 확인할 수 있지만 직접 보고 싶을 때가 있다.
이 경우에는 @Transactional + ( @Commit 혹은 @Rollback(value = false) )를 사용하면 데이터베이스에 커밋이 된다.
5. 로컬 환경에 대한 데이터베이스 설정
스프링 부트를 사용하는 개발자는 임베디드 모드를 통하여 손쉽게 데이터베이스 테스트를 진행할 수 있다.
스프링 부트는 데이터베이스에 대한 별다른 설정이 없을 시 기본으로 임베디드 데이터베이스를 사용한다.
* 만약 sql 스크립트가 필요하다면 resource 밑 schema.sql 파일을 작성하면 애플리케이션 시작 이후 실행된다.
'Test' 카테고리의 다른 글
TDD 시작 (0) | 2022.12.10 |
---|---|
JUnit (0) | 2022.11.08 |
JUnit5 (2) (0) | 2021.03.14 |
Test (0) | 2021.03.14 |
JUnit5 (1) (0) | 2021.03.13 |
댓글