Test Driven Development

Dev·2023년 4월 29일
0

5. TDD

Test Driven Development는 매우 짧은 개발 사이클을 반복하는 소프트웨어 개발 프로세스 중 하나이다. 개발자는 먼저 요구사항을 검증하는 자동화된 테스트 케이스를 작성한다. 그런 후에, 그 테스트 케이스를 통과하기 위한 최소한의 코드를 생성한다. 마지막으로 작성한 코드를 표준에 맞도록 리팩토링한다.

[1] TDD Cycle

  1. 작은 테스트를 추가한다.
  2. 모든 테스트를 실행하고, 실패하는 것을 확인한다. 컴파일 되지 않을 수도 있다. 프로덕트 코드를 건드리지 않았으니 당연하다.
  3. 빨리 테스트가 성공하도록 코드를 개발한다. 어떤 죄악(함수가 무조건 특정 상수를 반환)을 저질러도 괜찮다. 빨리 테스트가 성공하도록 만들자.
  4. 모든 테스트를 실행하고, 성공하는 것을 확인한다.
  5. 리팩토링한다.
    • 3번단계에서 죄악을 저질렀다면 이제 모든 케이스에서 성공하도록 여러 테스트 코드를 추가해보자.
    • 테스트는 당연히 실패했고, 이를 성공시키도록 죄악을 치워보자.
    • 기능이 완성되면서 테스트가 성공이된다. 하지만, 코드의 중복이 있다. 코드가 안 이쁠 수 있다. 괜찮다. 테스트코드가 성공하는 내에서 이쁜 코드를 만들어보자. 맘대로 바꿔도된다. 테스트만 성공하면 되니 리팩토링의 두려움도 사라진다.
  6. 개발 중 문뜩 "아 이거해야되는데?" 라는 생각이 든다. 이 때 바로 그 작업을 하지말고 메모장에 To-Do List를 추가하자. 이후에 하나하나 To-Do List를 제거하자. 이렇게 하는 이유는 현재 작업하는 부분에 집중하기 위해서다.

[2] TDD는 두려움을 관리한다.

  • 여기서 말하는 두려움이란 지금 작성중인 로직이 정상적으로 동작하나?에 대한 의구심이다.
  • 복잡한 구현 알고리즘 문제를 풀 때 생각해보자. 처음부터 끝까지 한번에 프로덕트 코드를 만들고, 한번에 테스트를 하는 경우는 드물다. 물론 똑똑한 개발자라면 가능하지만 적어도 본인은 아니다. 큰 기능을 작은 기능으로 쪼개고, 다양한 데이터를 넣어보면서 테스트를 수행한다. 버그가 나와도 기능을 쪼갰기 때문에 버그 포인트를 쉽게 찾을 수 있다. 즉, 단계를 나누고 디버깅을 통해 검증하면서 나아간다.
  • TDD도 유사하다. TDD는 매 순간을 자동화된 테스트를 통해 확인받고 나아가는 개발 방법이다. 테스트는 테스트 코드가 될 수 있고, curl로 api를 호출할 수도 있고 자동화된 방법이라면 모든 괜찮다고 생각한다. 이전 단계의 기능을 마음 한켠에 신경쓰지 않고 '현재 단계' 로직만 집중하면된다. 개발 중 문뜩 이전 로직을 신경쓰거나 로직 오류가 발생할 때 이전 로직을 신경쓰지 않고 현재 로직에만 집중하면된다. 심리적으로 '이전 로직이 틀렸을까?' 요런 불편한 감정을 최소화한다.
  • 만약 복잡한 프로덕트 코드를 한번에 짜고 테스트를 수행하는데 잘못된 점을 발견하면 어떨까? 아마 지금까지 힘들게 짠 프로덕트 코드를 다 수정해야한다. (수정하지 않더라도 정상적으로 동작하는지 머릿속으로 일일이 확인해야한다.) 아깝다. 하지만 TDD를 통해 이전에 점진적으로 검증받았다면, 이전에 개발한 로직은 신경쓰지 않아도된다.
  • 마지막으로 리팩토링할 때 수월하다. 모든 케이스를 검증할 수 없겠지만 기존 테스트 코드가 있으니, 테스트를 만족하기만 한다면 마음 편히 리팩토링할 수 있다. 이건 테스트 코드의 장점이기도 하다.

[3] 현재 하는 일에 집중한다.

  • 복잡한 기능을 한번에 짜기 힘들다. 따라서 작업을 분할하고 이를 합치는 방향으로 개발한다. 앞서 TDD는 각 단계마다 검증하면서 나아간다고 했다. 따라서 분할한 작업에서 오류가 나온다면 이전 단계의 오류는 신경쓰지 않고 현 단게만 생각하면된다.
  • 앞서 To-Do List를 말했다. 작업 중 문뜬 여러 생각이 난다. 이거 고쳐야하고, 이거 추가해야하고 등등 여러가지다. 그런 것들은 필요한데에 메모하고, 원래 하던 작업에 집중한다. 본인은 막 컴퓨터처럼 스위칭이 자유롭지 않다. 원래 하던일만 잘하고 싶다.

[4] TDD에 대한 개인적인 생각

테스트 코드를 먼저짜나, 프로덕트 코드를 먼저짜나 그게 무슨 차이가 있지?

  • 테스트 코드를 먼저 만들고, 프로덕트 코드를 만드나 순서를 바꾸는 거나 큰 차이는 없다고 생각한다. 다만, 테스트 코드를 먼저 생성한다면 자연스럽게 단계를 쪼갤 수 있고, 기능을 사용하는 관점에서 먼저 생각할 수 있다. 물론 객체지향 설계를 잘해서 적절히 코드의 책임을 분배하면 되겠지만, TDD를 통해 자연스럽게 기능을 쪼개기부터 시작할 수 있다.

TestCode가 많다면 무조건 좋을까?

  • 테스트 코드가 많은건 edge case를 많이 잡아줄 수 있다는 측면에서 좋다. 하지만 프로덕트 코드보다 테스트 코드를 수정하는데 시간이 많이 걸릴 수도 있다.
  • 결국 우리가 만든 로직의 결함을 잡아주기 위해 테스트 코드가 많으면 좋고, 그렇다고 유지보수할 때 테스트 코드에 너무 시간을 쓰기도 아깝다. 코드 한줄 바꿨는데 수 많은 테스트 코드를 고칠 수도 있다. 본인은 상황에 따라 테스트 코드를 추가하면된다고 생각한다. 즉, 테스트 커버리지를 높이기 위한 테스트는 굳이 필요 없다고 생각한다.
  • 금융, 방산, 보안과 같이 절대 edge case가 나오면 안되는 도메인에서는 시간이 걸리더라도 엄격히 테스트 코드를 추가하는게 맞다고 생각한다.
  • 핵심 로직이 담긴 부분은 나중에 유지보수시 실수로 로직이 깨지는걸 방지하고자 필수 로직에 대한 테스트 코드는 반드시 추가해야한다.
  • 실제 서비스 중 예상치 못한 데이터 인입, 시나리오, 잘못된 함수 사용 등에 대한 테스트 코드는 추가하자.
  • 관성적으로 테스트를 추가하는건 지양하고싶다. 유지보수가 너무 힘들다.

[5] 총평

TDD는 작은 과정을 조금씩 쌓아올려나가는 개발 방법론이다. 각 과정마다 테스트를 통해 확신을 얻고, 현재 작업하는 부분에만 신경쓴다. 이를 위해 적절한 분량의 단계를 나누고, TO-DO List를 활용한다.

profile
성장하는 개발자가 되고싶어요

0개의 댓글