Test Driven Development(이하 TDD)에 한 때 많은 이야기가 논의 되었고 지금도 많은 곳에서 이슈가 되고 있습니다. 옹호하는 사람과 그렇지 않을 사람들의 입장이 팽팽한 듯 합니다.
특히나 아직까지 국내에서는 TDD에 대한 필요성을 많이 인식하지 못하고 있는 듯 합니다. TDD 정말 필요할까요? 아니면 정말 불가능한 Practice 인가요?
그렇다면 TDD로 진행할 때의 좋은 점과 한계점은 무엇이 있을까요?
일단 TDD는 논외로 치고 junit을 기반으로 하는 단위 테스트에 대해서 제 생각을 이야기해보죠. 저는 아직까지 100% TDD로 개발하지는 못합니다. 하지만 가능하면 단위 테스트를 만들려고 노력합니다. 가장 큰 이유는 빠른 피드백 때문입니다. 단위 테스트가 있으면 개발하고, 테스트하고의 사이클이 무지 짧아집니다. 그렇다보니 다양한 시도를 해볼 수가 있다는 생각이 들더군요.
가끔 jpa를 기반으로 개발하면서 매핑이 잘 됐는지 확인하거나 내가 의도한데로 sql 쿼리가 생성되었는지를 확인하기 위해 테스트 코드를 만듭니다. 이 부분은 단위 테스트가 아니라 통합 테스트라고 하는 것이 맞겠지만 내가 의도한데로 동작하는지를 확인하기 위한 용도로 유용하더군요. 특히 orm을 처음 사용할 때는 내가 의도한데로 동작하지 않아서 삽질을 하는 경우가 많은데 이런 경우 테스트 코드 만들어 놓고 계속 실행해가면서 내가 의도하는 형태의 매핑을 만들어 낼 수 있습니다.
그외 javascript의 validation 기능을 사용할 때도 qunit(http://qunitjs.com/)을을) 사용해서 단위 테스트 코드를 만들고 테스트를 진행했는데 상당히 유용하더군요.
따라서 저는 반드시 TDD는 아니더라도 특정 영역을 확인할 수 있는 단위 테스트, 통합 테스트는 반드시 있는 것이 좋겠다는 생각입니다. 빠른 피드백을 통한 학습, 개발은 정말 우리들의 생산성을 높여줄 수 있다고 생각하거든요. 따라서 테스트의 가장 큰 강점은 빠른 피드뱅이라고 생각합니다.
그럼 TDD는 어떨까요? 왜 해야될까요? 이 부분이 항상 의문입니다. 개인적인 생각으로는 TDD를 하지 않으면 테스트가 필요한 부분에 단위 테스트 코드를 만들지 않고 Production 코드를 만드는 경험을 종종 합니다. 특히 마음의 여유가 없을 때는 더더욱 그렇죠. 그리고 Production 코드를 만들고 잘 동작하면 이후에 테스트 코드를 추가하는 것은 정말 쉽지 않은 일입니다. 이런 의미에서 TDD를 연습하고 적극적으로 활용하는 것이 중요하지 않을까 생각되네요. 물론 TDD의 최초 의도는 다르겠지만요.
단위 테스트 코드 많이 만드시나요? 여러분의 경험을 듣고 싶네요. 아니면 테스트에 대한 개인적인 생각이라도..
16개의 의견 from SLiPP
저는 단위테스트 코드를 만들기는 하는데, 자발적으로 내 코드를 테스트하기위해서가 아니라 산출물로 만들고 있어요. TDD방식도 아닌데다가 개발이 다 끝나면 만들고 있어서 처음엔 거부감이 많이 들더라고요~ TDD로 하면 코드를 복잡하지 않게 만들 수 있어서 TDD로 하고싶지만, 습관 들이기가 쉽지 않은거 같아요.
@최혜영 산출물로 만드는 것은 오히려 테스트에 대한 거부 반응이 생길텐데. 어차피 산출물도 만들어야 하는 상황이라면 이번 기회에 앗싸리 테스트를 제대로 만들어 보면 재미도 있고, 배우는 것도 많을 듯하다. 생각을 바꾸고 마음이 움직여 실행하는 것이 가장 좋은 효과를 볼 수 있잖아.
수십장 API 사용문서보다 API에 대한 TDD 코드 IN/OUT에 대한 코드를 봐도 쉽게 개발자들에게 더 도움이 됩니다.
어려운점은 개발자들이 개발이 완료된후 TDD코드를 산출물로써 받아들여서 초기에 적응이 힘드네요. TDD는 개발초기에부터 적용하는것이 몸에 익숙해지면 오히려 그런 부담이 더 줄고 테스트를 좀더 쉽게 만들려고 하다보니 리펙토링과정이 같이 진행되어 일석이조가 되네요 ^^ 이히히
전 TDD과정은 Serivce와 Persistence 계층까지만 하는데 UI쪽은 QA에게 그냥 맡기능 T.T ,어디까지 커버할지는 쉽게 결정내리기가 어렵네요
@김형석 정말 TDD를 산출물로 인식하는 순간 만들기 싫을 듯 합니다. 하지만 아직까지는 대부분의 조직이 하나의 평가 항목이나 소스 코드 품질을 따지는 일환으로만 생각하는 경향이 있어서 아쉬움이 있네요. 물론 중요한 부분이기는 하지만 순수한 목적으로 접근하지 않으면 효과는 많이 반감될 듯 하네요.
저는 ORM 사용하고 있어서인지 Persistence 계층은 테스트를 만드는 경우는 거의 없네요. 가능하면 테스트를 쉽게 할 수 있도록 Domain 클래스로 로직을 빼려고 노력하고 있습니다. 쉽지 않은 경우도 있지만 노력하면 상당 부분 가능하지 않을까라는 생각을 해봅니다.
(의견) 뭐 이런 이야기 나오면 항상 나오는 이야기 이지만, 'TDD' 와 'TestCode 의 작성의 필요성'이 짬뽕되는 것에 대해서는 경계를 가지고 진행되면 좋겠습니다. Test 를 작성하는 것과 TDD 간에는 어떤 논리(테스트냐 제품코드냐) 가 Driver 가 되느냐의 차이가 있다고 생각합니다.
짧은 경험이나마 오늘 내일 사이에 시간 내서 올려볼께요.
TDD의 장점 뿐만 아니라 단점과 유용한 도구를 잘사용하기까지 험난한 수련 과정 또한 숙지를 해야겠지요....
@김형석 그런것 같습니다. 잘 작성된 테스트케이스는 사용설명서 같은 느낌을 받습니다.
TDD 에 대한 개발자 인식변화도 중요한 것 같고 테스트케이스를 작성하고 버려두는 것이 아니라 꾸준한 리펙토링 과정이 중요하더라구요...
개인적으로는 '잘 작성해야 한다...' 라고 맘먹는 것 때문에 더 안하게 되었던 것 같아요. - 보고 들은게 많아서.. 거참.
TDD 에 느낌을 적는다면(글발이 안올라 쓰고 지우기를 반복합니다...) .....
불필요한 코드를 작성하지 않게 된다는 것입니다. 작성할 클래스에 대해서 이렇게 이렇게 사용하고 이럴때는 이렇게 동작하기를 원한다라고 미리 작성하고 진행하기 때문인것같습니다.
헌데....테스트케이스를 잘 작성하기란 좀처럼 쉬운것이 아니더라구요 ㅋㅋ 일단 테스트에 대해서 이해를 할 필요가 할듯 싶고요 (머 깊게는 모르더라도... 화이트박스,블랙박스, 상태테스트, 행위테스트 , Mock ,Stub등등) 무엇을 테스트케이스로 작성해야하는지 척하면 척하게 많은 연습과 숙달이 필요한듯 싶습니다. 오류사항을 먼저 테스트 케이스로 시작을 하고 경계값을 테스트로 작성한다든지..... 숙달되지 않고 한다면 굉장히 재미없고 지루한 작업이기도 한것 같습니다....
또 아무런 유닛없이 사실상 테스트작성하기가 어럽게 때문에 여러가지 도구들이 필요하기도 한듯 싶습니다. Mockito, Hamcrast ,dbUnit 요렇게 테스트 케이스를 하나 작성하기 위해서 아니 숙달되기 위해서 머나먼 길이 기다리고 있기 때문에 단점이라면 숙달되는데 굉장한 노력이 필요하다라고 말하고 싶네요....
어제 오티 하실때 전 테스트케이스를 추가하며 디버깅을 하고 있었습니다. 느낌은 내가 어느부분에 대해서 무엇만 테스트하면 언제 일이 끝날수있겠구나 하고 감이 오더라구요...(물론 딱 맞아떨어지진 않았고 오버를 했습니다.)
TDD BDD DDD 등을 접해보질 못해서 인터넷검색을 통해 개념을 잡으려고 합니다. ^^ 처음 접하는 거라 쉽지는 않지만 장/단점을 얘기할 수 있게끔 서둘러야 겠어요.
아직은 TDD를 통해서 개발하는 것이 습관이 들지가 않네요. ^^; 도메인을 중심으로 설계한 도메인이 생각한대로 정상적으로 동작하는지 확인하기 위한 테스트 케이스들을 초반에는 열심히 작성을 했습니다. 그렇게 하다가 기획변경에 의해서 도메인을 수정해야하는 경우들이 생기는데, 이런 떄는 습관적으로 도메인을 먼저 손대게 되네요. ^^; 지금도 대부분의 도메인이 어느정도 안정화된 상황 속에서, 기능개발해야되는 것이 많다는 핑계를 대면서 테스트 작성에 대해서 소홀해지게 됩니다.
테스트를 중심으로 개발하는 방식은, 분명히 프로젝트 초반에 강한 이점을 가지게 됩니다. ^^ 특히나 도메인 중심으로 개발을 하게 될 때는 도메인의 동작들을 테스트케이스를 통해서 확인해볼 수 있다는 게 좋죠. 영속화 하는 부분은 크게 신경쓸 필요도 없고...
지금은 도메인의 초기 구현후 기능 테스트, 중요 기능에 대한 확인을 위한 부분에는 '반드시 작성해보자.' 라는 생각으로 시도를 하고 있습니다. '반드시'가 '당연히'라는 것이 자연스럽게 몸에 스며들 수 있도록 꾸준히 시도를 해야죠. ㅎㅎ
TDD를 가까이 하려면, 그것이 필요한 것을 스스로 납득할 수 있는 상황들을 자주 부딪쳐야 시도를 해보게 되더라구요. ^^
TDD 방식의 개발은 분명 장점이 많은듯 합니다.
하지만 일반적인 프로젝트 (SI)에 나가보면 TDD 방식으로 코딩을 한다면... "왜 이런 필요없는 코드를 만들었지? FP(Function point)로 잡혀서 개발비가 산정되는것도 아니고.... 고객의 요구사항이 변경되면 쓸데없는 코드가 될텐데... 어짜피 UI 붙이고, 단위테스트, 통합테스트, 시스템 테스트, 인수테스트 등을 하게 될텐데... 굳이 테스트 코드를 넣어야 되나?" 라는 이야기를 주로 듣게 되더라구요.
그리고 영업파트 담당자께서는 이런 말씀도 하시더군요.. "개발자가 개떡처럼 만들어도, 사용자가 찰떡처럼 쓰면 그게 장땡이다." 꿈꾸는건 21세기 미래지향 모델인데, 현실은 20세기 삽질을 하는 모습이랄까요.
솔찍히 저는 저 자신을 잘 믿지 못하겠더라구요... 아무런 테스트 없이 구현한 DAO, Service, Controller와 SQL들... 그리고 UI에 적용한 여러가지 상관관계들...
우연찮케 한번에 모든 프로세스들이 딱 맞물린다면, 정말 좋겠지만 그런 경우는 20-30%에 지나지 않나 싶네요 ㅠㅠ (그게 톱니바퀴처럼 딱 맞춰서 돌아가게 만든다면, 제가 진짜 장인이겠지요.)
개발 문화 자체가 그런 방식을 받아들일 성숙도가 부족하다면, 아무리 좋은 이론도 그냥 이론으로 치부되는 현실이 있는것 같습니다. (사실 그런 모습을 저 스스로만이라도 개선을 하고자 스터디에 참여하게 되었지만요 ^^)
저도 한때는 TDD가 개발 문화가 되어서 팀내에 공유가 되어야 한다고 생각했던 때도 있었습니다만.. keisus 님이 말씀해주신 것과 같은 질문에 그닥 답을 하기 쉽지 않더군요.. 개발자마다 생각도 다르고.. 특히 자신의 코드에 만족하시는 분들이야.. 아..필요가 없을수도 있겠구나..생각도 들고;;
그래서 전 그냥 능력없는 제가 만드는 생산품의 품질을 높이기 위한 제 나름의 무기라고 생각했습니다. 내가 개발자로서 만드는 코드들이 좀 더 좋은 코드가 되기 위한 개발자의 선택지 중에 하나다..
저도 비슷한 생각의 관리자분 밑에서 일해본 적이 있었는데, 더 나아가..예전에 적용해봤었는데 그런 어려움이 있었다라는 생각까지 가지고 계신 분이었죠;;
그래서 제가 만드는 코드에 대한 요구사항을 명확히 하고, 제가 편하고, 다른 사람들한테 영향 안 줄테니.. 그냥 제가 만든 코드들은 알아서 테스트 코드 만들고 유지 하겠습니다... 그렇게 몇 주가 지나고 보니 다른 분들이 하나 둘 테스트 케이스를 만들기 시작하고.. 나중에는 관리자 분이 이거 테스트케이스 있는 코드냐고 믿을 수 있는 거냐고.. 문의하시더군요..
제가 경험해본 환경이 그다지 큰 프로젝트가 아니어서 그런지는 모르겠습니다만.. TDD는 주변 환경에 영향을 받기보다는 개발자 혼자서도 충분히 자신의 영역에서 적용가능한 방법론이라고 생각합니다. 그리고 그러다보면 주변 분들이 그 장점이나 효용성을 인식하면 변화하시는거고,.. 아니어도 잘 개발하시면 되는 분들은 그냥 계속 개발하시면 되고..
결국 항상 코드를 작성할 땐 "아무리 급해도 결국 테스트를 작성하는 길이 더 빠른 길이다" 라는 생각을 꾸준히 유지할 수 있을 경험을 쌓고, 그런 모습들이 다른 사람들에게 좋은 모습으로 보여질 수 있도록 스스로의 테스트 기술을 갈고 닦는 "멘탈"이 참 중요한 것 같다고 생각하는 요즘입니다.
첨 쓰는 글이라..원래 온라인에 글을 잘 안써봐서..두서가 없네요. 죄송합니다.;
@bluebird702 진정성이 담겨서 인지 마음 속에 팍팍 다가 오네요. 글과 강의에 대해서 잠시 이야기하면 저는 진정성이 가장 중요하다고 생각합니다. 진정성이 묻어나면 그 만큼 좋은 글과 강의는 없는 듯 합니다.
다시 TDD로 돌아가서 저도 bluebird702(진수 맞죠?)님 의견에 공감합니다. 멘탈이 참 중요하다는 말. TDD는 주변 환경보다는(물론 성공하기 위해서는 중요하기는 합니다.) 자기 자신과의 싸움이라고 생각합니다. 아무리 그런 환경을 만들더라도 하지 않는, 어쩌면 못하는 개발자들이 대부분입니다. 아직까지 이 길이 정말 빠른 길이라는 것을 느끼지 못했기 때문이라고 생각합니다. 저 또한 TDD로 진행하다 Production 코드 먼저 만들다가 상황에 따라 들쭉날쭉입니다. 하지만 지속적으로 시도하는 이유는 이 길이 빠른 길이라는 확신은 있기 때문입니다. 그럼에도 불구하고 잘 되지 않는 이유는 개발 습관이 잘못 들었기 때문이라고 생각합니다. 처음부터 TDD에 익숙했다면 좀 더 수월하게 접근하지 않았을까라는 막연한 생각입니다. 자기 자신과의 싸움에서 승리하면 그 가치를 인정하는 사람들이 생기고, 점차 단위 테스트의 중요성을 인식하리라 생각합니다.
현재 조직에서는 많은 사람들을 설득하고 그 당위성을 이해시켜야 하기 때문에 쉽지 않은 길이라 생각하고요. 스터디에서나마 TDD를 경험하고 실무에서 조금씩 사용하는 연습해보면 좋겠습니다.
안녕하세요. 자바지기님의 글은 가끔 검색으로 통해 접하게 되는데, 언제나 잘 보고 있으며 항상 도움 받고 있습니다. 저는 안드로이드 개발에 TDD를 적용하고 있습니다. 이제 1년이 다 되어 가네요. 엔터프라이즈급과는 규모가 달라서 얼만큼 도움이 될지는 모르지만 그동안 느낀 점에 대해서 남겨보겠습니다.
처음 유닛테스트에 대한 거부감을 많이 완화 시켜준 계기부터 말씀 드리고 싶네요.
어느 책에서, 테스트는 본질적으로 우리가 흔히 작성하던 코드와 별반 다르지 않다는 글을 접한 것이 그 계기였는데, 느낀 점이 많았습니다.
잘 작동하는지 확인하기 위해 제품에 직접 삽입하던 로그를 단순히 제품 밖으로 분리하는 것, 눈으로 확인하던 로그를 코드로 확인하는 것. break point를 걸어서 디버깅 하던 것을 코드로 하는 것, 빌드를 자동화 처럼 테스트를 자동화 하는 것, 제가 늘상 하던 작업과 테스트작성은 본질적으로 다르지 않았습니다.
또한, 스스로 한 번 구현했던 코드들은 의심 없이 재사용하고 싶었고, 설사 수정이 필요한 부분이 있다고 해도 검증이 끝난 부분을 다시 되짚는 수고는 하고 싶지 않았습니다. 이런 바램도 유닛테스트가 도와 줄 수 있다고 판단했습니다.
그럼에도 TDD에 관해서는 다소 회의적이었습니다. 테스트부터 역순으로 작성하는 것은 어딘지 순리에 어긋난 듯한 느낌도 있었지만, 결국 고민할 시간에 일단 써보자고 결심하게 되었습니다.
우선 느낀 장점은 너무 많아서 일일히 나열하기가 힘들 정도입니다. 그리고 대부분 애자일, TDD의 현인들께서 언급하던 장점과 상당히 일치했습니다. 그래도 개인적으로 위에서 언급하셨던 장점을 제외하고 가장 많은 도움을 받았던 부분을 몇 가지만 추려보면, 1. 구현의 유연성 향상 : 테스트에 맞추다 보면 비슷한 루틴도 다양한 형태로 고민하게 됩니다. 설계가 잘 안될 때에는 우선 구현을 해 봐야 답이 나오는 경우가 종종 있는데, 빠르게 픽스쳐를 세팅하고 구현이 필요한 부분만 고립시켜 구현할 때 많은 도움이 되었습니다. 2. 코드의 품질 보증 : 애자일에서 요구하는, 잦은 변경이나 수정에 대해서 대응 하는데 많은 도움이 됩니다. 종료 된지 몇 개월 지난 프로젝트의 수정 요청을 받아 코드를 변경했을 때, 문제는 없는지 확신하지 못하는 책임감 없는 개발자가 되지 않도록 도와 주었습니다. 추가적으로 규모가 작아서 따로 QA부서가 없기 때문에 Robotium등을 활용한 통합테스트와 CI등도 많은 도움이 되었습니다. 3. 집중력 향상 : 두뇌에서 "의심, 불확신, 반복작업" 등등의 프로세스를 내리는데 많은 도움이 됩니다. 결과적으로 좀 더 개발이 즐거워졌습니다.
그리고 제가 느낀 단점으로는, 1. 진입장벽 : 처음 TDD를 시도했던 순간은 결코 잊을 수가 없을 것 같습니다. 테스트 코드 딱 한 줄을 작성하고 나서는 반나절을 멍하니 모니터만 쳐다보고 있었습니다. 무엇을, 어떻게, 왜 내 코드를 테스트 해야 하는지 하나도 명확하게 떨어지지 않아서 소위말하는 멘붕상태에 빠졌었습니다. 스스로 많이 부족하다고 느꼈습니다. 제 실력 때문인지, 테스트가 어려운 것인지조차 구분이 안되는 상황이 계속 벌어졌고, 테스트 코드가 복잡해 질 수록 문제는 더더욱 늘어났습니다. 결국 처음으로 TDD를 시도했던 프로젝트는 도입을 포기하게 되었습니다. 2. 오해와 편견 : 테스트는 결코 쉽지 않았으며, Silver Bullet도 아니었습니다. UI, 쓰레드, 네트워크등 테스트 하기 힘든 부분들은 분명히 존재하고, 테스트를 빠져나가는 버그들도 존재했습니다. A/B 테스트라도 해 볼 수 있으면 좋으련만, 종종 테스트에 의한 설계가 내가 이전에 작성했던 것 보다 나은지에 대한 의심도 끊임없이 괴롭혔습니다. 3. 관리의 어려움 : 초반에는 정말 테스트코드가 풍선처럼 부풀어 제품코드의 두 세배는 되는 듯 느껴졌습니다. 중복도 많았고, 관리하는 스킬도 부족했고... 일정 추정도 안되었고... 애자일의 고객/유저와 개발자의 관계에 깊이 공감하고 있으며 적극적으로 실천하고 싶은데, 짧은 이터레이션과 그 수정에 따르는 부담은 과연 애자일과 TDD가 같이 가는 것이 가능한지에 대한 의문이 끊임없이 괴롭혔습니다.
그런데 좋은 테스트코드들을 접할수록 단점들을 극복할 수 있다는 희망이 생겼고, 실제로 점점 개선 되었습니다. 아직도 많이 부족하지만, 이전 방식에 비해서 비효율적이 아니란 것은 확신 할 수 있을 것 같습니다. 그리고 시간이 지나면 분명 모든 점에서 훨씬 더 향상 될 것이라고 생각합니다. 현재는 테스트가 어려운 부분에 대해서는 일정을 초과해서 굳이 시도하려고 하지 않습니다. 다만 테스트 되는 부분과 그렇지 않은 부분은 확실히 구분하려는 노력만으로도 현재 단계에서는 충분하고, 한 걸음씩 발전해 나가면 된다고 생각합니다.
위의 몇몇 분께서 언급 하셨던 것 처럼, TDD에 대해서 말로 설득하는 것 대신 효용성에 대해서 좀 더 적극적으로 보여줄 만한 무엇인가가 있었으면 하는 것이 최근의 제 바람 중 하나입니다.
하고 싶은 말이 많았는지 글이 길어졌네요... 읽어주셔서 감사합니다.
@최정열 정열님의 경험담을 공유해주셔서 공감하면서 재밌게 읽었습니다. 제가 고민하고 느꼈던 많은 부분들을 비슷하게 느끼는 분들이 많다는 것이 재밌네요. 어쩌면 TDD를 하면서 대부분의 프로그래머가 느끼는 감정이리라 생각합니다. 그런 어려움을 극복하고 꾸준하게 정진하는 정열님의 열정이 부럽네요. 자기 자신과의 싸움에서 이겨나가는 모습이 보기 좋네요. 앞으로도 TDD나 그외 ATDD 등에 관련한 경험담 있으시면 한번씩 글 남겨주세요.
나뿐만 아니라 주위의 많은 개발자들이 비슷한 고민을 했고, 어려움을 극복해 가는 과정을 안다면 힘들고 포기하고 싶더라도 더 많은 개발자들이 도전하지 않을까 생각합니다. 그러면서 점점 더 많은 노하우가 공유되고, 대안들을 찾아나가리라 생각합니다. 좋은 글 다시 한번 감사 드려요.
다른 분들의 글과 경험을 접하면서 항상 도움만 받아 왔는데, 보탬이 되었다고 말씀해주시니 정말 기쁩니다. 제가 많이 부족해서 도움은 커녕 민폐만 끼칠지도 모르지만, 용기내서 제 경험은 공유하도록 노력하고 많이 묻고 배우도록 하겠습니다. 감사합니다~
의견을 남기기 위해서는 SLiPP 계정이 필요합니다.
안심하세요! 회원가입/로그인 후에도 작성하시던 내용은 안전하게 보존됩니다.
SLiPP 계정으로 로그인하세요.
또는, SNS 계정으로 로그인하세요.