IT/IT 일반

TDD(Test-Driven Development), 단위테스트 개요

lI헐헐Il 2012. 6. 12. 16:38

소프트웨어 프로젝트에서는 많은 종류의 테스트를 수행할 수 있고 또 수행해야 한다.
이 테스트 중 일부는 최종 사용자가 광범위하게 개입해야 하고, 또 일부는 전담 QA 팀이나 또 다른 값비싼 자원들이 필요할 수도 있다. 그러나 TDD는 이런 테스트가 아니다.
프로젝트와 개인의 성공에서 필수적인 부분인 '단위 테스트'에 대해 이야기 하는 것이다.
단위 테스트는 더 나은 코드를 더 빨리 만들어 낼 수 있으며, 상대적으로 더 쉽고 비용이 적게 드는 방식이다.
많은 기업은 테스트에 관심이 무척 많지만, 프로젝트가 끝날 때에만 테스트를 하려는 경향이 있다. 그리고 정작 그때에 가서는 일정 압박 탓에 테스트 과정을 축소하거나 완전히 생략하기도 한다.
프로그래머는 테스트를 '직접 코드를 만들어 내는' 당장의 진짜 일에 집중하지 못하게 하는, 그저 귀찮고 성가신 일일 뿐이라고 생각한다.
단위 테스트는 기업의 품질 경쟁력만을 위한 것이 아니다. 최종 사용자나 경영진, 팀장들을 위한 것도 아니다.
프로그래머에 의해, 프로그래머를 위해 행해지는 것이다. 오직 우리의 이득을 위해, 우리의 삶을 더 편하게 만들기 위해 존재하는 것이다.

단위 테스트만으로도 성공과 실패가 갈릴 수 있다.

1. 확신을 갖고 코딩하기

1)A개발자
코드를 아주 빠르게 만들어 냈다. 그리고 종종 멈춰서 코드가 제대로 컴파일 되는지 확인했다.
하지만 최상위 프로그램을 실행하자 문제가 생겼다. 디버거를 써서 단계적으로 실행해 볼 시점이다. 코드를 거슬러 올라가며 잡기 어려운 이 문제가 생기기까지 과정을 되짚어 본다.
문제의 버그를 찾고 수정을 했지만 그 과정에서 버그가 몇개 더 생겼다. 어느덧 밤이 깊어졌다.

2)B개발자
도저히 빠르다고 할 수 없는 속도로 코드를 작성하였다. 새 루틴과 함께 짧은 테스트를 작성한다. 그리 대단한 것도 아니고, 단지 원래 의도대로 수행되는지 확인을 하기 위한 간단한 테스트 이다.
테스트를 생각하고 작성하기까지 시간이 약간 더 필요했지만, 새 루틴 자체를 검증할 수 있기 전까지는 더 진행해 나가지 않았다.

A, B개발자는 지적 능력이나 경력이 동일하다. 하지만 개발 방식이 다르다.

2. 단위 테스트란?

'단위 테스트'는 테스트 대상이 되는 코드 기능의 아주 작은 특정 영역을 실행해 보는, 개발자가 작성한 코드 조각이다.
대개 단위 테스트는 특정 상황에서 특정 메서드를 실험해 본다. 이는 어떤 코드 조각이 개발자가 생각한 대로 동작하는지 증명하기 위해 수행하는 것이다.
그 동작이 고객이나 최종 사용자가 바라는 것인지 아닌지는 해결되지 않은 채로 남는다. 이 부분은 인수 테스트의 목표이다. 아직은 공식적인 유효성 검증과 확인이나 정확성에 크게 신경쓰지 않는다.
이 시점에서는 성능 테스트에 조차 관심을 두지 않는다.
단지 코드가 의도대로 동작하는지 확인하는 것이고, 따라서 코드의 기능 중에 아주 작고 고립된 부분만 테스트하기를 원한다.
개개의 부분들이 생각한 대로 동작한다는 확신을 쌓아 나감으로써, 비로서 그것들을 조립하여 전체 동작 시스템을 테스트하는 단계로 나아갈 수 있다.

3. 왜 귀찮게 단위 테스트를 하지?

■ 삶을 편하게 해준다.
■ 설계를 좀 더 좋게 만들어 주고, 디버깅에 낭비하던 시간을 극적으로 줄여 준다.

A개발자의 경우 낮은 레벨의 코드가 제대로 동작한다고 가정하고 좀 더 높은 레벨의 코드에서 그것을 사용하였다.
하지만 낮은 레벨의 코드를 신뢰할 수 없다면 그 낮은 레벨의 코드만 고친다 해서 문제가 해결되지 않는다. 낮은 레벨의 문제를 고쳐도 그 영향은 더 높은 레벨의 코드에 미치고 이젠 그 코드도 고쳐야 하는, 그런 일이 계속 이어진다.
수정에 의한 영향은 전체 코드로 바이러스 처럼 퍼져 나간다.

B개발자의 경우 코드에 대한 확신을 얻기 위해서 코드에게 무슨 일을 하고 있는지 물어봐야 했고 그 결과가 기대한 바와 같은지 확인해 가며 프로그램을 완성해 갔다.
이 간단한 개념이 좀 더 나은 코딩을 위한 가장 확실하고 가장 효과적인 기법인 단위 테스트의 핵심이다.

4. 무엇을 이루길 원하는가?

