[Swift] TDD (Test Driven Development)의 개념

민경준·2022년 12월 14일
0

🌟 TDD 란?

TDD란 Test Driven Development의 약자로 테스트 주도 개발이라고 한다. 엔지니어 켄트 백 (Kent Beck)에 의해 고안되었다.

기본적인 TDD의 개념

테스트 케이스를 작성하고 이를 통과하는 코드를 추가하는 단계를 반복하여 구현한다.
짧은 개발 주기의 반복에 의존하는 개발 프로세스이며 애자일 방법론 중 하나인 eXtream Programming(XP)Test-First 개념에 기반을 둔 단순한 설계를 중요시한다.

Unit Test 구조가 짜여져 있으면 코드를 수정할 때 확인이 쉽기 때문에 코드를 수정하는데 두려움이 없어진다. Unit Test 구조를 만들 수 있다는 것은 기획서의 요구사항을 제대로 이해하고 있다는 뜻이다.

eXtream Programming(XP)란?

미래에 대한 예측을 최대한 하지 않고,
지속적으로 프로토타입을 완성하는 애자일 방법론 중 하나이다.
이 방법으론은 추가 요구사항이 생기더라도, 실시간으로 반영할 수 있다.

추상적인 레벨에서의 TDD의 핵심 개념

켄트 백 (Kent Beck)은 TDD가 프로그래밍 기법이나 기술적인 느낌보다는 심리적인 것으로 볼 수 있다고 한다. TDD는 결정(Decision)피드백(Feedback)의 갭에 대한 인식을 하고 그러한 갭을 조절하기 위한 테크닉을 늘려가는 것이다. 갭이 커질 수록 문제가 발생하고 그 갭을 전혀 이해하지 못한다면 더 큰 문제가 발생하게 된다.

결정(Decision)?
- 프로그램을 하다보면 ‘이 방법으로 해야지’, ‘이 부분은 이걸 이용해서 짜야지’라는 것을 결정한다.

피드백(Feedback)?
- 프로그램을 하다보면 성공/실패(에러)라는 피드백을 받는다.

Example.
- 결정: 나이를 구하는 코드를 작성할 때, ‘나는 빼기로 나이를 구해야겠다.’라는 것을 결정한다.
- 피드백: 빼기로 계산했을 때의 코드를 테스트 프로그램을 실행한 결과로, 된다/안된다라는 프로그램 상의 피드백을 받는다.
- 이 둘 사이의 갭을 내가 인식한다면 TDD를 하고 있는 것이다.


🌟 TDD는 왜 해야 할까?

테스트의 장점은 너무나도 많다.

제품의 안정성을 높이고, 기능 추가 및 수정으로 인한 부작용(Side-effect)를 줄일 수 있으며, 불안감 없이 코드 작성을 할 수 있도록 도와주고, 결과적으로 생산성을 매우 높여 준다. 디버깅을 쉽게 해주고, 개발 과정에서 반복적인 작업들을 하지 않도록 도와주며, 더 깔끔하고 재사용성이 좋은 코드 작성을 가능하게 해준다.

MVP, MVVM 과 같은 클라이언트 쪽에서 많이 회자되는 아키텍쳐들이 중요하게 생각하는 것은 바로 View와 로직의 분리이다. 이를 통해 얻고자 하는것 중 절대 빠질 수 없는 하나가 바로 테스트 가능성(Testability)이다.

UI Test는 어려워 빼더라도 Unit Test는 반드시 해야하는 이유다.
UI 없이 Unit Test가 불가능한 상태의 코드라면 다시한번 고민해봐야 한다.

TDD는 피드백과 협력을 증진시킨다. 테스트 코드(feedback)를 공유하여 개발자의 고민/의사결정(decision)을 확인 할 수 있기 때문에 개발자가 왜 그렇게 코드를 작성했는지 의도를 빠르고 쉽게 이해할 수 있다.

그리고 다른 개발자의 코드를 수정하더라도 자동화 된 테스트 코드가 문제를 알려주기 때문에 내가 코드를 망치면 어떡하지... 와 같은 걱정을 할 필요가 없어진다.



🌟 테스트 기본 원칙

테스트 구성에는 단위 테스트(Unit test), 통합 테스트(Integration test), 승인 테스트(Acceptance test) 등 다양한 테스트가 존재한다. 각 테스트의 목적과 상황에 맞게 테스트를 구성하는 것도 중요하지만, 테스트의 원칙을 지키는 것이 우선되어야 한다.

일곱 테스트 원칙 (Seven Testing Principles)

소프트웨어 테스팅 분야에서 40여년 간 제안되고 발전해 온 일곱 개의 기본 원칙이다.
이 글에서는 항목과 간단한 설명만 첨부하고 각 항목에 대한 자세한 내용은 Sevent Testing Principles   문서에서 확인할 수 있다.

  • 테스팅은 결함의 존재를 보여주는 것이다.
  • 완벽한 테스트는 불가능하다.
  • 테스트 구성은 가능한 빠른 시기에 시작한다.
  • 결함은 군집되어 있다.
  • 살충제 역설(Pesticide Paradox) - 비슷한 테스트가 반복되면 새로운 결함을 발견할 수 없다.
  • 테스팅은 정황에 의존적이다.
  • 오류 부재의 오해 - 사용되지 않는 시스템이나 사용자의 기대에 부응하지 않는 기능의 결함을 찾고 수정하는 것은 의미가 없다.

F.I.R.S.T 단위 테스트 원칙

단위 테스트는 가장 작은 단위의 테스트이며, 모든 테스트의 시작점이다. 단위 테스트만 구성되어도 굉장히 많은 문제를 해결할 수 있으며, 코드 품질이 훨씬 좋아질 수 있다. F.I.R.S.T 원칙은 다음 각 항목의 앞 글자를 딴 원칙이다.

  • Fast: 유닛 테스트는 빨라야 한다.
  • Isolated: 다른 테스트에 종속적인 테스트는 절대로 작성하지 않는다.
  • Repeatable: 테스트는 실행할 때마다 같은 결과를 만들어야 한다.
  • Self-validating: 테스트는 스스로 결과물이 옳은지 그른지 판단할 수 있어야 한다. 특정 상태를 수동으로 미리 만들어야 동작하는 테스트 등은 작성하지 않는다.
  • Timely: 유닛 테스트는 프로덕션 코드가 테스트를 성공하기 직전에 구성되어야 한다. 테스트 주도 개발(TDD) 방법론에 적합한 원칙이지만 실제로 적용되지 않는 경우도 있다.


Refrence

profile
iOS Developer 💻

0개의 댓글