recoen.

TDD란 무엇일까? (큰 그림에서 바라보기)

오늘은 TDD에 대해서 알아보려고 합니다. 본 글은 제가 TDD를 입문하기 전에 다양한 자료들을 찾아보며 이것이 무엇이며, 어떤 유익이 있는지에 대해서 정리한 글입니다. TDD를 입문하시려는 분들에게 도움이 되는 글이 되었으면 좋겠습니다.


TDD란 실제 코드를 작성하기 전에 테스트를 먼저 작성하는 방식으로 이루어지는 소프트웨어 개발의 프로세스입니다. 이것은 개발과 유닛 테스트 작성 그리고 리팩토링의 결합의 반복이라고 이해하면 좋습니다. 그렇다면 TDD의 목적은 무엇일까요? TDD의 목적은 테스트성, 모듈성, 유연성, 확장성을 보장하기 위한 것입니다. TDD는 테스트를 먼저 작성함으로써 2가지 도움을 줍니다. 첫번째는, 개발자가 코드로부터 기대하는 행동을 명확하게 정의내릴 수 있도록하고, 두번째는 그런 요구사항들을 충족시키도록 코드를 작성할 수 있게 가이드하는 역할을 합니다.

지금부터 TDD에서 중요한 포인트를 몇 가지 소개해드리도록 하겠습니다.

1. TDD의 프로세스

TDD에서는 개발자는 어플리케이션의 작은 단위의 기능에 대한 테스트를 설계하고 개발하는 것으로부터 시작합니다. 이런 테스트들은 다양한 도구들에 의해서 작성될 수 있습니다.(js에서는 대표적으로 jest가 존재합니다.) 이 테스트들은 초반에는 실패할 수 밖에 없습니다. 왜냐하면 테스트에 대응하는 기능들이 아직 구현되지 않았기 때문입니다. 이후에 개발자들은 실패한 테스트를 통과할 수 있는 수준만큼. 최소한의 코드만 작성합니다. 그리고 테스트가 통과하고 나면, 그 코드들을 더 유지보수 가능한 방향으로 리팩토링합니다. 이렇게 테스트, 코딩, 리팩토링의 사이클이 각각의 기능에 대해서 반복됩니다. ( TDD의 사이클 : 테스트 -> 코딩 -> 리팩토링 )

2. TDD로부터 얻을 수 있는 유익

TDD는 소프트웨어 개발에 있어서 여러가지 유익을 제공해줍니다. 각각의 유익들에 대해서 소개해보도록 하겠습니다.

코드의 퀄리티를 높여줍니다.

TDD의 방식으로 개발을 하게 되면 코드의 퀄리티가 높아지게 됩니다. TDD가 코드의 퀄리티를 높여준다는 것에 대해서는 여러 방면으로 생각해볼 수 있습니다. 그 전에 먼저 "코드의 퀄리티가 높다" 라는 말의 정의가 무엇인지에 대해서 살펴봐야할 것 같습니다.

제가 읽었던 책 "리액트 스타일 가이드"라는 책에서는 소스 코드의 품질을 평가하기 위한 척도로 3가지를 소개하고 있습니다. 가독성, 유지보수성, 테스트가능성. 사실 이외에도 다른 요인들이 존재할 수 있습니다. 하지만 제가 조금 더 검색을 하고 찾아본 결과 위 3가지로 범위를 좁힐 수 있겠다는 생각이 들었습니다. 그렇다면 TDD는 위 3가지 조건을 달성가능하게 만들어준다는 것이 보장되어야 합니다. 그 말이 보장된다면, "TDD가 코드의 퀄리티를 높여준다"는 말을 이해할 수 있게 될 것이라고 생각합니다.

먼저 가독성 입니다. 코드의 가독성이 높다는 말은 이 코드의 의도하는 바가 무엇인지 명확하게 이해된다는 것을 의미할 수 있습니다. 그런 점에서 TDD는 항상 코드를 작성하기 전에 테스트 코드를 먼저 작성함으로써, 내가 작성하려는 코드가 어떤 의도를 가지고 있는지 명확하게 만들어줍니다. 이는 자연스럽게 TDD가 소스코드의 가독성을 높여준다고 말할 수 있습니다.

다음으론 유지보수성 입니다. 유지보수성은 코드가 시간이 지나도 쉽게 변경하고, 확장할 수 있는지를 나타내는 중요한 척도입니다. 만약 코드가 복잡하거나, 각 부분이 서로에게 너무 의존적으로 작성되어 있다면, 그 코드를 수정하거나 확장하는 것은 매우 어렵게 될 것입니다. 이러한 문제를 방지하기 위해, 코드는 가능한 한 모듈화되어야 하며, 각 부분은 최대한 독립적으로 작성되어야 합니다.

이런 점에서 TDD는 유지보수성을 향상시키는데 크게 기여합니다. 테스트를 먼저 작성함으로써, 개발자는 코드의 각 부분을 분명하게 정의하고, 각각의 코드에 대해서 독립적으로 테스트할 수 있게 만들어야 합니다. 이는 코드가 모듈화가 되도록 만들어주며, 코드의 결합도를 낮추고 응집력을 높이는데 도움이 됩니다.

또한, TDD는 리팩토링을 안전하게 수행할 수 있게 합니다. 테스트 케이스가 있으면, 코드를 변경하거나 개선하더라도 그 기능이 여전히 잘 동작하는지 확인할 수 있습니다. 이는 유지보수를 쉽게 하며, 코드의 유지보수성을 향상시키는 데 중요한 역할을 합니다.

