테스트 주도 개발(TDD)

taeheeyoon·2022년 2월 22일
6

CS

목록 보기
3/3
post-thumbnail

지난 2월 17일 Udemy에서 성장하는 개발자의 학습법이라는 웨비나를 진행했다.
현재 우아한테크코스에서 코치로 계신 메이커준님과 포코님이 연사로 참여하셨다.
첫번째 세션을 진행하신 메이커준님이 테스트 주도 개발(TDD)에 대해 설명해주셔서 이번 기회에 관련 포스팅을 하기로 생각했다.

TDD!

테스트 주도 개발(TDD)를 아는가. 프로그래밍을 하다보면 한 번쯤은 들어본 적이 있을 것이다. 하지만 실천해본 사람을 적을 것이다.
메이커준님은 TDD의 중요성을 강조하시면서 꼭 개발에 적용해볼 것을 당부하셨다.
특히 테스트를 먼저 만들고, 실제 코드를 작성하고, 원하는대로 동작하는지 빠르게 피드백을 받는 것이 중요하다고 강조하셨다.

❗ 핵심은 더 자주, 더 빨리 피드백을 받는 것
내가 던진 농구공이 들어갔는지 1달 뒤에 알 수 있다면..?

테스트 주도 개발(Test-Driven Development, TDD)은 매우 짧은 개발 사이클을 반복하는 소프트웨어 개발 프로세스 중 하나이다. 개발자는 먼저 요구사항을 검증하는 자동화된 테스트 케이스를 작성한다. 그런 후에, 그 테스트 케이스를 통과하기 위한 최소한의 코드를 생성한다. 마지막으로 작성한 코드를 표준에 맞도록 리팩토링한다. 이 기법을 개발했거나 재발견 한 것으로 인정되는 Kent Beck은 2003년에 TDD가 단순한 설계를 장려하고 자신감을 불어넣어 준다고 말하였다. - 위키백과

왜 이런 방식을 권장하는 것일까? TDD의 장점을 알아보자.

TDD의 장점


이런 일을 미연에 방지해준다.

가장 큰 장점은 높은 퀄리티의 소프트웨어를 보장한다는 것이다. 그렇다면 높은 퀄리티의 소프트웨어는 어떻게 정의할 수 있을까? 참고한 포스트에서는 이를 아래와 같이 3가지로 정의했다.

  1. 절대 에러나 버그가 없을 것.
  2. 추가적인 요구사항이 있을 때 손쉽게 그 요구사항을 반영할 수 있을 것.
  3. 유지보수에 용이할 것.

TDD는 아래와 같은 특징 때문에 위 3가지 사항을 모두 만족시킨다.

보다 튼튼한 객체지향적인 코드생산

TDD는 코드의 재사용성을 보장할 것을 명시하므로 TDD를 통한 소프트웨어 개발 시 기능별 철저한 모듈화가 이뤄진다. 이는 종속성과 의존성이 낮은 모듈로 조합된 소프트웨어 개발을 가능하게 하며 필요에 따라 모듈을 추가하거나 제거해도 소프트웨어 전체 구조에 영향을 미치지 않게된다.

재설계 시간의 단축

TDD는 테스트 코드를 먼저 작성하기 때문에 내가 지금 무엇을 해야하는지 분명히 정의하고 개발을 시작하게 된다. 또한 테스트 시나리오를 작성하면서 다양한 예외상황에 대해 생각해 볼 수 있으며 이는 완성도 높은 설계로 이어진다. 따라서 매우 크리티컬한 예외상황이 생길 확률이 극히 낮으며, 개발진행 중 소프트웨어의 전반적인 설계가 변경되는 일을 방지할 수 있다.

디버깅 시간의 단축

이는 통합 테스팅이 아닌 유닛 테스팅을 하는 이점이기도 하다. 우리는 각각의 모듈 별로 테스트를 자동화 할 수 있는 코드가 없다면 특정 버그를 찾기 위해서 모든 레벨의 코드들을 살펴봐야 한다. 예를 들어 사용자의 데이터가 잘못 나온다면 DB의 문제인지, 비지니스 레이어의 문제인지 UI단의 문제인지 실제 모든 레이어들을 전부다 디버깅 해야하지만, TDD의 경우 자동화 된 유닛테스팅을 전재하므로 특정 버그를 손 쉽게 찾아낼 수 있다.

테스트 문서의 대체가능

주로 SI 프로젝트를 진행하다 보면 어떤 요소들이 테스트 되었는지 테스트 정의서를 만들곤 한다. 이것은 단순 통합테스트 문서에 지나지 않는다. 즉, 내부적인 하나하나의 로직들이 어떻게 테스트 되었는지 제공할 수 없다. 하지만 TDD를 하게 될 경우 테스팅을 자동화 시킴과 동시에 보다 정확한 테스트 근거를 산출할 수 있다.

추가 구현의 용이함

개발이 완료된 소프트웨어에 어떤 기능을 추가할 때 가장 우려되는 점은 해당 기능이 기존 코드들에 어떤 영향을 미칠지 모른다는 점이다. 따라서 단순한 기능이라도 추가 된 후에는 모든 기능들을 처음부터 테스트 해야한다. 하지만 TDD의 경우 자동화된 유닛 테스팅을 전재하므로 이러한 테스트 기간 역시 획기적으로 단축시킬 수 있다.

