본문 바로가기
프로그래밍

[프로그래밍] TDD와 테스트 코드

by 개발 까마귀 2023. 9. 2.
반응형

TDD 와 테스트 코드

안녕하세요. 개발 까마귀입니다 이번에는 TDD 와 테스트 코드에서 대해서 알려드리려고합니다.
우선 TDD 와 테스트 코드는 다른것입니다. TDD는 개발 방법론이고 테스트 코드는 말 그대로 테스트 코드입니다.
그래서 회사나 다른 곳에서 "나는 TDD 하고있어 또는 할거야" 하고 나중에 보면 그냥 기능 구현 다 하고 테스트 코드를 짜거나 테스트 코드를 다 작성하고 기능 구현을 하는 사람이 많습니다. 이는 TDD를 정확히 모르는거죠

테스트 코드 적용 이전의 개발

우선 TDD와 테스트 코드에 대해서 설명하기전에 그저 기능 구현만 했을 때의 개발 플로우 와 문제점들을 얘기하겠습니다.

테스트 코드 적용 이전의 개발 플로우

1. 기획서 작성
2. 기능 구현
3. QA(기능 테스트)
4. 배포
 
간소화 하자면 위 과정입니다. 플로우만 본다면 별 문제 없어보입니다.
QA에서 내가 개발한 부분을 잡을 테고 오류를 잡으면 다시 개발 진행하면되니깐 뭐가 문제야? 라고 생각 할수있습니다.
하지만 서비스의 규모가 커진다 즉 코드의 양이 커진다면 이에 들어가는 인력비용 또한 커지게됩니다.

테스트 비용

REST API를 이용해서 개발을 했다고 하면 해당 기능을 테스트 하기 위해서 Postman 또는 Swagger를 이용해서 테스트를 할겁니다.
하지만 여러 군데를 리팩토링 했다거나 테스트 자체가 어려운 API 등 시스템이 커져갈수록 수동적으로 하는 회귀 테스트(기존 코드가 올바르게 동작하는지에 대한 테스트)는 힘듭니다. 그래서 종종 개발자들은 QA 분들이 잡아주겠지하고 개발만하고 배포하는데 이러면 QA 분들이 에러를 찾고 개발자한테 전달하고 개발자는 또 테스트 안하고 배포하고 QA 분들이 에러 찾고 전달하고... 이 과정이 계속 반복되는데
이거는 회사 자원으로 돈 낭비 시간 낭비를 한다고 볼수있습니다. QA를 하는 사람들 또한 짜증나고 배포하는 속도 또한 많이 느립니다.

QA는 에러를 찾으면 안된다.

QA를 하는 사람들은 개발에 대한 에러를 찾으면 안됩니다.
에러를 찾을 때 마다 그에 들어가는 비용과 시간이 들어가기 때문입니다.
100% 완벽하게 에러를 없앨수는 없지만 그에 근접하게 하는 것이 우리 개발자들이 해야 할 일입니다.

불안감

서비스가 커지다 보면 오류 픽스, 리팩토링, 기능 개발, 기능 수정 등 많은 일을 하게 됩니다.
하지만 장담할수있나요? 내가 개발한거가 정말 정상적으로 작동하고있다고 장담할수있나요?
사람은 실수의 동물입니다. 실수를 한다것은 실수를 할수있는 환경이고 그 실수를 줄이기 위해서 많은 Tool 과 방법론이 나오는것이니깐요. QA가 정상적으로 통과가 되었다 하지만 QA 또한 사람이므로 완벽하게 못찾습니다.
QA를 통과했다고 해도 오류가 납니다. 서비스가 커질수록 오류는 자주 일어나겠죠
이러다 보면 코드에 손대는게 공포처럼 다가 올 뿐더러 이는 곧 개발자에게 스트레스로 다가옵니다.
스트레스는 판단력 저하를 일으키고 계속 악순환의 반복이 되는겁니다.
위 문제점들로 인해 테스트 코드 또는 TDD를 적용해야한다고 적극 권장합니다.
Github PR을 보내기전 PR을 보낼 때 마다 그냥 심심할 때 마다 테스트를 계속 돌려서 마음의 안정감과 서비스의 안정감을 얻을수있습니다. 

테스트 코드 적용시 개발 속도

