[tdd] 테알못 신입은 어떻게 테스트를 시작했을까? 리뷰

https://www.youtube.com/watch?v=1bTIMHsUeIk

방법에 대한 이야기

RED에서 시작할 수도 있고, GREEN 에서 시작할 수 있다.
여기서 RED는 버그가 있어서 RED인 것이고, TDD의 RED는 아직 코드가 없기 떄문에 RED이다

테스트 라스트 방식

이미 구현되어 있는 코드에 테스트를 붙이는 방식

테스트하기 쉬운 코드로 시작한다

  • 순수함수로 만들어져 있다
  • 외부 의존성이 전혀 없다
  • 인풋과 아웃풋이 명확한 단순한 기능들(유틸리티 같은)
  1. 프로덕션 코드는 아무것도 수정하지 않고, 함수에 제대로된 인풋에 제대로된 아웃풋이 나오는지 테스트하는 것을 먼저 만든다
  2. 리팩토링을 한다
  3. 테스트 코드는 수정하지 않고 프로덕션 코드를 수정한다

이제 테스트하기 어려운 코드를 리팩토링 한다

  • 중요도가 높은 비즈니스 로직
  • 버그가 발견된 부분
  • 결합이 낮고 논리는 복잡한 부분

여기서 쉽게 테스트할 수 있는 부분을 분리해서 테스트한다

  1. 테스트하기 어려운 코드에서 테스트 가능한 코드를 찾는다
  2. 이를 분리한다
  3. 테스트코드를 추가하고 GREEN이 되도록 만든다
  4. 리팩토링 한다
  5. 1~4를 계속 반복한다

예시

전달받은 정보를 validate 한 뒤
api를 요청하고, 요청이 끝나면 모달창을 닫는다
api 요청은 테스트하기 너무 어렵지만, 위의 validate는 테스트하기 쉽다
그 부분을 함수로 빼고 테스트를 만든다.
여기서 테스트가 실패하는데, 이는 외부 의존성이 남아있었기 떄문이다.
이를 파라미터로 받는 형태로 바꿔서 독립적인 함수로 변형시킬 수 있다
이제 스팩을 추가하고(나와야 하는 결과들) 해당 테스트가 성공하도록 하고,
리팩토링 하면 된다

TDD

Test LAST와 달리 이미 구현되어 있는 코드가 없다
신규 요구사항에 대한 개발을 말한다

  1. 요구사항에 맞춘 테스트를 먼저 작성한다
    • 이미 구현되어 있는 코드가 없으므로 무조건 RED 부터 시작한다
  2. 테스트에 맞춰 기능을 개발한다
  3. GREEN 이 뜨면 테스트는 손대지 않고 프로덕션 코드를 리팩토링한다
  4. 이를 반복한다

경험에 대한 이야기

좋은점

  • 불안감소

  • 스펙문서기능

    • 본인이 만든 함수의 세부사항을 다 기억하는 사람은 없다
    • 함수를 다시 읽는것보단 테스트를 읽는것이 훨씬 빠르다(스펙의 역할을 한다)
  • 디자인 개선 효과

    • 하나의 함수가 여러가지 역할을 수행하고 있는지 체크할 수 있다
  • 학습 동기부여

    • 디자인 개선을 하다보면 내가 얼마나 디자인을 못하게 되는지 알게 된다
    • 그래서 설계에 계속 관심을 가지게 된다
    • 이게 학습이다!
  • 개발 생산성 향상

    • 통합테스트는 손해보는 시간
    • 테스트 안해서 아낀 시간(테스트 작성 시간) < 테스트 안해서 나온 버그 고치는 시간
    • 비즈니스 로직의 허점을 미리 발견할 수 있다
      • 스펙에 대해서 많이 생각하게 되기 떄문이다
      • 코딩하기 전에 발견할수 있어서 아끼는 비용이 많다
  • 집중력 향상

    • TDD는 죽었다에 대한 켄트백의 말
      • 나는 내가 필요하게 될 거라고 알고 있는 기능을 추가하려는 성향이 있다.
      • 하지만 하나의 빨간 테스트를 녹색으로 만드는 것을 딱 충분한 만큼 구현하도록 도와준다.
      • 집중을 유지할 새로운 방법을 찾아야한다.
    • 실제로도 테스트(스펙)을 정해놓으면 내가 구현해야 할 기능에 집중할 수 있다

실수

테스트 자체가 목적이 되어서(커버리지를 높이자!) 테스트를 막 찍어내는 상황

  • 불필요한 테스트

    • 비즈니스와 관련된 버그를 낼 가능성이 낮거나 없음
    • 테스트를 유지함으로써 얻는 이익 < 테스트 유지와 관리에 드는 비용
    • 테스트가 단언하고 있는 내용이 사용자에게 중요한 가치를 주는것이 아닐 때
      • 이때 div가 몇개 나오게 되고, div 안에는 p가 몇개고… 같은 테스트
        • 이런것은 사용자의 관심이 아니다
        • 이런것까지 굳이 테스트 할 필요는 없다
  • 필요하지만 검증방식이 잘못된 테스트

    • DOM 구조에 의존한 테스트
      • div의 첫번째 자식에 이러이러한 테스트가 있다 등
    • 사용자에게 주는 가치가 낮고, 테스트를 유지하는 비용이 더 큰 경우
    • 특정 위치를 찝어서 검사하는 형태보단, 의존관계를 줄이는 방식으로 테스트를 개선한다(DOM구조 의존 제거)
  • 검증력이 떨어지는 테스트

    • 테스트가 원하는 결과가 나올수 있는 상황이 여러가지 일때
      • 우리가 원하지도 않는 형태에서 우리가 원하는 결과 발생
      • e.g. expect 값이 undefined
  • 테스트 제목과 검증의 불일치

    • e.g. 전체요소에 대해 테스트하는 척해놓고 엘리먼트 1번만 테스트 하기
  • 테스트를 앞서가는 프로덕션 코드

    • 프로덕션 코드에서 테스트에서 테스트하는 대상보다 이상의 행위를 할 때
    • 프로덕션에 테스트되지 않은 코드가 추가되는 것이 허용되는 것이다
    • 첫번째 요소에 대해 테스트했다면, 프로덕션에서는 첫번째 요소만 렌더링 했어야 했다

고민

  • 픽스쳐(테스트를 위해 만들어진 데이터) 생성을 어떻게 해야할까?
  • 함수만 계속해서 만들어지게 된다
    • 무조건 함수들을 분리 하는게 맞는건가?
    • 이게 가독성을 더 해치는건 아닌가?
      • 추상화 수준이 낮아서 그렇다
      • 높은 응집, 낮은 결합 을 충족해야 한다
        • 함수로 분리해서 낮은 결합은 달성했지만, 높은 응집은 달성하지 못함
      • 그냥 니 리팩토링 수준이 낮아서다 라고 얘기하는 중