유닛 테스트를 내가 접한 지도 어언 10년이 되간다.

그간 내가 거쳐온 많은 회사에서 사용되기도, 무시되기도, 우선 순위에 밀리기도 하더라.

 

과정에서 제안도 여러 해보고, 설득 과정에서 자주 나왔던 질문이 있었다.

 

유닛 테스트하면 뭐가 좋은가요?

 

처음 질문을 받았을 당시, 답변은

 

테스트야 하면 당연히 좋은 거다

 

라고 답변했었다.


 

사실 누구나 테스트의 중요성은 배운다. 그래서 아주 작은 팀이고 여력이 부족하다면, 개발팀 테스트라도 소화하려고들 하는 것은 사실이긴 하다.

 

하지만 많은 사람들에게 테스트란 재미없고, 지루하지만 해야만 하는 교리 같은 것에 불과하다는 것이 문제다.

듣는 사람도 고개는 끄덕였지만, 막상 실천으로 이끌어 들이는 데에는 실패했다.

결과적으로 동기부여에 실패했다.

 

 

이어진 고민은, 과연 유닛 테스트의 장점이라고 주장해야, 테스트 검증 개발 (TDD is dead - http://likelink.co.kr/29242 - 이후, 나는 생각을 굳게 굳혔다. Test Verify Development. 테스트를 통해 검증을 하며 이뤄지는 개발을 말한다) 동조 있게 만들 있을지 였다.

 

과정에서 유닛 테스트 시스템 테스트 코드에 대해 여러 가지 대화를 나누곤 했다.

과정에서, 그리고 내가 직접 겪었던 테스트 코드의 가장 장점은, 바로 작업자의 의도를 테스트로 강제한다는 점이다.

 

건즈2 팀에서 당시, 테스트가 깨지는 것은 build 깨지는 것으로 간주됐다. 왜냐하면 테스트 프로젝트는 프로젝트와 대응되어 함께 build 되었으며, post build 이벤트로 테스트가 수행되는 것이 프로세스였는데, 과정에 strict 검사가 많으면 많을 수록, 새로 작성한 코드나 수정된 코드가 기존 작업자의 의도를 벗어난다는 것을 있었다.

 

그렇다. 유닛 테스트를 통해, 동작하는 코드만으로 부족한 작업자의 의도를 전달하고, 의도가 지켜질 있었다.

 

이야기를 해보면, 유닛 테스트를 프로젝트에 밀접해 적용해온 팀들의 개발자 분들은 비슷한 의견을 내비치셨다.

 

여기서 중요한 점이 있다.

 

바로 자신의 코드가, 자신이 의도한 대로 동작하는지를 먼저 확인해준다는 점이다.

 

나는 DHH 위에서 언급한 TDD is dead라는 글을 쓰기 전에도 이미, TDD 하지 않고 있었다. Post Test Development 해왔다고 있다.

 

그렇게 해오다 보니, 테스트를 작성하는 과정에서 내가 작성한 코드가 의도대로 동작하는지 확인하는 과정을, 그리고 예외 상황에 대한 고민을 테스트 작성하는 과정에서 진행했다.

 

물론 과정이 너무 늦어, 설계를 변경해야 되면 어떻게 할거냐는 질문을 받기도 했는데, 사실 설계가 테스트를 통과하지 못해 무너지게끔 구성되어 있다면, 유연하지 못한 코드를 작성한 거라고 봐도 무방하다고 생각한다.

 

사실 아무리 commit message 작성해도, 문서를 작성해도, 주석을 달아놓아도, build 깨지는 것만큼 강한 메시지는 없다.

 

그것도 논리적 모호함이 가장 적은 언어의 문법에 맞춰 작성된 코드라면 나위 없이 명확하다.

 

그래서 우리는 유닛 테스트를, 시스템 테스트를 진행 해야만 한다.


Posted by 엘키 엘키

댓글을 달아 주세요

2000년대 중후반은 모두가 유닛 테스트에 미쳤다. 아니 TDD에 미쳤다.

Test Driven Development에 대한 서적이 넘쳐났으며, 모두가 TDD를 통해 구원 받을거라는 희망찬 상상에 들떠 있었다.


이 붐을 주도했던 개발자중 한명인 DHH (rails를 만든 이)도 이 흐름에 동참했었다. 

그를 비롯한 많은 이의 주장은 테스트 우선 신앙 (Test first fundamentalism)라 불릴 만큼 테스트를 바탕으로 코드를 작성하면 그 퀄리티가 비약적으로 상승 할 것이라는 의견이었다.



여지껏 내가 해온 테스트는 다음과 같았다.


독립적으로 동작할 수 있는 클래스에 대한 유닛테스트.

- 화이트 박스 테스트로써의 유닛 테스트. (나는 크게 선호하진 않았지만, 가끔 진행했고 유닛테스트를 실천한 초반에 특히 많이 진행했다.)

- 블랙박스 테스트로써의 유닛 테스트. (블랙박스 테스트를 난 매우 선호했는데, 외부에서 사용하는 메소드야 말로 기대치대로 동작하는지 검증되어야 한다고 믿고 있고, 그 믿음에 대해선 변함이 없다.)


외부 프로세스 내지는, 외부 입력을 시뮬레이션 해서 진행하는 컴포넌트 테스트

- input이 패킷이 주가 되는 서버 프로그램의 경우에는, 시뮬레이터 내지는 테스트 클라이언트라 불리우는 어플리케이션을 통한 테스트.


외부 입력을 통한 부하 테스트

- 프로파일링을 겸한, 임계치 측정 및 검증.

- 부하 발생시의 안정성에 대한 검증.


위 테스트중 유닛테스트는 일일 빌드를 통해 검증

컴포넌트 테스트는 업무시간 도중에.

부하테스트는 퇴근하고 난 이후부터 익일까지.


이런식으로 시간을 나누어 관리했다.


헌데 이렇다보니, 컨텐츠 개발하고 버그에 쫓기고 하다보면 막상 테스트를 들여다보고 개선하고, 테스트 코드를 추가하는 일이 만만치 않았다.

당연히 개발 후 테스트 코드 추가보다 더 오래 걸리는, 테스트를 추가하며 기능을 검증하는 일. 즉 테스트 주도 개발과는 거리가 멀게 개발해오고 있었고, 심적으로 매우 불편했다.

꼭 안생겨도 될 버그를, 시간을 조금만 더 쓰면 커버리지를 갖출 수 있는 상황을, 테스트 주도 개발을 외면하면서 맞이한게 아닐까 하는 생각이었다.



이런 생각을 이사님과 토의한적이 있었고, 이사님은 비용이 많이 드는 테스트에 대한 부정적인 의견을 피력하셨다.


"테스트를 작성하기 위한 비용이 너무 크다면, 테스트 코드를 작성하는 것마저 낭비라고 생각한다."


테스트 코드가 주는 이득을 많이 체감했던지라 나는 당시 크게 공감하진 못했다. 특히나 이 말을 하신 이사님은 테스트 코드 추가를 위해 많은 비용을 감내하시고, 여러 객체의 mocking과 단위 테스트, 시뮬레이트 코드를 위해 시간을 많이 쏟으신 분이셔서 더더욱 놀랐었다.


헌데 DHH의 고백을 읽고나서 다시금 떠올려본 이사님의 말은 나에게 큰 공감을 가져다 주었다.


가장 크게 와닿은 단락은 아래와 같다.

  • 두번째 단계는, unit 부터 system 사이의 테스팅 스펙트럼의 균형을 잡는 것이다.


그렇다! TDD는 유닛 테스트의 중요성만을 지나치게 강조해왔다.

유닛테스트를 통해 해당 클래스의 단독 동작은 보장되지만, 여러개의 클래스가 mocking 없이 묶였을 때의, 다양한 입력과 다양한 상태(state)에서의 출력(동작)은 보장하지 않는다.


실제로 이 부분을 커버하기 위해 나는 컴포넌트 테스트라 불리우는 (시스템 테스트라는 용어가 있는지 이제 알았다. 나도 앞으로 이렇게 써야겠다.) 시스템 테스트를 해오긴했으나, 유닛 테스트를 위한 시간 투자를 덜한다는 찜찜한 마음은 버릴 수 없었다.


하지만 이제 편해졌다.

너무나 당연한 얘기지만 시간은 돈이다. 테스트를 작성하기 위한 시간도 돈이고, 테스트를 유지하기 위한 비용도 돈이다. mocking을 위해, 혼자 일때만 잘 동작할지도 모르는 녀석을 위한 시간낭비가 될 수도 있는 유닛 테스트를 위해 강박을 가질 필요까진 없다.


물론 DHH의 이야기도 테스트의 중요성을, 매우 강조한다. 하지만 테스트 "주도" 개발은 하지 않고 있다는 것을 고백했다.

테스트 "주도" 개발이 얼마나 느리고, 비효율적이며, 그 성과가 미약했음을 고백한 것이라고 볼 수 있다.


이런 얘기가 다른 사람도 아닌 DHH에게서 나온 것은 너무나도 반갑다.


테스트 코드나 테스트를 줄이자는 얘기가 아니라는 것은 다들 알 것이다.

유닛 테스트와 시스템 테스트간의 밸런스를 맞추고, 테스트에 대한 투자 대비 효율에 대해 지금보다 심도 있게 고민해보자.

그리고 TDD에선 자유로워 지자!



TDD는 죽었다 - Rails를 만든 DHH의 글

http://yisangwook.tumblr.com/post/83725422949/tdd-is-dead-long-live-testing


TDD is dead. Long live testing. (DHH) — likelink

http://likelink.co.kr/29242

Posted by 엘키 엘키
 TAG TDD

댓글을 달아 주세요



사실 저는 테스트를 별로 좋아하지 않습니다.
 
테스터 분들이 보시면 기분나빠하실지도 모르지만, 개발보다 지루한 작업이기 때문이죠.
 
하지만 테스트는 언젠가 해야하고, 프로그램의 품질에 지대한 영향을 끼칩니다.
 
프로그래머는 모든 상황을 생각할 수 없습니다. 현재의 코드가 미칠 여파를 모두 생각해내는건 사실상 불가능하죠.
 
프로그래머의 논리적 빈틈은 테스트를 통해서 해결해야합니다.
 
그런 코드의 빈틈을 테스터에게만 맡길 수 있을까요?
 
그 프로그램을 작성한 사람보다 빈틈을 더 잘 찾을 수 있을까요?

프로그래머가 하는 테스트가 꼼꼼하다면 프로그램이 공개 되고 나서 발생할 문제를 상당수 방지 하거나 해결 할 수 있습니다.
 
테스트 주도 개발은 기본적으로 리팩토링을 기반으로 이루어집니다.
 
테스트를 통해 개발을 하며, 리팩토링을 통해 같은 기능을 하지만 좀 더 좋은 코드를 자연스레 갖춰나갈 수 있게 됩니다.
 
개발자 선에서 이루어지는 테스트 도중 더 좋은 아이디어를 떠올릴 수도 있고, 빈틈 하나 하나를 채워가며 높이는 완성도는 프로그램의 가치를 높여줄 것이라고 확신합니다.

Posted by 엘키 엘키

댓글을 달아 주세요

이전버튼 1 이전버튼

블로그 이미지
Software Engineer
엘키

공지사항

Yesterday31
Today29
Total1,605,483

달력

 « |  » 2020.8
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31          

글 보관함