테스트 주도 개발, TDD 그리고 프로그래밍
Posted by 시리니07月 3
회사에 입사한 이후 어느 덧 시간이 흘러 저도 실무에 투입을 하게 되었습니다. MFC 를 이용한 나름 간단한(?) 유틸리티를 제작하는 임무를 받았는데요, 그 때 저의 지도 선배님께서 알려주신 절차들을 정리해 보면 아래와 같습니다.
제일 장점은, 역시 코드를 좀 더 신중하게 작성하는 태도가 생긴 것이라 생각 됩니다. 그 동안 저는 제가 작성한 코드던 다른 사람이 작성한 코드던 "신뢰성" 이라는 부분에 대해서는 별로 깊게 생각해 보지 않았습니다. 입력이 잘못되면 어떤 결과가 초래될까, fatal 에러가 생겨서 프로그램 전체가 멈추게 될까 아니면 예외 처리를 통해 핸들링이 가능할까 같은 것 조차도 제대로 생각해 보지 않았었습니다.
단순한 덧셈 함수나 swap 함수를 구현한다 하더라도 이제는 테스트 케이스를 어떻게 해야 올바른 검증이 될까를 먼저 생각하게 됩니다. 물론 시간이 많이 걸립니다. 특히 저 처럼 내공이 부족한 사람은 정말 많이 걸립니다. 로직을 구현하는 데만도 시간이 걸리는데 거기다 로직에 대한 테스트 케이스를 고민하고 또 테스트 코드를 작성하는 것은 시간이 정말 많이 걸리는 일이죠. 매번 테스트를 할 때마다 컴파일을 해서 구동시켜 직접 확인해 보는 것은 당연하구요.
하지만 이러한 시간 투자는 오히려 당연하다고 생각 됩니다. 나중에는 내공이 쌓이면 테스트 케이스를 작성하는 데 그리 오래 걸리지 않을 것 같고, 또 이렇게 작은 단위별로 무결성을 확보해 나가는 습관을 들여 놓으면 높은 품질의 코드를 작성 할 수 있을 것 같습니다. 프로그래밍을 처음부터 다시 배우는 느낌입니다. ^^;;
사실 아직은 잘 모르겠습니다. TDD 를 쓰면 좋겠다는 생각은 있지만, 작업을 하는 도중에는 수시로 "아... 이 메소드는 또 어떻게 검증하지? 테스트 코드도 짜야되네..." 하는 생각이 많이 듭니다. 그렇지만 투덜 대면서도 막상 테스트를 해서 결과를 보면 또 그렇게 든든할 수가 없습니다. 저는 지금 gtest (Google Test) 를 쓰고 있는데 빨간색, 초록색 글자들이 뒤섞여서 내가 작성한 코드를 자동으로 검사 해주니 정말 믿음직스럽더군요. (PASS 가 하나씩 늘어 날 때마다 생기는 그 소소한 성취감이란... ㅎㅎ)
저는 프로그래밍도 여러 가지의 방법론이 있을 수 있다고 생각 합니다. 사실 TDD 없이도 여태까지 프로그래밍을 잘 해왔고 앞으로도 TDD 를 무조건 신봉할 생각은 없습니다. 이 것도 하나의 방법이고, 또 다른 길은 언제나 존재할 테니까요.
하지만, 그럼에도 저는 앞으로 한 동안 TDD 를 연구해 볼 생각입니다. 공부한다고 표현하기엔 TDD 의 재미가 반감될 수 있을 것 같습니다. 유닛 테스트를 어떻게 하는 게 정석인지 고수님들의 코드를 구경해보고, 저도 저 나름의 방식으로 한 번 시도해보는 식으로 이 TDD 라는 친구를 알아가 볼까 합니다.
음, 어떨까요? 자신의 코드를 자신이 직접 검사해 나간다..., 하나씩 PASS 를 늘려 가다가 모두 PASS 되면 프로그램이 완성되는, 마치 온라인 게임에서 캐릭터가 만렙을 향해 달려가듯 내 프로그램도 수 많은 테스트의 시련을 거쳐 (때론 반복적인 노동도 있지만!) ALL PASS 의 영광을 만끽해보는 그런 재미도 좋지 않을까요? ^^;;;
덧. 혹시 TDD 와 관련해서 볼 만한 책을 알고 계시는 분들은 추천 좀 부탁드립니당... ㅎㅎ;
- StarUML 을 이용하여 클래스 다이어그램을 그려보고, 먼저 설계를 꼼꼼히 해볼 것
- Google Test (gtest) 를 이용하여 유닛 테스트를 습관화 할 것
- 가독성이 먼저다. 코드를 단순하게 읽기 쉽게 작성할 것
왜 그런 거 있잖아요. 교과서에 보면 참 좋은 말들이 많은데 막상 현실 세계에서는 잘 실천하지 않는 것들... 오히려 지키면 손해라고 생각되는 것들이 많이 있지요. 저는 프로그래밍의 세계에서 적어도 TDD 같은 이야기는 내 이야기가 되진 않을 거라고 지레 짐작 했었는데, 현업에 와서야 그 생각이 얼마나 잘못되었는지를 알 수 있게 되었습니다.
딱히 TDD 라는 거에 반감을 가지거나 그렇진 않습니다. 오히려 무지했다고 표현하는 게 적합하겠네요. 정말 어떻게 신문지상에서 들을 법한 단어와 어림 짐작으로 뜻을 알긴 하지만 사전적 의미 그 이상도 이하도 아닌 정도. 딱 그 수준이었습니다. 쓰면 좋긴 하겠지... 근데 어느 세월에 테스트 케이스를 다 만든데? 뭐 이런 느낌?
근데 막상 실무에 투입하면서 제대로 공부를 하고 적용하기 시작하니까... 아래의 사항들이 조금 어렵고 힘들더라구요.
- 클래스를 거의 2배 가량 작성해야 함 (구현 클래스 하나, 테스트 클래스 하나 이런 식)
- 구현 알고리즘보다 테스트를 어떻게 할 것인가, 어떻게 신뢰할 수 있을까 고민하는 게 어려움
- 코드를 작성하면서도 자꾸 테스트 케이스를 의식해서 그런지 멈칫 멈칫함
아직 말 그대로 잘 모르는 상태에서 조금씩 적응하는 단계라 그럴 수도 있겠지만, 정말 알고리즘이나 루틴한 코드들을 구현하는 시간 보다 오히려 테스트 코드를 작성하고 어떻게 검증을 해야 할까 고민하는 시간이 더 많아졌습니다. 결과적으로는 작업 시간이 거의 체감상 3배 정도 늘어진 것 같은 느낌입니다. 이전 같았으면 이렇고 저런 뻔한 코드들은 대충 뚝딱뚝딱 조립해서 쓰곤 했는데 이젠 메소드 하나 추가 할 때마다 이 놈은 어떻게 테스트를 해야 하나... 이 생각에 시간이 많이 걸리네요.
사실 프로그래밍을 그리 잘 하지도 못할 뿐더러, UML 을 그려 가면서 설계에 이렇게까지 시간을 많이 쏟아 부었던 적은 없었습니다. UML 을 설계할 때도 지도 선배님의 설계가 70% 이상이었고, 인터페이스와 구현클래스를 어떻게 나눌지 MVC 패턴을 어떤 식으로 적용할 지에 대해 식견이 짧았던 전 설계에 이렇게까지 시간을 투자하는 선배님이 의아했습니다. 아니, 프로젝트 완료 기한이 있는데 이래도 되나...? 하는 생각이 들기도 했지요.
설상가상 거기다 TDD 방식으로 개발을 진행 해보자 하시니 이거 원 답이 안나왔습니다. 어떻게 해야 하나, 설계는 시간을 쏟은 만큼 제대로 나온 거 같아서 다행이긴 한데 개발까지 TDD 로 진행하면 테스트 케이스 만들다가 끝나 버리는 건 아닐까... 그리고 막상 TDD 로 개발을 하게 되니 UML 을 수시로 업데이트 하랴, 구현 클래스 수정 하랴, 테스트 조건 변경하랴 난리도 아니었습니다.
하지만 지금에 와서는 지도 선배님이 저에게 말하고 싶었던, 혹은 선배 개발자로서 알려주고 싶었던 또 다른 길이 약간씩 보이는 것 같기도 합니다. 다시 처음으로 돌아가 프로그래밍을 배우는 심정으로 되짚어 보니 아래와 같은 것들이 장점이라고 생각됩니다.
- 테스트 케이스를 먼저 생각하게되니 메소드 구현에 좀 더 신중해짐
- 테스트 과정에서 입력 / 출력을 자동화 하게 되니 굳이 내가 검증하지 않아도 됨
- 알고리즘 구현에만 치우쳐진 편향된 시각이 테스트 및 신뢰성이라는 것까지 좀 더 넓혀짐
제일 장점은, 역시 코드를 좀 더 신중하게 작성하는 태도가 생긴 것이라 생각 됩니다. 그 동안 저는 제가 작성한 코드던 다른 사람이 작성한 코드던 "신뢰성" 이라는 부분에 대해서는 별로 깊게 생각해 보지 않았습니다. 입력이 잘못되면 어떤 결과가 초래될까, fatal 에러가 생겨서 프로그램 전체가 멈추게 될까 아니면 예외 처리를 통해 핸들링이 가능할까 같은 것 조차도 제대로 생각해 보지 않았었습니다.
단순한 덧셈 함수나 swap 함수를 구현한다 하더라도 이제는 테스트 케이스를 어떻게 해야 올바른 검증이 될까를 먼저 생각하게 됩니다. 물론 시간이 많이 걸립니다. 특히 저 처럼 내공이 부족한 사람은 정말 많이 걸립니다. 로직을 구현하는 데만도 시간이 걸리는데 거기다 로직에 대한 테스트 케이스를 고민하고 또 테스트 코드를 작성하는 것은 시간이 정말 많이 걸리는 일이죠. 매번 테스트를 할 때마다 컴파일을 해서 구동시켜 직접 확인해 보는 것은 당연하구요.
하지만 이러한 시간 투자는 오히려 당연하다고 생각 됩니다. 나중에는 내공이 쌓이면 테스트 케이스를 작성하는 데 그리 오래 걸리지 않을 것 같고, 또 이렇게 작은 단위별로 무결성을 확보해 나가는 습관을 들여 놓으면 높은 품질의 코드를 작성 할 수 있을 것 같습니다. 프로그래밍을 처음부터 다시 배우는 느낌입니다. ^^;;
사실 아직은 잘 모르겠습니다. TDD 를 쓰면 좋겠다는 생각은 있지만, 작업을 하는 도중에는 수시로 "아... 이 메소드는 또 어떻게 검증하지? 테스트 코드도 짜야되네..." 하는 생각이 많이 듭니다. 그렇지만 투덜 대면서도 막상 테스트를 해서 결과를 보면 또 그렇게 든든할 수가 없습니다. 저는 지금 gtest (Google Test) 를 쓰고 있는데 빨간색, 초록색 글자들이 뒤섞여서 내가 작성한 코드를 자동으로 검사 해주니 정말 믿음직스럽더군요. (PASS 가 하나씩 늘어 날 때마다 생기는 그 소소한 성취감이란... ㅎㅎ)
저는 프로그래밍도 여러 가지의 방법론이 있을 수 있다고 생각 합니다. 사실 TDD 없이도 여태까지 프로그래밍을 잘 해왔고 앞으로도 TDD 를 무조건 신봉할 생각은 없습니다. 이 것도 하나의 방법이고, 또 다른 길은 언제나 존재할 테니까요.
하지만, 그럼에도 저는 앞으로 한 동안 TDD 를 연구해 볼 생각입니다. 공부한다고 표현하기엔 TDD 의 재미가 반감될 수 있을 것 같습니다. 유닛 테스트를 어떻게 하는 게 정석인지 고수님들의 코드를 구경해보고, 저도 저 나름의 방식으로 한 번 시도해보는 식으로 이 TDD 라는 친구를 알아가 볼까 합니다.
음, 어떨까요? 자신의 코드를 자신이 직접 검사해 나간다..., 하나씩 PASS 를 늘려 가다가 모두 PASS 되면 프로그램이 완성되는, 마치 온라인 게임에서 캐릭터가 만렙을 향해 달려가듯 내 프로그램도 수 많은 테스트의 시련을 거쳐 (때론 반복적인 노동도 있지만!) ALL PASS 의 영광을 만끽해보는 그런 재미도 좋지 않을까요? ^^;;;
덧. 혹시 TDD 와 관련해서 볼 만한 책을 알고 계시는 분들은 추천 좀 부탁드립니당... ㅎㅎ;
2 Responses
[nabiko] DELETE REPLY*
[시리니] DELETE