[클린코드] 9장 : 단위 테스트

목록으로 돌아가기
  • 단위테스트란
    • 하나의 모듈을 기준으로 독립적으로 진행되는 가장 작은 단위의 테스트다.
    • 하나의 모듈이란 하나의 기능 또는 클래스가 될 수 있다.
    • 오랜 기간 단위테스트는 단순히 자기 프로그램이 돌아가는 것에 대한 확인에 불과했다.
    • 현재는 애자일 방법론과 TDD로 인해 단위 테스트를 자동화하여 개발을 진행하는 프로그래머가 많아졌다.
    • 하지만 많은 프로그래머 다수가 급하게 코드를 작성하고 앱을 만드는 바람에 제대로 된 테스트 케이스를 작성하지 않고 있다.
    • 테스트는 또한 유연성, 유지보수성, 재사용성을 제공한다.
      • 테스트가 있다면 코드 변경이 수월해지며, 테스트 커버리지가 높을수록 변경에 대한 공포가 줄어들 것이다.

  • TDD란
    • 테스트 주도 개발의 영문 약어로, 반복 테스트를 이용한 소프트웨어 방법론 중 하나다.
    • 단위 테스트 케이스를 작성하고 이를 통과하는 코드를 추가하는 단계를 반복하여 구현한다.
    • 실패하는 테스트 코드를 먼저 작성하고, 실제 코드를 작성한다.
    • 테스트 코드를 성공시키면 중복 코드를 제거하고, 일반화 및 리팩토링을 진행한다.

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

    ⇒ 테스트 코드와 실제 코드는 함까 나오며, 불과 몇 초 차이로 테스트 코드가 먼저 나온다. 많은 수의 테스트를 진행하면 실제 코드를 전부 테스트 가능한 코드를 작성하게 된다. 하지만 너무 많은 테스트 코드는 관리 문제를 유발한다.



  • 깨끗한 테스트 코드 유지
    • 실제 코드가 변경되면 테스트 코드도 함께 변경하여야 한다.
    • 그러므로 테스트 코드를 지저분하게 관리하는 경우, 관리에 어려움을 느끼게 된다.
    • 테스트 코드가 지저분하다면 코드 수정에 많은 시간을 할애하게 되며, 테스트를 통과시키기 점점 어려워진다.
    • 이로 인해 테스트 슈트를 폐기해야할 수 있다.
    • 그리하여 테스트 코드는 실제 코드와 동등하게 깔끔함을 챙겨야하며, 이를 위해 사고와 설계, 주의가 필요하다.

  • 깨끗한 테스트 코드
    • 테스트 코드를 깨끗하게 만들려면 가독성이 상당히 중요하다. 이를 위해 단순성, 명료성, 풍부한 표현력이뒷받침해주어야한다. → 최소한의 표현으로 많은 것을 보여줘야한다.
    • BUILD-OPERATE-CHECK 패턴
      • 테스트 자료를 만든다. → 조작한다. → 결과가 올바른지 확인한다.
      • 이러한 패턴이 사용되면 코드를 읽는 사람은 코드가 수행하는 기능을 빠르게 이해할 수 있다.
    • 도메인에 특화된 테스트 언어
      • 테스트 코드를 구현하는 기법에 사용되는 언어 중 하나
      • 테스트를 구현하는 개발자와 이 테스트를 볼 사람을 도와주는 언어.
    • 이중 표준
      • 실제 환경과 테스트 환경이 다름을 인정하고 테스트 시 표준을 폭넓게 인정해줌
      • 코드의 효율 및 자원의 제한은 실제 환경에서보다 테스트 환경에서 후하게 인정한다.
      • 이는 코드의 깨끗함과는 무관하나, 가독성을 높이는 대에는 좋을 수 있다.

  • 테스트 당 assert 하나
    • assert를 단 하나만 사용해야 한다고 주장하는 학파가 있다.
    • 이들의 장점은 결론이 하나기 때문에 코드를 이해하기 빠르고 쉽다는 점이 있다.
    • 하지만 이는 중복되는 코드가 많아질 위험이 있다.
    • 위의 학파는 주로 given-when-then 관례를 사용한다.
    • TEMPLATE METHOD 패턴을 사용하여 given when을 부모 클래스에 두고, then을 자식 클래스에 두는 방식으로 중복 코드를 해결할 수 있다.
    • 하지만 노력이 더 크게 들어가기 때문에 차라리 assert를 여러개 두는 것을 허용하지만, 그 개수를 최소한으로 사용하려는 노력이 더 좋다.
    • 차라리 하나의 assert를 허용하는 것 보다 테스트 함수마다 하나의 개념만 테스트하게끔 하는 것이 더 낫다.
      • 많은 개념을 중복하여 연속하여 테스트하는 것을 피하는 것이 더욱 좋다.

    ⇒ ‘개념 당 하나의 assert문 수를 최소로 줄이며, 테스트 함수 하나에 개념 하나만 테스트하라’ 라는 규칙을 만들 수 있다.



  • FIRST
    • 깨끗한 테스트는 다음과 같은 다섯 가지 규칙을 따른다.
      1. Fast (빠르게)
      • 테스트를 자주 돌려야하기 때문에 속도가 빨라야한다.
      • 그렇지 않으면 초반에 문제를 찾기 어렵다. 2. Independent (독립적으로)
      • 각 테스트는 서로 의존하면 안 된다.
      • 각 테스트는 어떤 순서로 실행해도 서로 간섭을 일으키면 안된다.
      • 의존성을 띄면 한 테스트의 실패가 다른 테스트의 실패를 불러오므로 원인 진단에 어려움을 겪는다. 3. Repeatable (반복 가능하게)
      • 어떠한 환경에서도 반복이 가능해야한다.
      • 여기서 환경이란 실제 환경, QA, 퇴근길 등 테스트 가능한 모든 환경을 일컫는다. 4. Self-Validating (자가 검증하는)
      • 테스트는 boolean 값으로 결과를 출력해야한다. → assert문 사용
      • 테스트는 스스로 통과 여부를 파악해야하며, 사람의 주관이 들어가선 안된다.
      • 로그 파일 및 텍스트 파일을 비교 및 읽게 해서는 안된다. 5. Timely (적시에)
      • 테스트하려는 실제 코드를 구현하기 전에 단위 테스트를 작성해야한다.
      • 실제 코드를 구현한 다음 테스트 코드를 작성하면, 실제 코드가 테스트하기 쉽게 만들어진다.
      • 또한 테스트가 불가능하도록 실제 코드를 작성할 수 있는 위험을 방지해야한다.
author-profile
Written by 상 한규

댓글