ATDD에서 TDD

PPakSSam·2022년 1월 30일
1
post-thumbnail


1주차에서는 ATDD 개발 사이클 중 인수테스트 부분에 집중을 했었다.


2주차에서는 인수테스트를 작성한 후TDD를 적용하는 부분에 대해서 자세하게 배우게 되었다. 그래서 이에 대해서 정리를 해보고자 한다.

단위 테스트


1. 단위 테스트의 정의

단위 테스트란 작은 코드 조각(단위)을 검증하는 테스트를 말한다.

단위 테스트의 특징으로는 다음이 있다.

  • 빠르게 수행 가능하다.
  • 격리된 방식으로 처리한다.

2. 단위 테스트의 구분 기준

위의 테스트를 보고 혹자는 다음과 같이 생각할 수 있고

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

혹자는 다음과 같이 다른 생각을 할 수 있다.

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

여기서 협력 객체란 Line의 기능 검증을 위해 필요한 Station 객체(강남역 등)를 뜻한다.

협력 객체를 실제 객체로 사용하는지 Mock(가짜) 객체로 사용하는지에 따라 테스트 구현이 달라진다.

협력 객체를 실제 객체로 사용하는 테스트를 통합테스트(Sociable Test), Mock(가짜)객체를 사용하는 테스트를 고립테스트(Solitary Test)라 부른다.

또한 통합테스트를 Classist의 단위 테스트라고 하고, 고립 테스트를 Mockist의 단위 테스트라고 한다.

3. 통합 vs 고립

협력 객체를 실제 객체로? 가짜 객체로?

  • 실제 객체를 사용하면 협력 객체의 행위를 협력 객체 스스로가 정의한다.

  • 가짜 객체를 사용하면 협력 객체의 행위를 테스트가 정의한다.

가짜 객체(테스트 더블)를 사용할 경우

  • 고립 테스트를 하는 경우 테스트 대상을 검증할 때 외부 요인(협력 객체)으로 부터 철저히 격리한다.

  • 하지만 테스트가 협력 객체의 상세 구현을 알아야 한다.

  • 외부 요인으로 부터 철저히 격리하므로 실제 객체를 사용할 때보다 조금 더 편하게 작성할 수 있는 장점이 있다.

  • 상세 구현에 의존하는 테스트가 될 수 있다는 단점이 있다.


※ 테스트 더블이란

실제 객체 대신 사용되는 모든 종류의 객체에 대한 일반 용어이다.
즉 실제(클래스, 모듈 또는 함수)를 가짜 버전으로 대체한다는 의미이다.



실제 객체를 사용할 경우

  • 실제 객체를 사용할 경우 협력 객체의 상세 구현에 대해서 알 필요가 없다.

  • 하지만 협력 객체의 정상 동작 여부에 영향을 받는다.



TDD의 접근 방법


1. Classical TDD (Inside Out)

  • 실제 객체를 다뤄야 하기 때문에 도메인 모델로부터 시작한다.

  • 의존하는 협력 객체가 실제 존재해야 테스트를 작성할 수 있다.

  • 도메인 설계가 충분히 이루어진 다음에 진행 가능하다.

장점

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

단점

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

2. Mockist TDD (Outside In)

  • 상위 레벨 테스트 부터 시작한다.

  • 테스트 더블을 활용하여 테스트 대상이 의존하는 협력 객체의 예상 결과를 정의한다.

  • 다음 사이클로 테스트 더블로 미리 정의한 협력 객체를 테스트 대상으로 한다.

장점

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

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

단점

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

3. 어떤 방법을 선택해야 하는가

아는 것에서 모르는 것으로

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

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

추천하는 방법

  • Top-Down으로 방향을 잡고, Bottom-Up으로 구현하기

  • 인수 테스트 작성을 통해 요구사항과 기능 전반에 대한 이해를 얻고

  • 위에서부터 아래로 테스트를 진행해 나가면서 설계 흐름을 구상한다.

  • 설계가 끝나면 도메인부터 차근차근 TDD로 기능 구현한다.

profile
성장에 대한 경험을 공유하고픈 자발적 경험주의자

0개의 댓글