마지막으로 테스트 가능성 입니다. 코드의 테스트 가능성은 그 코드가 얼마나 쉽게 테스트할 수 있는지를 나타내는 척도입니다. 코드가 테스트하기 어렵다면, 버그를 찾아내거나, 새로운 기능을 안전하게 추가하는 것이 어려울 것입니다. TDD는 코드의 테스트 가능성을 향상시키는데 핵심적인 방법입니다. TDD는 애초에 테스트를 먼저 작성하기 때문에, 코드는 처음부터 테스트하기 쉬운 방향으로 설계됩니다. 이로 인해 코드의 테스트 가능성이 높아지며, 이는 코드의 품질을 높이는 데 중요한 요소가 됩니다.

결국, TDD는 코드의 가독성, 유지보수성, 그리고 테스트 가능성을 모두 높이는 방법이므로, "TDD는 코드의 퀄리티를 높여준다" 고 말할 수 있을 것 같습니다.

빠른 개발 생산성을 가지게 해줍니다.

TDD는 개발 프로세스의 초반부터 문제점을 잡아낼 수 있도록 도와줍니다. 때문에 추후에 발생할 수 있는 에러나 디버깅에 드는 비용을 줄여줄 수 있습니다.

더 나은 유지보수성을 가지게 해줍니다.

코드 퀄리티를 높인다는 측면에서도 살펴본 내용입니다. 앞서 설명했듯이 TDD는 자연스럽게 각각의 코드들이 모듈화 될 수 있도록 만들어주며, 각각의 모듈들에 대해서 독립성을 가지도록 만들기 때문에 잘 설계된 구조를 가지게 만들고, 결론적으로 유지보수하기에 쉬운 코드를 작성하도록 만들어줍니다.

요구사항을 더욱 명확하게 만들어줍니다.

TDD는 무작정 개발에 착수할 수 없게 만듭니다. 먼저 내가 작성할 요구로부터 기대되는 행동이 무엇인지 생각해야하고, 해당 내용에 대해서 테스트를 작성해야합니다. 이런 과정을 거치게 되면 요구사항을 더욱 분명하게 만들 수 있게 됩니다. 또한 이렇게 사전에 요구사항을 명확하게 함으로써, 요구사항이 불분명한 경우를 빠르게 캐치하여 명확성을 요청할 때에도 도움이 될 수 있습니다.

3. 3가지 단계로 나뉘어지는 TDD :

TDD는 다음의 세 단계로 나뉩니다:

  • 빨강: 이 단계에서 개발자들은 코드의 예상되는 행동을 설명하는 실패하는 테스트를 작성합니다. 이 테스트는 아직 구현되지 않은 기능에 대한 사양을 제공합니다.
  • 초록: 이 단계에서 개발자들은 실패한 테스트를 통과시키기 위해 필요한 최소한의 코드를 작성합니다. 이때의 초점은 코드를 최적화하거나 견고하게 만드는 것이 아니라 기능적으로 동작하게 만드는 것입니다.
  • 리팩토링: 이 단계에서 개발자들은 코드의 기능을 변경하지 않으면서 코드의 설계와 유지보수성을 향상시킵니다. 중복을 제거하고, 명명을 개선하며, 코드를 더 읽기 쉽고 유지보수하기 쉽게 만듭니다.

4. TDD와 테스트 커버리지 :

TDD는 개발의 초기 단계에서부터 각각의 기능에 대해서 테스트를 작성하는 것을 강조합니다. 이것은 개발 이후에 테스트를 작성하는 전통적인 개발 모델에 비해서 훨씬 더 높은 테스트 커버리지를 달성할 수 있게 만들어줍니다. 높은 테스트 커버리지를 달성하는 것이 의미가 있느냐고 반문할 수도 있습니다. 이에 대해서는 의견이 분분할 수 있지만, 높은 테스트 커버리지가 가져다주는 이점은 명확하다고 생각합니다. 제가 참고했던 자료는 토스 | SLASH21 - 테스트 커버리지 100% 입니다. 이 자료는 단순히 높은 커버리지를 달성할 것이 아니라, 커버리지 100% 달성을 목표로 한다고 이야기하고 있지만 커버리지가 높아질 수록 얻을 수 있는 이점에 대해서는 다음과 같이 생각해볼 수 있습니다. 대부분의 기능에 대해서 테스트가 작성되어 있을수록 기능이 정상적으로 작동할 것에 대한 자신감을 얻을 수 있으며, 자연스럽게 프로덕트에 대한 높은 이해도를 가질 수 있게 된다는 점입니다.

결론

TDD는 기존의 방식과는 다른 방식으로 개발을 하도록 만들기 때문에 입문자에게는 높을 피로도를 불러일으킬 수 있습니다. 하지만 익숙해지기만 한다면 굉장한 유익을 얻을 수 있는 개발 방법론으로 이해할 수 있습니다. 부디 이 글이 TDD를 입문하시려는 분들에게 TDD의 전체적인 그림을 이해하는데에 도움이 되는 글이 되었기를 바랍니다.

참고 : https://www.guru99.com/test-driven-development.html https://www.techtarget.com/searchsoftwarequality/definition/test-driven-development https://www.spiceworks.com/tech/devops/articles/what-is-tdd/