[워밍업 클럽 4기 백엔드] 4주차 발자국
Practical Testing: 실용적인 테스트 가이드 강의를 수강하고 작성한 회고입니다.
1. 학습한 내용 및 회고
Validation에 대한 책임 분리
도메인 로직에 해당하는 것을 Presentation 레이어에서 검증을 하는 게 맞는지 고민해봐야 한다.
Test Double
Stub : 요청한 것에 대해 어떤 값을 리턴할 지 만들어놓는 객체 (상태 검증)
Spy : Stub처럼 행동하면서, 메서드 호출 내용이나 횟수를 기록
Mock : 요청한 방식대로 동작하도록 하는 객체 (행위 검증)
관련 어노테이션
@Mock
: 가짜 객체 (Mock 객체)로 생성하고 싶을 때 사용@Spy
: 행위에 대한 기록(몇 번 호출됐는지, 타임아웃 검증)을 하는 객체@InjectMocks
: Mock이나 Spy 객체들을 테스트 클래스의 의존성으로 주입한다.
BBDMockito
Mockito를 BDD 스타일로 바꾼 것으로 기능을 Mockito와 동일하다.
Classicist와 Mockist
Classicist는 협력 객체를 처리할 때 실제 객체를 사용하고, Mock은 꼭 필요한 외부 의존성 정도로만 제한한다.
Mockist는 모든 협력 객체를 Mock으로 처리한다. 테스트 대상 객체가 어떤 협력 객체와 어떤 메시지를 주고받는지에 초점을 맞춘다.
더 나은 테스트를 작성하기 위해
한 문단에는 한 주제가 들어가는 게 좋은데, 그걸 확인하는 방법 중 하나가 'DisplayName을 한 문장으로 할 수 있는가'를 생각해보는 것이다.
모든 구조를 개발자가 완벽하게 제어할 수 있어야 한다.
현재 시간이나 랜덤값처럼 개발자가 제어할 수 없는 부분은 상위 계층으로 분리하거나 mocking 처리를 하자.
Test Fixture
@BeforeAll
: test class 실행 전에 한번 실행된다.@BeforeEach
: test method 실행 전에 실행된다.@AfterEach
: 하나의 테스트가 끝날 때마다 실행된다.공유 자원은 되도록이면 쓰지말자.
그럼 언제 BeforeEach를 쓰는가
각 테스트 메서드 입장에서 공유 자원을 아예 몰라도 테스트 내용을 이해하는 데에 문제가 없을 때
공유 자원을 수정해도 모든 테스트에 영향을 주지 않을 때
Test Fixture 클렌징
deleteAllInBatch()
바로 DELETE 쿼리 실행
한 번의 쿼리로 테이블 전체 삭제
deleteAll()
엔티티를 하나씩 조회한 후 삭제한다.
내부적으로 각 엔티티를 개별적으로 삭제
@ParameterizedTest
하나의 테스트에서 여러 값에 대한 테스트를 진행하고 싶을 때 사용한다.
여러 값에 대해 같은 로직을 테스트하고 싶을 때 분기문보단 @ParameterizedTest로 하는게 더 이해하기 좋다.
@DynamicTest
같은 환경에서 단계적인 시나리오 테스트할 때 사용한다.
만약 private 메서드를 테스트하고 싶다면 객체 분리가 덜 되었는지 생각해보자.
회고
강의를 들으면서 테스트에 대한 생각이 많이 바뀌었다. 테스트 코드가 중요한 건 알았지만, 항상 프로젝트를 할 때 시간적 제약이 있기 때문에 테스트 코드는 항상 우선순위가 밀렸었다. '가까이 보면 느리지만, 멀리 보면 가장 빠르다'라는 말처럼 테스트 코드가 우선순위에서 밀려야 하는 존재가 아니라는 걸 깨달았고, 앞으로도 테스트 코드는 꼭 작성해야겠다고 생각했다.
Classicist와 Mockist에 대해서도 생각해봤는데, 우빈님과 동일하게 나도 Classicist에 더 가깝다고 생각한다. 모든 협력 객체를 mocking 처리해버리면, 실제 여러 모듈을 결합해서 동작시켰을 때 어떤 문제가 발생할지 알 수 없다. 그리고 classicist 방식이 실제 객체 간의 흐름을 검증할 수 있기 때문에 더 신뢰할 수 있는 테스트를 작성할 수 있다고 생각했다.
이제 4주간의 여정이 끝났다. 그냥 혼자 강의 들으면서 공부할 수도 있는 건데, 이렇게 워밍업 클럽을 통해서 미션도 하고, 라이브 세션도 들으면서 혼자였다면 몰랐던 인사이트도 많이 얻어 가는 것 같다. 아주 의미 있는 4주였다.
4주 동안 열심히 공부한 내용을 바탕으로 앞으로의 개발 경험에 잘 활용해나가고 싶다.
2. 미션 회고
레이어별 테스트의 특징을 고민해보면서, 테스트 코드를 어떻게 작성해야 할지에 대한 감을 조금씩 잡을 수 있었다.
그리고, 그동안은 @Mock 정도의 간단한 Mocking만 사용해봤는데, 이번에는 @Mock, @Spy 등 다양한 애노테이션을 직접 활용해보면서 각 어노테이션의 역할과 차이를 명확하게 이해할 수 있었다.
또한 어떤 상황에서 공유 자원을 사용하는 것이 적절한지에 대해서도 고민해볼 수 있는 좋은 기회였다.
출처
Practical Testing: 실용적인 테스트 가이드
댓글을 작성해보세요.