인프런 워밍업 클럽 스터디 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()

댓글을 작성해보세요.


채널톡 아이콘