CleanCode(클린코드) - 9장. 단위테스트

🔖 오늘 읽은 범위 : 9장 - 단위테스트



😃 책에서 기억하고 싶은 내용을 써보세요.

TDD 법칙 세 가지

  1. 실패하는 단위 테스트를 작성할 때까지 실제 코드를 작성하지 않는다.
  2. 컴파일은 실패하지 않으면서 실행이 실패하는 정도로만 단위 테스트를 작성한다.
  3. 현재 실패하는 테스트를 통과할 정도로만 실제 코드를 작성한다.

위 세 가지 규칙을 따르면 실제 코드를 사실상 전부 테스트하는 테스트 케이스가 나온다. 하지만 실제 코드와 맞먹을 정도로 방대한 테스트 코드는 심각한 관리 문제를 유발하기도 한다.

깨끗한 테스트 코드 유지하기

  • 테스트 코드는 실제 코드 못지 않게 중요하다. 테스트 코드는 사고와 설계와 주의가 필요하다. 실제 코드 못지 않게 깨끗하게 짜야 한다.
  • 테스트는 유연성, 유지보수성, 재사용성을 제공한다.

    • 코드에 유연성, 유지보수성, 재사용성을 제공하는 버팀목이 바로 단위테스트다.
    • 테스트 코드가 지저분하면 코드를 변경하는 능력이 떨어지며 코드 구조를 개선하는 능력도 떨어진다.
    • 테스트 코드가 지저분할수록 실제 코드도 지저분해진다. 결국 테스트 코드를 잃어버리고 실제 코드도 망가진다.

깨끗한 코드

  • 깨끗한 테스트 코드를 만들려면 가독성이 필요하다.
  • BUILD-OPERATE-CHECK 패턴이 테스트 구조에 적합하다. 각 테스트는 명확하게 세 부분으로 나눠진다.

    • 테스트 자료를 만든다.
    • 테스트 자료를 조작한다.
    • 조작한 결과가 올바른지 확인한다.

이중 표준

  • 실제 환경에서는 절대로 안 되지만 테스트 환경에서는 전혀 문제없는 방식이 있다. 대개 메모리나 CPU 효율과 관련 있는 경우다. 코드의 깨끗함과는 철저히 무관하다
  • 컴퓨터 자원과 메모리가 제한적일 가능성이 높지만, 테스트 환경은 자원이 제한적일 가능성이 낮다.

테스트 당 assert 하나

  • assert 문이 단 하나인 함수는 결론이 하나라서 코드를 이해하기 쉽고 빠르다.
  • given-when-then 이라는 관례를 사용하면 테스트 코드를 읽기가 쉬워진다.
  • 테스트를 분리하면 중복되는 코드가 많아지는데, 이 때는 TEMPLATE METHOD 패턴을 사용하면 중복을 제거할 수 있다.

    1. given/when 을 부모 클래스에 두고 then 을 자식 클래스에 둔다.
    2. given/when 을 @Before 함수에 넣고, @Test 함수에 then 을 넣어도 된다.

테스트 당 개념 하나

  • 테스트 함수마다 한 개념만 테스트하라
  • 개념 당 assert 문 수를 최소로 줄여라

F.I.R.S.T

깨끗한 테스트는 다음 다섯 가지 규칙을 따르는데, 각 규칙에서 첫 글자를 따오면 FIRST 가 된다.

  1. Fast : 테스트는 빨리 돌아야 한다. 테스트가 느리면 자주 돌릴 엄두를 못 낸다. 자주 돌리지 않으면 초반에 문제를 찾아내 고치지 못한다.
  2. Independent : 각 테스트는 서로 의존하면 안 된다. 각 테스트는 독립적으로 그리고 어떤 순서로 실행해도 괜찮아야 한다.
  3. Repeatable : 테스트는 어떤 환경에서도 반복 가능해야 한다.
  4. Self-Validating : 테스트는 bool 값으로 결과를 내야 한다. 성공 아니면 실패다.
  5. Timely : 테스트는 적시에 작성해야 한다. 단위 테스트는 테스트하려는 실제 코드를 구현하기 직전에 구현한다.

결론

테스트 코드는 지속적으로 깨끗하게 관리하자. 표현력을 높이고 간결하게 정리하자. 테스트 API 를 구현해 도메인 특화 언어를 만들자.


🤔 오늘 읽은 소감은? 떠오르는 생각을 가볍게 적어보세요

  • 테스트는 유연성, 유지보수성, 재사용성을 제공한다는 것을 명심하고 테스트 코드를 작성하는 것을 필수로 해야 한다.
  • 그렇지만 컴포넌트와 의존성이 강한 함수는 어떻게 테스트를 할 수 있을까? 시각적 요소를 자동화하기라는 주제로 강연이 있었는데 그걸 얼른 봐야겠다.

테스트 코드는 작성하다보면 깔끔하게 작성하기가 어려울 때가 많다. 테스트 당 개념 하나를 놓치고 생각대로 작성했기에 그렇게 작성할 수 밖에 없었던게 아닐까.

오늘부터 다시 알고리즘을 풀면서 테스트 코드를 좀 더 깨끗하게 작성하는 방법을 익혀봐야겠다.

FIRST 전략 중 가장 공감이 되는 부분은 Fast 이다. 이전에 오픈소스에 기여할 때, 특정 테스트는 오래 걸려서 테스트 돌릴 때 빼고 돌리는 형태로 작업을 했었다. 작업할 때 돌리지 못한 테스트는 Pull Request 시에 테스트 할 수 있었는데 이 부분을 작업하면서 같이 돌릴 수 있으면 좀 더 많은 범위를 테스트할 수 있지 않았을까 아쉬움이 남는다. (테스트 코드 경험이 많지 않아서 작성한 예시는 매번 돌리지않아도 되는 테스트였을 수 있다.)


🔎 궁금한 내용이 있거나, 잘 이해되지 않는 내용이 있다면 적어보세요.

템플릿 메소드 패턴

알고리즘의 구조를 메소드에 정의하고, 하위 클래스에서 알고리즘 구조의 변경없이 알고리즘을 재정의하는 패턴

알고리즘이 단계별로 나누어지거나, 같은 역할을 하는 메소드이지만 여러곳에서 다른 형태로 사용이 필요한 경우 유용한 패턴이다.

참고: https://yaboong.github.io/design-pattern/2018/09/27/template-method-pattern/

BUILD-OPERATE-CHECK 패턴

Build - 테스트 시나리오를 준비하는 단계

Operate - 메서드를 실행하는 단계

Check - 실행된 메소드의 결과가 예상했던 것과 일치하는지 확인한다.

https://medium.com/swlh/usual-production-patterns-applied-to-integration-tests-50a941f0b04a


🔥 소감 3줄 요약

  • 깨끗한 테스트 코드를 만들려면 가독성이 필요하다.
  • 코드에 유연성, 유지보수성, 재사용성을 제공하는 버팀목이 바로 **단위테스트**다.
  • TDD 법칙 3가지 명심하자.
  • 테스트 함수마다 한 개념만 테스트하라
  • 깨끗한 테스트는 F.I.R.S.T 전략을 따른다
  • 테스트 코드를 작성하는 것에만 집중하지말고, 지속적으로 깨끗하게 관리하자

Written by@sujin-park
항상 배우는 자세 갖추기 💻

GitHubLinkedIn