무엇을 테스트 할 것인가? - (1)

dongbin_Shin·2021년 11월 28일
0

Test

목록 보기
6/7
post-thumbnail

테스트를 작성할수록 테스트를 얼마나 자세하게, 어떤 것을 테스트 해야하는 지 등의 고민이 점점 커졌다.

그렇게 레퍼런스를 찾던 중 2019년에 진행된 스프링캠프에서 진행된 좋은 세션을 발견했다. 개인적으로 정말 좋은 강연이라는 생각이 들었다. 강연을 듣으며 테스트에 대한 기준을 정리해보았다.

테스트로 얻을 수 있는 것

테스트 작성으로 우리는 마음의 안정과 자신감을 가질 수 있다.

그렇다면 이 안정감과 자신감을 누구에게 주어야 하는가?

바로 "현재와 미래의 나""현재와 미래의 동료" 이다.

테스트를 작성할 때 나 뿐만 아니라 같이 일하는 동료를 위해 테스트를 짠다는 생각을 갖고 작성하면 더 좋은 테스트를 작성할 수 있다.

무엇을 테스트할 것인가?

만약 우리에게 로또를 구현하라고 과제가 주어진다면 우리는 먼저 비즈니스 요구사항을 정리해야 한다.
1. 6개의 숫자 반환
2. 중복되지 않은 숫자
3. 랜덤 반환

generateTicket() 메소드를 통해 6개의 랜덤 숫자를 뽑아 반환하는 로직과 그에 대한 테스트이다.

로직상으로 보면 Set으로 구현을 했기 때문에 중복이 나올 수는 없다.

그렇다고 이에 대한 테스트를 생략해도 되는 것일까??

결론부터 말하면 생략하면 안된다이다.

원칙 1. 설계사항을 테스트

우리는 테스트할 때 항상 아래와 같은 생각을 갖고 작성해야 한다.

만약 위의 로직이 미래에 아래와 같게 바뀐다면 어떻게 될까?

기존에 Set 자료형으로 반환하던 로직에서 List 자료형으로 반환하는 로직으로 변경되었다.

이렇게 되면 비즈니스 로직을 만족하지 않는데도 불구하고 테스트가 성공된다.

곧바로 위의 잘못된 코드는 배포되어 서비스 장애로 이어지게 될 것이다.

만약 중복 여부 테스트도 작성되면 아래처럼 테스트 오류로써 사전의 서비스 장애를 막을 수 있게 될 것이다.

즉, 우리는 구현을 검증하는 테스트가 아니라 사전에 갖고 있던 비즈니스 요구사항에 대한 검증을 하는 테스트를 작성해야 한다.

비즈니스 설계 테스트 요령

아래는 구현을 검증하는 잘못된 테스트 설계이다.

그렇다면 이런 상황에서 우리는 어떻게 테스트를 해야 할까?

어떤 행위를 했을 때 그 케이스에 대한 비즈니스적 설계사항을 테스트하는 것이다.

내부의 메소드까지 들여다 보며 테스트를 작성할 필요가 없이 단지 기존에 있던 플로우에서 요구사항에 따른 테스트 케이스만 더 추가하면 된다.

만약 이렇게 코드를 작성했는데 어딘가 이상한 부분이 있다면 내부적인 private 메소드가 사실은 개별적으로 특정 비즈니스 케이스를 갖는 외부 메소드로 작성되어야 할 가능성이 크다고 봐야 한다.

원칙 2. 테스트할 수 있는 것을 테스트

"항상 성공 가능한, 동일한 결과가 나올 수 있는 것을 테스트하자!"

아래의 그림은 내부에 Non-Testable한 메소드가 있을 때 감싸고 있는 전체 메소드도 모두 테스트할 수 없게 됨을 표현한 그림이다.

Non-Testable는 다른 말로 제어할 수 없는 영역을 테스트하지 못한다는 의미이다.

Non-Testable

  • Random, Shuffle, LocalDate.now()
  • 외부 세계
    • HTTP
    • 외부 저장소

"제어할 수 없는 영역은 같은 결과를 보장할 수 없다"

이에 따라 앞의 로또 예시에서 3. 랜덤 반환 은 요구사항을 잘못 도출했다고 볼 수 있다. 이때는 3. 의도한 전략대로 반환 으로 요구사항을 수정하여 Testable하게 바꾸어야 한다.

Reference

스프링캠프 2019: 무엇을 테스트할 것인가? 어떻게 테스트할 것인가? (feat. 권용근님)

profile
멋있는 백엔드 개발자

0개의 댓글