"기능 개발만 하기에도 바빠요"
테스트 코드를 안짜고 기능 개발만 하신 분들이 테스트 코드를 적용하기 전에 제일 많이 하시는 말 이죠
개발을 할 때 소요되는 시간은 기능 개발 뿐만이 아니죠, 기능 개발을 할 때 들어가는 버그 수정, 기능 테스트 등 모든게 개발 소요시간 입니다. 버그를 찾기 위해서 수동으로 API를 호출하고 버그 찾고 고치고 또 API 호출하고 이러한 프로세스가 오히려 더 많은 소요시간을 잡아먹게됩니다. 테스트 코드를 적용하면 자동으로 테스트 코드를 돌리고 오류 발견해서 고치므로 소요시간이 더 짧아집니다. 테스트 코드는 필수적으로 적용해야합니다.

TDD란?

TDD(Test Driven Development) 번역하자면 테스트 주도 개발 입니다.
말 그대로 테스트부터 시작한다 입니다. 즉 구현을 먼저하는게 아닌 테스트 코드를 먼적 작성하고 그 다음에 구현을 하는것입니다.
보통 개발을 하면 기능을 먼저 구현하고 테스트 코드를 작성하거나 테스트 코드를 작성 안하고 배포를하는데 말이죠 그렇다면 테스트 코드를 먼저 작성해서 얻는 장점은 뭐가 있을까요?

TDD의 흐름

위 사진처럼 [Red - Green - Refactor]가 있습니다.
 
Red

  • 실패하는 테스트를 의미

Green

  • 성공한 테스트를 의미
  • 코드를 구현해서 테스트를 통과시키는 것을 뜻함

Refactor

  • 리랙토링 과정을 의미

위 순서를 아래 사진처럼 쉽게 정리해봤습니다.

테스트 코드를 먼저 작성 후 테스트를 통과시킬 만큼 코드를 작성하고 리팩토링으로 마무리하는 과정을 반복

 

이러한 플로우로 얻을수있는 장점은 아래와 같습니다.

  • 단기적인 목표와 장기적인 목표를 뚜렷하게 제시해주고 올바르게 잡아준다.
  • 반복되는 짧은 개발 패턴을 통해 개발 리듬을 만듦으로써 개발 집중력을 높여준다.
  • TDD 를 행함으로써 개발하고 있는 코드의 문제점을 빠르게 잡아낼 수 있다.

TDD를 꼭 적용해야하나?

TDD를 반대하는 입장도 많습니다. 이에 TDD 관련해서 문제점등을 유명한 글이 바로 "TDD는 죽었다" 라는 글이죠 해당 글을 쓴 사람은 Ruby를 만든 분으로서 개발 업계에서는 무시할수없는 분이고 글을 쓴 내용들 또한 논리적입니다.

TDD는 죽었다

1. 아키텍처의 복잡화
TDD가 유닛테스트의 초점이 맞춰져 있으므로 복잡한 구조를 만들기 쉽다고합니다.

2. 시스템 전체의 테스트를 지양
속도가 느려지는것을 기피하다보니 인프라 관련된 부분(데이터베이스, API 호출 등)을 Mock를 함으로써 테스트 전체의 테스트를 지양하게된다.

우선 제가 이해한 1번은 TDD의 플로우인 Refactor 과정에서 발생하는 부분 같습니다. 유닛 테스트의 관점으로 계속 class나 함수가 추가 되면서 복잡한 구조가된다고 하는거 같습니다.
2번은 TDD 책에서 많이 언급됩니다. 인프라 쪽 부분은 매우 변동적이기 때문에 Mock를 하게됩니다. 예를들어 DB가 mysql 일시에 테스트 코드에서는 mysql을 연결을 안하고 메모리 DB를 사용한다거나 Dirty DB를 사용한다는거죠 이런거를 인프라 모킹이라고합니다. 하지만 해당 테스트는 E2E 테스트로 하면되서 상관은 없어보입니다.

포프TV 효율적인 테스트 코드 작성 방법

또한 "TDD는 죽었다" 글 말고 제가 재미있게봤던 영상 중 하나가 포프님이 운영하는 포프TV에 "효율적인 테스트 코드 작성 방법" 이라는 영상이 있는데 보시면 좋을거같습니다. 해당 영상에는 아래와 같이 말씀을 하십니다.
 
