테스트 관련 이론 정리(2)

김윤서·2024년 9월 11일
1

단위 테스트

  • 일반적으로 작고, 범위가 좁은 테스트를 의미한다.
  • 테스트의 가장 중요한 목적
    • 버그 예방
    • 엔지니어의 생산성 개선

유지보수하기 쉬운 단위 테스트 작성

테스트는 개발자가 믿을 수 있을 때 의미있다. 자주 깨져 생산성을 저하시키는 테스트는 오히려 독이 된다.

유지보수 하기 어려운 테스트(엔지니어의 생산성을 저하시키는 테스트)는 다음 2가지 특징을 가지고 있다.

  • 깨지기 쉬운 테스트 : 검증 대상과 관련 없는 변경 때문에 실패하는 테스트
  • 불명확한 테스트 : 무엇이 잘못되어 실패했는지, 어떻게 고쳐야 하는지를 파악하기 어려운 테스트

깨지기 쉬운 테스트 예방하기 ( 테스트 하고 싶은 것 만 테스트, 많은 로직 넣지 않기 )

  • 이상적인 테스트
    • 한 번 작성한 후로는 대상 시스템의 요구사항이 바뀌지 않는 한 절대 수정할 일이 없어야 한다.
    • ex)
      • 순수 리팩터링(외부 인터페이스는 놔두고 내부만 리팩터링하는 경우) → 테스트는 변경되지 않아야한다.
      • 새로운 기능 추가 → 테스트는 변경되지 않아야 한다. & 새로운 테스트 추가
      • 버그 수정 → 기존 테스트 변경 X & 누락된 테스트 추가
      • 행위 변경 → 기존 테스트 변경
  • 상호작용이 아니라 상태를 테스트하기
    • 상태 테스트 : 메소드 호출 후 시스템 자체를 관찰한다.
    • 상호작용 테스트 : 호출을 처리하는 과정에서 시스템이 다른 모듈들과 협력하여 기대한 일련의 동작을 수행하는지를 확인 한다.
    • 대체로 상호작용 테스트는 상태 테스트보다 깨지기 쉽습니다. 왜냐하면 내부 구현에 의존하기 때문입니다.

명확한 테스트 작성하기

테스트가 실패한다는 건 엔지니어에게 유용한 신호를 주는 것이며, 테스트의 존재 가치를 증명하는 가장 주요한 수단 중 하나이다.

  • 테스트 실패하는 케이스
    • 대상 시스템에 문제가 있거나 불완전함. (테스트가 자신의 역할을 하고 있는 상황)
    • 테스트 자체에 결함이 있는 경우. 이 때 대상 시스템에는 아무런 문제가 없다. (테스트가 깨지기 쉬운 테스트의 경우)

따라서 테스트가 깨지면 위 2 케이스 중 어떤 케이스인지 빠르게 판단해야 한다. 그리고 이 일을 얼마나 빠르게 마치느냐는 테스트의 명확성에 달렸있다.

  • 명확한 테스트 : 존재 이유와 실패 원인을 엔지니어가 곧바로 알아 차릴 수 있는 테스트
  • 완전하고 간결하게 만들기
    • 완전한 테스트 : 결과에 도달하기까지의 논리를 읽는 이가 이해하는 데 필요한 모든 정보를 본문에 담고 있는 테스트
    • 간결한 테스트 : 코드가 산만하지 않고, 관련 없는 정보는 포함하지 않은 테스트
  • 테스트의 구조는 행위가 부각되도록 구성
    • given : 시스템의 설정
    • when : 시스템이 수행할 작업
    • then : 결과를 검증
    • 테스트 이름은 검사하는 행위에 어울리게 짓기
    • 테스트의 이름은 주로 테스트 보고서에 담겨 사람에게 전달되기 때문에 이름이 상세해도 괜찮다.
  • 테스트에 논리를 넣지 말자
    • 테스트 코드에서는 스마트한 로직보다 직설적인 코드를 고집해야 한다.
    • 서술적이고 의미 있는 테스트를 만들기 위한 약간의 중복은 허용하는 것이 좋다.
  • 실패 메시지를 명확하게 작성하자

결론

  1. 안정적으로 서비스를 개발하기 위해선 테스트는 필수
  2. 테스트를 작성할 때 가장 중요한 것은 개발자가 믿을 수 있는 테스트, 개발자의 생산성을 증가시켜주는 테스트를 작성해야 한다.
    • 깨지지 않는 테스트 & 명확한 테스트를 작성해야 한다.
  3. Repository, Service, Controller에 작성되어 있는 다른 메소드들에 대한 성공 테스트 코드를 작성하기.
  4. 실패하는 테스트 시나리오를 작성해 테스트를 만들기.

0개의 댓글