우아한테크코스 4기/프로젝트

[테스트 자동화 2] @AfterEachCallBack을 통해 롤백 자동화하기

giron 2022. 10. 30. 18:09
728x90

이전의 게시글에서 필자의 서비스에서 테스트는 @Tansactional을 통한 롤백을 제거했다.

이후, 매번 테스트에서 아래의 사진처럼 DatabaseCleaner를 주입받아 반복적으로 @AfterEach로 테스트가 끝난 후, 롤백을 진행해 주었다.

반복했던 tearDown()

최근에 우아한테크코스 리펙토링 미션을 진행하면서 해당 방식에 대해서 알게 되었다. 이후, Junit5의 공식 문서를 확인해봤고 해당 기술에 대해서 알게 되었다.

  • BeforeAllCallback - @BeforeAll 적용된 메서드 전에 실행(가장 먼저 실행된다.)
  • BeforeEachCallback - @BeforeEach 적용된 메서드전에 실행
  • BeforeTestExecutionCallback - 각 테스트가 실행되기 직전에 실행(@Before후에 실행된다.)
  • AfterTestExecutionCallback : 각 테스트가 종료 후 실행(@AfterEach전에 실행된다.)
  • AfterEachCallback : @AfterEach 적용된 메서드 종료 후 실행
  • AfterAllCallback : 모든 테스트 종료 후 실행  (가장 나중에 실행된다.)

BeforeAllCallback과 AfterAllCallBack은 딱 한 번만 실행된다. 

자동화를 해보자!

아래는 Junit 5의 AfterEachCallBack을 활용하여 자동으로 테스트가 끝난 후에 롤백을 시켜주는 방식이다.

RollbackExtension

public class RollbackExtension implements AfterEachCallback {

    @Override
    public void afterEach(ExtensionContext context) {
        DatabaseCleaner databaseCleaner = SpringExtension.getApplicationContext(context).getBean(DatabaseCleaner.class);
        databaseCleaner.tableClear();
    }
}

@ServiceTest

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@ExtendWith(RollbackExtension.class)
@SpringBootTest
public @interface ServiceTest {
}

@AfterEachCallback적용

이렇게 적용만 해주면 끝! 사용법은 간단했다.

이제 매번 DatabaseCleaner를 Autowired로 선언 안 해줘도 되고 @AfterEach로databaseClear.tableClear()를 실행시키지 않아도 된다. 매번 테스트가 돌고난 후, 자동으로 테이블을 초기화시킬 수 있다.

 

이를 통해, 아래와 같이 공식팀의 테스트 자동화가 변했다.

  1. truncate.sql로 매번 레포지토리를 추가해서 롤백하는 방식
  2. entityManager를 활용해서 자동으로 테이블의 이름을 매핑해서 truncate 시켜주는 방식
    • 매 테스트마다 @AfterEach를 선언해서 롤백시켜주는 방식
  3. @AfterEachCallback을 통해 매 테스트마다 반복적인 작업을 제거

Reference

https://junit.org/junit5/docs/5.4.0/api/org/junit/jupiter/api/extension/AfterEachCallback.html

https://www.baeldung.com/junit-5-extensions

728x90