[개발 도서 리뷰 ] 테스트 주도 개발 1

·2023년 1월 9일
0

개발 도서 리뷰

목록 보기
2/5
post-thumbnail

이 글은 켄트 백의 테스트 주도 개발을 읽고 쓴 내용입니다.

우테코 프리코스를 진행하면서 가장 어려웠던 부분은 TDD였다. jest에 대해서 잘 모르니까 테스트 코드 자체를 작성하는 것도 어려웠고 특히나 테스트 코드를 어느 정도 짜야 하는지 감이 오지 않았다. 그래서 구체적인 테스트 코드를 짜는 방법에 대해 궁금해졌고, 이 책을 읽게 되었다. 내가 테스트 코드를 짰던 경험을 바탕으로 인상 깊었던 부분을 간략하게 정리해 보려고 한다. 1부만 정리하는 이유는 내가 자바를 잘 몰라서 속도가 잘 안나고 😓 이러다 결국 안 쓸까봐 나눠서 정리한다.


1. 테스트 코드 실행 주기

저자가 테스트 코드를 실행하는 주기를 기록했는데, 약 1분에 한 번 정도 테스트를 실행했다고 한다. 프로그래밍에 익숙한 사람이라 속도가 빠른 것도 있겠지만, 피드백 주기를 이정도로 짧게 하기 위해서 할 일 목록을 엄청 세분화했구나 싶었다.

2. 할일 목록 만들기

나는 기능 목록을 만들었기 때문에 기능 단위로 테스트를 만들고 구현하려고 노력하였다. 하지만 저자는

  • 85 + 10CHF = $10(환율이 2:1일 경우)
  • $5 × 2 = $10
  • amount를 private로 만들기
  • Dollar 부작용(side effect)?
  • Money 반올림?

기능 목록을 조금 더 세분화한 다음, 해결하기 쉬운 것부터 조금씩 해결해 나간다. 나는 도메인 로직이 중요하다고 생각해 그것부터 붙잡고 해결하려고 했는데, 시간이 많이 들었던 원인인 듯 하다.

3. 가짜로 구현하기

TDD의 기초는 테스트를 작성하고, 실행 가능하게 만든 뒤 올바르게 만드는 것이라고 한다. 나는 이 실행 가능하게 만든다는 부분을 어찌되었든 기능 목록에서 요구하는 것에 맞게 제대로 작동하게 만들려고 노력했기 때문에 시간이 많이 걸렸다. 하지만 저자가 말하는 방법은 가짜로 상수를 넣어서라도 돌아가게 만든 뒤 점점 일반화하는 것이다.

예를 들어,

public void testMultiplication () {
  Dollar five= new Dollar (5);
  five.times (2);
  assertEquals (10, five.amount);
}

위의 테스트를 통과하기 위해서 간단히 아래의 테스트를 작성하였다.

//Dollar 

int amount;

void times (int multiplier) {
  amount = 5 * 2;
}

원래는 인수를 받아서 인수만큼 곱하는 것이지만, 그냥 5 * 2라는 상수를 반환시켜서 테스트를 통과시켰다. 이것을 조금씩 일반화하는 것이다.

4. 명백하게 구현하기

이 방법은 내가 여태까지 했던 방법으로, 그냥 쉽게 일반화할 수 있는 방법이 떠오르면 바로 일반화하여 테스트를 통과하게 만드는 것이다. 저자는 가짜로 구현하기와 명백하게 구현하기를 상황에 맞게 사용하라고 알려 준다. 자신이 어떻게 구현할 지 확신이 든다면 바로 일반화하여 테스트를 통과한다. 어떻게 할 지 방법이 떠오르지 않는다면 가짜로 구현하기와 삼각측량법을 이용한다.

5. 삼각측량법

만약 라디오 신호를 두 수신국이 감지하고 있을 때, 수신국 사이의 거리가 알려져 있고 각 수신국이 신호의 방향을 알고 있다면, 이 정보들만으로 충분히 신호의 거리와 방위를 알 수 있다(당신이 나보다 삼각법에 대해 더 잘 기억하고 있다면). 이 계산법을 삼각측량이라고 한다.

말이 어렵지만 일반화하는 방법이라고 생각한다.

우리가 5달러라는 객체를 만들 때, 5달러 객체는 여러 번 만들어도 똑같이 5달러여야 한다. 따라서 이 테스트 코드를 통과해야 한다.

public void testEquality () {
assertTrue (new Dollar (5) .equals(new Dollar (5)));
}

이 테스트 코드를 통과하기 위해서라면 Dollar 객체에서 상수를 반환해도 테스트 코드를 통과할 수 있다.

하지만 실제 세계에서, 5달러는 6달러와는 다르다. 따라서 아래의 테스트 코드도 통과해야 한다.

public void testEquality () {
assertFalse (new Dollar (5) .equals(new Dollar (6)));
}

이 두 가지의 테스트 코드를 통과하기 위해서 일반화를 하면, 결국 일반화된 코드가 나온다. 저자는 오로지 예가 두 가지 이상일 때만 추상화를 하라고 제안한다.

6. 중복 제거하기

이런 식으로 진행하다 보면 테스트코드와 코드 사이에 중복이 생기게 된다. 예시가 너무 복잡해서 들고 오지는 않았지만, 그 중복을 제거해나가다 보면 코드가 완성된다.


이 이후부터는 계속해서 우리가 보통 알고 있는 테스트 추가 -> 테스트가 실패하도록 만들기 -> 수정 -> 테스트 성공 확인 -> 중복 제거를 위한 리팩토링의 TDD 과정의 연속이다. 실제 TDD 과정을 확인해보고 싶었는데, 좋은 참고가 되었다.

TDD 과정을 보다보니 할 일 쪼개서 능률을 높이는 방법이랑도 유사하다. 이걸 실제 생활에 적용해 봐도 효율을 늘릴수 있겠다 싶다.

이론상으로 참고할 부분이 생겼으니 앞으로는 실제로 적용해볼 차례이다! TDD의 적용 사례에 대해서도 쓸 수 있었으면 좋겠다 😁

profile
전 이것도 몰라요

0개의 댓글