테스트 작성 규칙

정영찬·2024년 8월 30일

테스트 코드

목록 보기
2/9

인터페이스를 기준으로 테스트를 작성할 것

인터페이스란? 서로 다른 클래스 또는 모듈이 상호작용하는 시스템

내부구현에 대한 테스트는 캡슐화를 위반하게되며 깨지기 쉬운 테스트가 된다.

잘못된 테스트 코드

  • 변경되는 상태가 많은 경우 테스트 코드 상에서 일일이 직접 변경해야하며 어떤 상황에서 변경되는 것인지 드러나지 않음
  • 내부 상태나 변수값을 기준으로 검증하다 보니 어떤 것을 검증하는지 테스트 코드만 보고 한눈에 파악이 어려움
  • 내부 구현을 검증하려다 보니 구현에 종속적인 테스트 코드가 양산된다. 상태나 변수명이 하나라도 바뀌면 테스트 코드 모두를 바꿔야하기 때문에 캡슐화를 위반하는 코드가 된다.

올바른 테스트 코드

if('버튼을 누르면 배경이 바뀐다.', () => {
	// 유저의 동작과 비슷하게 클릭 이벤트를 발생
    user.click(screen.getByRole('button'));
}
  • 내부 구현과 종속성이 없어서 캡슐화 위반되지 않음
  • 어떤 기능을 하는지 명확해진다.
  • 테스트를 설명하기 위한 불필요한 설명이 필요없음

커버리지 보다는 의미있는 테스트인지 고민하자.

100% 커버리지를 위해 모든 것을 테스트 코드로 검증하려하면, 그 값에만 의존해 의미있는 테스트 코드를 놓치게 된다.

커버리지란? 테스트 코드가 프로덕션 코드의 몇 %를 검증하고 있는지 나타낸 지표를 뜻하며, 구문, 분기, 함수, 줄 등을 기준으로 한다.

그러면 100% 커버리지는 좋은거 아님?

그렇진 않다.

  • 테스트 작성, 실행, 유지보수 관점에서 비용이 많이 발생한다.
  • 100% 커버리지로 테스트를 작성했다고 한들 잘못된 검증때문에 문제가 발생할 수 있다.
  • ui 렌더링, 간단한 유틸함수 테스트는 오히려 비용낭비이다.

100% 커버리지 보다는
의미 있는 테스트인가?
어떤 범위까지 검증해야 효율적인 테스트인가?

를 고민하는 것이 좋다.

가독성을 높이자.

테스트는 유지보수가 진행됨에 따라 끊임없이 변하기 때문에 가독성이 좋을수록 변화 파악이 용이해진다.

  • 테스트 하고자 하는 내용을 명확하게 작성
// ❌
it('리스트에서 항목이 삭제된다', () => {})

// ✅ 
it('항목들을 체크한 후 삭제 버튼을 누르면 리스트에서 체크된 항목들이 삭제도니다.', () => {})
  • 하나의 테스트에서는 가급적 하나의 동작만 검증할 것

단일 책임 원칙(SRP, Single Responsibility Principle)

모든 클래스는 하나의 책임을 갖고 그와 관련된 책임을 캡슐화하여 변경에 견고한 코드를 만들어야한다.

profile
개발자 꿈나무

0개의 댓글