1. TDD를 통해서 설계적인 부분이 나아지지 않는다. 
TDD에서 Refactor 단계에 들어가면 설계적인 부분 또한 손을 되게 됩니다.
이를 TDD 진영에서는 자연스럽게 설계 부분이 나아지게된다고 합니다.
하지만 해당 부분은 객체지향 및 함수의 선조건 후조건을 이해를 했다면 Refactor 부분이 없더라도 좋은 설계를 만들수있다는거죠, 객체지향의 SOLID 원칙 및 매커니즘을 이해 했다면 좋은 설계는 당연히 나올수밖에 없다고 생각됩니다.
 
2. 사람은 실수가 이미 Default 이기에 테스트 코드를 작성한다는 것은 이미 실수가 내장이 되어있다.
사람이 실수가없다고하면 테스트 코드를 작성할 필요가 없죠, 하지만 사람은 실수가 default 이기 때문에 테스트 코드 작성 조차도 실수가 내장되어있으므로 큰 효과를 보지 못합니다.

3. 바뀌는 부분 안 바뀌는 부분 모두 처음부터 테스트 코드를 짜는거는 비효율적이다.
코드에서는 바뀌는 부분과 안 바뀌는 부분이 있습니다. 이거에 대해서 처음부터 테스트 코드를 짤 필요가 없다는 거죠 어차피 비즈니스 로직은 바뀌고 오류가 생기기 마련이므로 그 때 마다 미리 짜놓은 테스트 코드들이 실패가되면서 해당 테스트 코드들을 성공 시키기 위해 돈 낭비 시간 낭비가 됩니다. 오류가 발생되면 해당 오류 관련된 테스트 코드를 그 때 만들고 문제를 고치므로서 커버지리지 자연스럽게 상승 및 코드의 안정성도 올라게되고 시간 및 돈 또한 절약이 됩니다.
 
하지만 위 프로세스라면 테스트 코드를 처음에 작성을 안하고 기능 추가 및 리팩토링을 할 때 회귀 테스트 관련해서의 답은 인수 테스트(사용자 관점의 테스트)로 하는 것인가? 라는 궁금증이 생기더군요.

정리

TDD를 모든 프로젝트에 적용하는거는 불가능 하다고 생각됩니다. 하지만 Refactor 단계에서는 어느정도 설계 관련해서 개선되는 부분이 있다고 생각하기 때문에 객체지향 및 설계 관련해서 이해도가 부족하고 숙련도가 낮다면 TDD를 완전히 버리라기보다는 적용할수있는 코드에는 적용하는게 맞다고 생각합니다. 아직도 여러 커뮤니티에서 찬/반 입장이 있기 때문에 결국에는 여러분들이 TDD 관련 책, 영상, 글, 커뮤니티 등을 직접 찾아보면서 결정을 내리는게 중요한거같습니다.
마지막으로 제가 TDD를 이해하기 위해서 읽었던 책 추천 및 참조한 글들을 소개로 마무리하도록 하겠습니다.
 
감사합니다.
 
TDD: Dead or Alive 2023?

 

TDD: Dead or Alive in 2023? - MethodPoet

Is TDD dead in 2021? No. It is alive and well. Learn why it's not just a methodology to follow, but an approach that helps you write better code today.

methodpoet.com

TDD 이야기(TDD에 대한 오해와 진실)

 

TDD 이야기(TDD에 대한 오해와 진실) - Rain.i

All about IT tech, especially database, cloud, linux, clustering.

cloudrain21.com

테스트 주도 개발 시작하기

 

테스트 주도 개발 시작하기 - 예스24

TDD(Test-Driven Development)는 테스트부터 시작한다. 구현을 먼저 하고 나중에 테스트하는 것이 아니라 먼저 테스트를 하고 그다음에 구현한다. 구현 코드가 없는데 어떻게 테스트할 수 있을까? 여기

www.yes24.com

테스트 주도 개발

 

테스트 주도 개발 - 예스24

Test-Driven Development: By Example아름다운 코드와 즐거운 개발을 위한 테스트 주도 개발테스트 주도 개발은 학계와 업계에서 많은 주목을 받아온 프로그래밍 방법으로, 여러 연구 논문과 실례를 통해

www.yes24.com

 

반응형

댓글