자신의 삶을 그리고 동료들의 삶을 더 편하게 만들기 위해 단위 테스트를 한다.

1) 내가 원하는 일을 하는가?
"이 코드가 내 의도를 충족시키는가?"
자신이 생각한 그대로 코드가 동작한다는 것이 증명되기를 바란다.

2) 언제나 내가 원하는 일을 하는가?
자기가 테스트를 한다고 주장하는 많은 개발자는 줄곧 테스트 하나만 작성한다. 이런 것은 전체 코드에서 모든 것이 완벽하게 돌아가는 '올바른 한 길'만을 택한 반쪽짜리 테스트다.
하지만 당연하게도 항상 완벽하게 진행된다는 보장은 없다. 예외는 발생하고, 디스크는 꽉 차고, 네트워크는 끊어지고, 버퍼는 오버플로우되고, 그리고 버그를 만든다.
정해진 최상의 가정으로만 테스트 한다면 단편적인 경우만 검증될 수 있다. 코드가 어떤 여러가지 상황에서도 항상 내가 원하는 대로 움직이는 것을 확인해야 한다.

3) 의존할 수 있는가?
의존할 수 없는 코드는 쓸모가 없다. 설상가상으로 의존할 수 있다고 갱각되는 코드는 버그를 찾아내고 디버깅하는데 아주 많은 시간이 들 수 있다.
완벽하게 코드를 작성하는 사람은 없다. 그래도 괜찮다. 문제가 어디에 있는지 알기만 한다면 말이다.
우리가 작성한 코드에 의존할 수 있고 그 코드의 능력과 한계를 정확히 알 수 있으면 된다.

4) 의도를 문서화하고 있는가?
단위 테스트의 멋진 부대 효과중 하나는 의도한 코드의 사용법을 전달할 수 있게 해준다는 것이다. 실제로 단위 테스트는 개발자가 다양한 조건하에서 어떻게 코드가 동작할 것을 기대했는지 보여주는, 실행 가능한 문서화 역할을 한다.
팀원들은 테스트를 보고 코드를 사용하는 방법을 알 수 있다. 만약 누군가가 고려하지 못했던 테스트 케이스에 맞닥뜨리면 그 사실을 빨리 팀원들에게 경고할 것이다.
그리고 당연하게도, 실행 가능한 문서란 것은 정확한 상태의 유지라는 이점이 있다.

5. 단위 테스트를 어떻게 해야 하는가?

① 코딩전 문제가 되는 메서드를 테스트할 방법을 결정.
② 단위 테스트 실행.
③ 단위 테스트를 통한 통합 테스트 실행.(모든 테스트를 통과 시키기)

6. 테스트를 하지 않는 사람들의 변명

■ 테스트 작성까지 시간이 너무 많이 걸린다.(단위 테스트에 입문한 대부분의 불평 1위)
- 코드를 디버깅하는데 얼마나 시간을 쓰는가?
- 제대로 동작한다고 생각했지만 중대하고 심각한 버그가 드러난 코드를 다시 뜯어고치는데 얼마나 시간을 쓰는가?
- 드러난 버그가 발생한 위치를 파악하는데 얼마나 시간을 쓰는가?

■ 테스트 실행이 너무 오래 걸린다.
대부분의 단위 테스트는 굉장히 빠른 피드백을 준다 하지만 때론 지나치게 오래 걸리는 테스트가 나올수 있다.
이 경우에는 짧은 테스트에서 더 오래 걸리는 테스트를 분리하고 싶을 것이다. 오래 걸리는 테스트는 하루에 한 번이나 적절히 며칠마다 한 번씩 정도로 실행해보고, 짧은 테스트는 자주 실행해 보면 된다.

■ 내 코드를 테스트하는 것은 내 일이 아니다.
이쯤되면 막가는 말이 나올법 하다. 진지하게 말해서, 그렇다면 정확이 내가 할 일인 것은 무엇인가?
코드가 제대로 동작한다는 아무 보증도 없이 벽 너머의 테스트 팀에게 코드를 내팽개친다면, 자신의 일을 완수하지 않은 것이다.
극단적으로 말하자면 자신이 어질러 놓은 것을 다른 사람이 치워주길 기대하는 것은 교양있는 처신이 아닐뿐 아니라, 출세를 막는 수가 될 수 있다.
실제로 지식과 능력을 겸비한 우수한 개발자가 버그를 종종 발생하여 테스터들을 신나게 한다면(앗싸! 버그다!) 오히려 지식과 능력은 다소 부족하지만 꼼꼼한 개발자 보다 인정받기 힘들어 진다.

■ 난 코드가 어떻게 동작해야 할지 정확히 모르기 때문에 테스트할 수가 없다.
코드가 무엇을 해야 할지 알지 못한다면, 어떻게 정말 그 일을 한다고 확인할 수 있는가?
지금은 그것을 작성할 적기가 아닌 것이다.

■ 컴파일된다면 괜찮은거 아닌가?
컴파일러는 로직을 검증하는게 아닌 코드의 정확성을 검증하는 것이다.

7. TDD효과

■ 자가 테스트 : 자신의 실력 평가 및 개선할 수 있는 기회 제공
■ 테스트를 통해서 요구사항을 좀 더 명확히 하고 질 높은 소프트웨어 개발 가능

 

[출처: http://ingenuity.egloos.com/1834544/ ]