인수 테스트의 격리를 위해 TestExecutionListener를 적용한 내용을 공유합니다. #439
greeng00se
started this conversation in
기록
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
테스트 격리
테스트의 순서에 따라 성공 실패 여부가 결정되는 비결정적인(non-determinism) 테스트가 되어서는 안되고, 테스트는 항상 순서에 상관없이 독립적으로 수행되도록 보장되어야 합니다. 일반적으로 자원의 공유, 외부 API, 시간 등으로 비결정적인 테스트가 되고는 합니다. 이를 해결하기 위해 테스트 대역을 사용하거나, 컨텍스트를 재실행하는
@DirtiesContext
, 자원을 초기화하기 위해 테스트 이후에 테이블을 롤백 하는@Transactional
등 다양한 방법이 있습니다.기존의 테스트 격리
기존 테스트의 경우 @SQL 애너테이션을 이용하여 각 테스트 이후마다 truncate 구문을 실행하여 테스트를 진행했습니다. 빠르게 적용할 수 있지만 프로젝트를 진행하면서 새로운 테이블이 추가되는 경우, 테이블을 직접 추가해 줘야 한다는 문제점이 있었습니다.
TestExecutionListener
스프링에서는 TextExecutionListner를 이용하여 각 테스트 실행 단계에서 이벤트를 수신할 수 있습니다.
이를 이용하면 JUnit의 @beforeeach를 사용하는 것과 유사하게, 테스트의 생명주기 이전 또는 이후에 필요한 작업을 실행시킬 수 있습니다.
AbstractTestExecutionListener 상속하여 구현
AbstractTestExecutionListener를 상속받아 테스트 격리 환경을 만들어주는 클래스입니다. 또한 인터페이스인 TextExecutionListner와 달리 Ordered가 구현되어 있어 해당 클래스를 상속받아 구현한 클래스는 프레임워크가 제공하는 리스너 다음에 실행시키도록 합니다.
다음과 같이 데이터베이스에서 각각의 테이블에 해당하는 Truncate 쿼리를 만들어서 조회하고, Test 메서드가 끝날때 마다 해당 쿼리를 실행하여 테이블을 초기화시키도록 설정했습니다.
Listener 등록
@TestExecutionListeners를 이용하여 사용자 정의 리스너를 등록할 수 있습니다.
mergeMode의 기본값은 REPLACE_DEFAULTS로 리스너가 이미 존재하는 경우 등록된 리스너로 변경됩니다.
MERGE_WITH_DEFAULTS로 설정한다면 Ordered 기준으로 순서가 결정됩니다.
이후 격리가 필요한 테스트들은 다음의 추상 클래스를 상속하면 됩니다.
참고 자료
The Spring TestExecutionListener, Baeldung
인수테스트에서 테스트 격리하기, 테코블
Eradicating Non-Determinism in Tests, martin fowler
@SpringBootTest의 테스트 격리시키기, MangKyu
Beta Was this translation helpful? Give feedback.
All reactions