TDD는 위와같이 무수한 장점을 가지고 있지만 모두가 이 개발 프로세스를 따르지 않는다. 이유가 무엇일까?

TDD의 단점

가장 큰 단점은 바로 생산성의 저하다. 단순한 어플리케이션을 개발하는 경우 경험에 의해 어떤 예외상황이 발생할지 눈에 뻔히 보이는 경우가 많다. 특히 이러한 단발성 개발은 개발 기간이 타이트하게 잡히는 경우가 많은데, 이럴 때 TDD를 적용해 뻔한 테스트 코드를 작성하고 그에 통과하기 위한 코드를 작성한다면 마치 답을 알고 푸는 문제집처럼 따분하고 비효율 적일 것이다.

본 포스팅에 참고한 박경훈 님의 글에 의하면 아래와 같은 경우도 있다고 한다.

TDD로 프로젝트를 진행하면서 어려운 예외가 생길 수 있는데 그것 때문에 고민하는 순간이 찾아오게 된다. 원칙을 깰 수는 없고 꼼수가 있기는 한데 그 꼼수를 위해서 구조를 바꾸자니 이건 아무래도 아닌 것 같고, 테스트는 말 그대로 테스트일 뿐 실제 코드가 더 중요한 상황인데도 불구하고 테스트 원칙 때문에 쉽게 넘어가지 못하는 그런 경우다.

왜 다들 TDD를 활용하지 못할까? TDD를 하기 여려운 이유는 무엇일까?

개발 시간이 증가한다.

  • 많은 기업들이 단기적인 성과에 집중해 있다. 전체 개발 시간을 줄이는 것보다 오늘 일을 끝내는 것을 강조하기 때문에 TDD 도입이 어렵다.
  • 단기적인 것에 집중되어 있으니.. 그때까서 또 고치면 되니까.. 급한 불을 끄면서 허덕이면서 살기 때문에..

TDD가 어렵다.

  • 왜?
  • 이제까지 자신이 개발하던 방식을 많이 바꿔야 하기 때문에
  • 몸에 체득한 것이 많을수록 바꾸기가 어렵다.
  • 언러닝(Unlearning): 이미 배운것을 까먹는 과정
  • TDD는 오히려 개발을 별로 안해본 사람에겐 적용하기가 쉽다.

TDD는 이렇게 해야된다는 이미지/틀이 있다.(핵심)

  • ‘반드시 툴(단위 테스트 프레임워크)을 써서 이렇게 해야된다.’라고 생각한다.
  • 하지만 이런 규칙에 얽매이는 것은 애자일이 아니다.
  • 결국엔 규칙에 얽매여 똑같은 테스트를 copy&paste 한다.
  • 너무 도구/규칙에 집착하니까 TDD가 어려워지는 것이다.

TDD를 잘하는 방법?

적응적, 진화적으로 접근해야 한다.

  • 나 스스로 ‘어떻게 해야 피드백을 더 자주 받을까’, ‘어떻게 해야 내가 하는 작업에 대해 협력이 잘 일어나게 할까’를 고민하면서 계속해서 내가 일하는 방식을 업그레이드 해야한다.
  • 중복적으로 하는 노력들을 조금 더 자동화하도록 업그레이드하면 발전할 수 있다.

Just Do It🚀

그럼 메이커준님이 소개한 간단한 프로그램으로 TDD를 적용하여 개발해보자

계산기

1. ui없이 사칙연산이 되는 것만 빠르게 만들기

class Calculator() {
  add(num1, num2) {
	return num1 + num2;
  }
  
  minus(num1, num2) {
	return num1 - num2;
  }
  
  multiply(num1, num2) {
	return num1 * num2;
  }
  
  divide(num1, num2) {
	return num1 / num2;
  }
}
const calculator = new Calculator();
console.log(calculator.add(1,2);
console.log(calculator.minus(1,2);
console.log(calculator.multiply(1,2);
console.log(calculator.divide(1,2);            

2. input으로 사용자 입력 받고 이벤트 처리하기

3. 숫자 UI 추가하고 이벤트 처리하기

4. 실제 계산기 처럼 구조잡기

5. 스타일 입히기

TDD는 이런식으로 진행된다고 설명해주셨다. 나는 개인적으로 애자일 방법론에서 설명하는 것과 비슷하다고 느꼈다.

핵심은 큰프로그램을 한번에 만들려고 하는 것이 아닌 기능을 테스트하며 점진적으로 업그레이드 하는 것이 중요하다고 생각된다.

ex) 자동차를 만들 때
처음부터 자동차의 바퀴, 문, 엔진등을 만드는 것이 아닌,
자전거 -> 오토바이 -> 자동차의 순서로 기능을 업그레이드 하면서 만드는 식

Reference

https://gmlwjd9405.github.io/2018/06/03/agile-tdd.html
https://ko.wikipedia.org/wiki/테스트_주도_개발
https://manorgass.tistory.com/63

profile
생각하는 대로 살지 않으면, 사는 대로 생각하게 된다.

0개의 댓글