인프런 워밍업 클럽 스터디 3기 - 백엔드 클린 코드, 테스트 코드 4주차 발자국
이번 주차에서는
테스트 코드 리뷰
더 나은 테스트를 작성하기 위한 구체적 조언
1. 테스트 코드 리뷰 정리
테스트 커버리지
코드 커버리지(테스트 커버리지)는 괜찮은 부정 지표지만 동시에 좋지 않은 긍정 지표다.
테스트 커버리지가 너무 낮을 경우 테스트가 충분하지 않다는 좋은 증거가 되지만, 테스트 커버리지가 100%라고 해서 반드시 양질의 테스트 스위트가 보장되지는 않는다.
학습 시에는 높은 커버리지를 목표로 하는 경험이 도움이 될 수 있다
테스트 시 사용하는 자원
private 메소드라도 상단에 위치시켜 보기 편하도록 한다
네이밍에 신경쓰자 (ex : target~ all~)
검증하는 데이터가 변경될 시 테스트가 깨지는 현상은 자연스러운 현상이다
데이터 정책 ex passtype이 바뀐다면 이를 사용한 테스트 코드들이 전부 깨질 것으로 예상된다
프로덕션 코드가 변경되면 테스트 코드 또한 영향을 받는 것은 당연하다
테스트 코드가 실패 하는 것을 보고 영향 범위를 인지 할 수 있다. (프로덕션 코드 변경에 대한 영향을 인지 못하는 것이 더욱 큰 문제)
수정해야 하는 비용은 들겠지만, 이는 자연스러운 현상이며, 테스트 코드에 대한 존재 이유이기도 하다
검증해야 하는 테스트 케이스가 너무 많아질 경우 코드 자체의 가독성을 위해 반복문을 선택할 수 있지만 이 또한 코드 이해에 허들이 될 수 있음을 인지해야 한다
ex 4개 정도면 그냥 나열하자 or 10개 이상이면 반복문을 돌리자
검증부는 상수로 쓰인 데이터를 하드코딩 해서 검증하자
ex EMPTY_SIGN 이 EMPTY_SIGN인지 검증 하는 형태는 항상 통과하게 된다 → 테스트 하는 의미가 없음
EMPTY_SIGN 이 ㅁ 문자열 인지 검증 (하드코딩)
간단한 로직의 경우 테스트 해야할까?
getter 정도는 테스트 하지 않아도 무방. getter와 거의 동일한 작업을 하는 is~메서드 등
한줄이라도 가공 비교 판별 등 비지니스에 직결된다면 테스트 해야 한다
테스트 시 새로운 제약사항이 필요하다고 판단되면 클라이언트에게 역 제안도 가능하다
displayname 에 변경이 일어나기 쉬운 내용 넣지 말자 (ex 파일 경로)
f/u 하기 힘듦
2. 더 나은 테스트를 작성하기 위한 구체적 조언
한 문단에 한 주제
여러가지 논리 구조(분기문, 반복문)가 들어 가는 것을 피한다
완벽하게 제어하기
현재 시간 같은 제어할 수 없는 변수는 쓰는 것을 지양하자. 수행되는 환경 (로컬/배포)에 따라 달라질 가능성이 있다.
테스트 환경의 독립성을 보장하자
팩토리 메서드는 프로덕션 코드에서 의도를 가지고 만드는 편 → 테스트 환경에서 사용은 지양하는 것이 좋다
대신 순수한 생성자를 가지고 테스트 환경을 위한 given절에서 객체 생성
테스트 간 독립성 보장
공유 자원 사용 금지
TestFixture
테스트를 위해 원하는 상태로 고정시킨 일련의 객체
각 테스트 입장에서 어떻게 구성 되는지 몰라도 내용을 이해하는데 문제가 없을 때
수정해도 모든 테스트에 영향을 미치지 않을 때
예) 댓글 생성 테스트의 경우 → 댓글 생성에 집중 → 테스트를 위한 게시글 생성 로직, 사용자 생성 로직 등이 @BeforeEach에 위치시켜 TestFixture을 구성할 수 있다.
TestFixture클렌징
deleteAll의 경우 셀렉트 쿼리, 각 레코드 마다 딜리트 쿼리가 건 단위로 나가게 된다. → 성능 이슈가 생길 수 있음
deletAllInBatch가 더욱 효과적으로 생각된다
트랜잭션 롤백을 사용하는 전략의 경우 SpringBatch를 사용한 배치 통합 테스트의 경우 사용하기 어렵다.
테스트 환경 통합하기
테스트 수행에 드는 시간 또한 잘 관리하여야 한다
스프링을 띄우는 환경이 조금이라도 달라지면 테스트 시 새로운 컨택스트를 띄우게 된다
동일한 환경에서 띄운다면 시간을 단축 가능하다
datajpatest → 데이터 jpa 관련 빈들만 올려서 빠르게 테스트 할 수 있지만, 서비스 에서 @Transactional로 테스트 후 사용하게 된다면 스프링을 새로 띄우게 된다는 걸 알아야함
서비스 테스트를 하면서 같이 레포지토리 테스트를 하는 것이 좋은 전략일 수 있다.
private 메서드의 테스트
테스트 하지 않는다
테스트 하고 싶어진다면 객체 분리의 신호일 수 있다.
테스트에서만 필요한 메서드
보수적으로 생성한다
매우 간단한 메서드 or 추후에 프로덕션 코드에서 사용할 가능성이 있는 경우
예시 size(), isEmpty()
댓글을 작성해보세요.