NEXT STEP/ATDD, 클린 코드 with Spring 5기

[ATDD] 단위 테스트

샤아이인 2022. 7. 16.

이번 글에서는 단위 테스트에 대하여 고민해보는 시간이다.

 

1. 단위 테스트

보통 단위 테스트라는 단어를 들으면 다음과 같은 그림이 떠오른다.

출처 - NextStep ATDD 류성현

각각의 테스트가 Production Code의 부분 부분들을 검증하고 있다.

 

1) 작은 코드 단위를 검증하며

2) 빠르게 수행 가능하고

3) 격리된 방식으로 처리된다면

단위테스트라 할 수 있을 것이다. (여기서 격리된 방식의 의미가 중요한데, 이는 뒤에서 알아보자!)

 

이쯤 되서 다음 코드를 살펴보자!

위 테스트는 단위 테스트 일까? 아닐까? 2가지 생각이 가능하다.

 

1) Station과 Line의 기능 모두를 검증하는 테스트는 단위 테스트가 아니라 통합 테스트 아닌가?

2) 여러 객체가 사용되었지만 구간 추가라는 하나의 기능을 검증하는 테스트이니 단위 테스트 아닌가?

 

이를 이해하기 위해 테스트의 종류에 대하여 알아볼 필요가 있다.

 

2. 테스트의 종류

테스트에는 크게 통합테스트(Sociable Test)고립테스트(Solitary test)가 있다.

협력 객체를 실제 객체로 사용하는 테스트를 통합 테스트(Sociable Test),

협력 객체를 Test Double(대역)을 사용하는 테스트를 고립 테스트(Solitary Test)라 부른다.

 

3. 테스트를 바라보는 두 관점 (Classist vs Mockist)

테스트를 바라보는 관점 또한 크게 2가지로 나뉠 수 있다.

위에서 언급한적이 있는데, 격리된 방식이 어떤 의미가 있는지 생각해본 적이 있는가?

 

이 격리된 방식의 의미에 따라 2가지 종류로 나뉜다.

1) 테스트 대상과 협력 객체 간의 격리

2) 테스트와 테스트 간의 격리

 

3-1) Classist의 단위 테스트

Classist는 테스트를 격리해야 하는 대상은 코드가 아니라, 또 다른 테스트라 생각한다.

즉, 테스트와 테스트의 격리가 "격리"의 의미라 생각한다.

 

따라서 각 테스트간에 공유하는 의존성이 아니라면 실제 객체를 사용해도 상관없다.

 

Classist가 생각하는 단위 테스트란 위와 같은 테스트 일 것이다.

 

3-2) Mockist의 단위 테스트

테스트 대상을 협력 객체로부터 격리하기 위해 테스트 대상이 의존하는 모든 것을 가짜 객체로 대체한다.

Mockist가 생각하는 단위 테스트란 위와 같은 것이다.

(참고로 나는 Mockist 쪽이다, 개인적으로는 테스트 환경은 개발자가 컨트롤 가능하도록 외부의 부차적인 의존성들을 끊어야 한다고 생각한다)

 

아까 위에서 살펴본 Line, Station이 나오는 테스트는 Mockist 입장에서 통합 테스트라 생각하게 된다.

Line과 Station 모두 잘 동작하는지 검증하기 때문이다.

 

4. TDD의 접근 방식

4-1) Classical TDD

 

  • 실제 객체를 다뤄야 하기 때문에 도메인 모델로부터 시작한다.
  • 의존하는 협력 객체가 실제 존재해야 테스트를 작성할 수 있다.
  • 도메인 설계가 충분히 이루어진 다음에 진행 가능하다.

▶ 장점

프로덕션 코드에 덜 의존적인 테스트가 작성된다.

 

▶ 단점

TDD 사이클을 이어나가기가 상대적으로 어렵다.

 

4-2) Mockist TDD

  • 상위 레벨 테스트부터 시작한다.
  • 테스트 더블을 활용하여 테스트 대상이 의존하는 협력 객체의 예상 결과를 정의한다.
  • 다음 사이클로 테스트 더블로 미리 정의한 협력 객체를 테스트 대상으로 한다.

▶ 장점

OOP와 TDD가 익숙하지 않은 사람들에게 가이드할 때 도움이 된다.

도메인에 대한 이해도가 높지 않은 상태에서도 진행이 가능하다.

 

▶ 단점

상대적으로 프로덕션 코드에 의존적인 테스트가 작성된다 (깨지기 쉬운 테스트)

왜냐하면 협력 객체의 행위를 Test에서 직접 지정하기 때문이다. Test Double을 만들기 위해서는 프로덕션 코드에 대한 이해 또한 높아야 한다.

 

4-3) 어떤 방식을 선택해야 하는가?

위 2가지 방식 중 정답은 없다.

 

아는 것에서 모르는 것으로

 

[Test-Driven Development, kent beck]
사실은 상향식, 하향식 둘 다 TDD의 프로세스를 효과적으로 설명해 줄 수 없다.
... 만약 어떤 방향성을 가질 필요가 있다면 아는 것에서 모르는 것으로(known-tounknown) 방향이 유용할 것이다.

 

꼭 Inside Out방법과 OutSide In방식 중에서 골라야 하지 않아도 된다는 말이다.
테스트 방향성을 잡을 때 내가 아는 부분에서부터 테스트를 시작해 나가자!~~

댓글