추억은 방울방울!!!

 

2015년이 반이나 지나갔습니다. 정말 시간이 총알같이 지나간다는 진부한 이야기밖에 할 수가 없지만, 진심 총알보다 빠르게 지나가내요. 연초에 세운 계획은 하나라도 이루셨나요? 오히려 무슨 계획을 세웠는지 기억이 나질 않고 있습니다.

 

일찍 찾아온 무더위와 예년과 다른 가뭄 그리고 메르스라는 전염병까지 올 해 초여름은 유난히 힘겹게 지나가고 있는 듯 합니다. 그래도 또 이 시간들은 결국 지나가겠죠?

 

때로 라디오나 TV를 보면 몇 년 전의 음악 순위라든가 그 당시 인기 있었던 드라마나 영화를 이야기하며 추억을 되새길 수 있게 해주는데요, 오늘 저희는 2010(5년 전)에 출간 되었던 도서로 돌아가 추억을 되새겨 볼까 합니다. (되새겨질까 모르겠네요^^)

 

20106월 지앤선이 사이텍미디어로부터 법인을 당당히 분리하고 6개월이 지난 시점에 출간된 도서는 바로바로 아이폰 쿨 프로젝트뻔뻔하게 배우는 임베디드 리눅스입니다.



이 책들을 보니까 그 당시의 기억도 떠오르고, 특히나 뻔뻔(FunFun)강사 유명환 님의 캐리커처를 이용한 표지는 당시로서는 저희도 도전에 가까웠는데요, 다시 보니 추억이 새록새록~

 

2010 6, 여러분은 어떤 여름을 보내고 계셨나요??? 어떤 책을 읽고 어떤 공부를 하고 계셨나요???

 

 

설정

트랙백

댓글


 



번역가 : 조인석


현재 중공업 필드에서 원격 플랜트의 주기기 모니터링 및 고장 예측 관련 업무를 수행하고 있다. 인공지능, 머신러닝 기반의 다양한 알고리즘과 인 메모리 기반의 Spark와 같은 빅 데이터 플랫폼 기술에 관심이 많다.

 

원문링크


역자주 : 본 글은 Martin Fowler가 회의록 형태로 작성한 글로써, 세 화자가 나눈 대화를 1인칭 관점에서 작성한 것을, 독자 여러분의 이해와 번역 분량 축소를 위해 대화 형태로 변경하여 번역 하였습니다.

 

 

TDD는 죽었는가?

 

본 글은 Martin Fowler, Kent Beck, David Heinemeier Hansson과 함께 Test-Driven Development (TDD) TDD  소프트웨어 설계에  미치는 영향에 관하여 나눈 대화입니다.

 


어디서부터 시작되었나


우리가 서로의 관점과 경험을 이해하기 위해 대화를 시작하게 된 것은 도발적인 발언과 블로그 포스트 때문이었습니다.

 

본 대화는 David Rails 커뮤니티에 TDD Unit Testing에 대한 언짢은 감정을 드러낸 David’s RailsConf keynote 로 인해 시작되었습니다. 그는 얼마 후에 몇 개의 블로그 포스트로 이어서 그의 견해를 정리했는데, 그 중 첫 번째 포스트가 바로 “TDD 죽었다(TDD is dead)” 입니다.

 

며칠 후, 저는 후속 포스트에 대한 오탈자 내역을 보냈고, 그는 그의 발언과 블로그 포스트에 대해 내가 어떤 생각을 가지고 있는지 알고 싶다고 말하였습니다. 그 후 우리는 Skype를 통해 한 시간 동안 즐겁고 사려 깊은 토론을 하였습니다. David Kent와도 비슷한 토론을 하였고, Kent는 우리 세 명이 함께 토론을 하고 대화 내용을 공개하자고 제안하였습니다. David는 그 생각을 트위터에 올렸고, 많은 사람들이 긍정적인 반응을 보였습니다.

 

우리는 단지 30분씩 6번 정도의 가벼운 대화가 오고 갈 것이라고 생각했었지, 이 시리즈에 대해 별 다른 계획을 하지 않았습니다. 우리는 그저 서로의 경험과 관점에 대해 배우기를 원했기 때문에 이번 일을 시작하였습니다 - 실은 많은 사람들이 우리를 봐주기를 바라는 자아도취에 빠진 사람들 같았죠. 우리는 초반 에피소드에서는 질문을 거의 받지 않았습니다만, 마지막 에피소드에서는 몇 개의 질문에 답변을 주었습니다. 우리는 우리가 이 토론을 진행하는 동안 블로그와 트위터를 통해서도 토론이 지속 되는 것을 즐겼습니다.


비디오 셋업과 행아웃 시간대를 조정해 준 ThoughtWorks Wesley Clock에게 감사의 말씀을 전합니다. 저는 각 에피소드가 끝날 때 마다 토론 내용을 그저 지켜보기 보다는 읽혀지기를 바라는 마음에 회의록을 작성하였습니다.

 

1: TDD와 확신

9 May 2014 / video / audio

우리는 TDD의 흐름에 대한 가지각색의 경험들과 사람들이 TDD와 자가-테스팅 코드를 종종 혼동하는 점에 대해 이야기 하였습니다.

 

회의록

David TDD와 단위테스팅에 대한 3 가지 주요 이슈를 띄우면서 토론을 시작하였습니다: 1) TDD와 단위테스팅의 정의에 대한 혼란, 2) TDD 구조를 준수하기 위해 사용한 mock객체들로 인한 테스트로 인한 손실, 그리고 3) TDD의 붉은색/초록색/리팩토링 사이클이 그에게는 무용지물이라는 것입니다. 저는 이해를 돕기 위해 TDD 등의 기원이 뭔지 아는 게 좋겠다고 의견을 냈는데, 이는 역사를 아는 것이 유용하기 때문이었습니다. 이에 Kent TDD의 기원에 대해 설명해주었습니다. 그는 스몰톡에서 여러 테스트 방식을 실험하기 시작했고 자기 성격에 TDD가 잘 맞았다고 합니다.

 

Martin : 우리가 C3에서 처음 함께 일하기 시작한 때가 생각나는 군요. 우리는 TDD를 사용하지는 않았지만, 각 프로그래밍 에피소드는 코드와 테스트가 함께 제공되었다고 장담합니다.

 

Kent : 프로그래머들은 그들이 작성한 코드가 잘 동작하는 것에 확신을 가져야 마땅하며, TDD가 그렇게 만드는 방법 중 하나(유일하지는 않은)이죠.

 

David : 저는 프로그래머의 행복을 위한 Ruby의 설계 목적을 좋아하고, 테스트 코드를 가지기 전까지는 일이 끝나지 않았다는 개념에는 동의합니다. - 하지만 TDD와 같은 방식으로 테스트 코드를 갖는 것을 선호하지는 않습니다. 사람들은 서로 사고방식이 달라서 서로 다른 기술과 언어를 좋아한다고 생각하고 있으며, TDD를 자가-테스팅 코드에서 얻을 수 있는 확신과 TDD라는 개념이 합쳐지는 것을 좋아하지 않습니다.

 

Kent : 최근 페이스북의 해커톤에서 절반은 TDD가 가능하였으나, 절반은 그렇지 않았었죠. TDD가 가능한 코드에서는 즐겁게 작업을 하고 있다는 것을 느꼈지만, 다른 절반에서는 그렇지 못 하다는 것을 느꼈었습니다. 하지만 non-TDD 파트에서도 여전히 저는 재발(regression) 테스트와 짧은 피드백 루프를 사용하였습니다. 저는 두 스타일을 함께 쓰는 것에 대해 별 다른 문제가 없었으며, 마치 클래식 음악과 재즈 음악을 함께 연주하는 것과 같았죠. TDD는 제가 학창시절에 수학을 어떻게 배웠는지 기억하게 해주었습니다 - 항상 예제가 필요했죠.

 

David : TDD가 잘 적용하여 개발을 한적도 있지만, 대부분의 저의 작업은 TDD가 잘 적용되지 않았습니다 - 제 질문은 “TDD를 적용함으로써 생기는 희생을 기꺼이 감수하는 이유가 무엇인가?”이죠. 많은 사람들이, 특히 무거운 mock객체 생성(mocking)으로 인해 나쁜 트레이드 오프를 합니다.

 

Kent : 다음 질문에 대한 트레이드오프에 대해 얘기 해보죠: 테스트가 가능한 중간 결과를 만들어내는 것이 가치가 있는 가?  컴파일러를 예를 들어보죠, 중간 구문분석-트리가 훌륭한 테스트 지점을 만들어주고, 더 좋은 설계입니다. 하지만 mock 객체에 대한 David의 질문에는 이렇게 대답하고 싶군요. 저는 mock객체를 거의 사용하지 않으며, 테스트는 리팩토링을 더 쉽게 해주는 반면, 목 객체는 종종 리팩토링을 더 어렵게 한다는 점이 좀 걱정 됩니다.

 

Martin : 저는 서로 다른 것이 뒤 섞이는 부분에서 전문 용어로 두 가지 문제점이 있다고 생각합니다.: 1) 첫째, TDD에 대한 David의 비평은 Mock객체를 사용해야 할 적합한 케이스가 아닌데도, 모든 TDD에 무거운 Mock객체를 써야만 한다는 가정을 하고 있습니다.; 2) 둘째, 자가-테스팅 코드와 TDD에는 차이점이 있습니다. TDD는 자가-테스팅 코드를 얻기 위한 한 가지 방법입니다.

 

David : 저의 TDD에 대한 반응은 무거운 mock 객체 스타일의 TDD를 도덕적으로 해야 한다고 말하는 사람들을 보았기 때문이며, 독립적인 단위 테스트를 가능하게 하기 위하여 비효율적으로 설계한 수 많은 코드들을 봤기 때문이죠.


Martin : 미리 정해놓은 시간에 따라 본 세션을 종료하겠습니다. 다음 세션에서는 어떻게 TDD가 손실을 발생시키는지, 진짜 손실인지, 어떻게 손실 유무를 판단 할 수 있는 지에 대해 논의 하겠습니다.

더 읽을 거리

·  이번 논의를 시작하게 된 David의 대화 (RailsConf talk).

·  David의 에세이 중 TDD는 죽었다(TDD is Dead) 와 테스트-유도 설계 손실(test-induced design damage).

·  Martin Flower가 얘기하는 자가-테스팅 코드(self-testing code)TDD의 차이점

·  Martin Flower의 단위테스트의 정의(defining unit tests).

 

2: 테스트로 인한 설계 손실

16 May 2014 / video / audio

David TDD를 사용하는 것이 hexagonal rails 와 같은 것에 도달하게 한다는 것을 느꼈습니다. hexagonal rails라 함은 지나친 간접 참조(indirection)로 인한 복잡성 때문에 테스트로 인한 설계 손실이 발생하는 경우를 말합니다. Kent는 이러한 현상이 TDD로 인한 것이라기 보다는 설계 결정에 대한 품질에 의한 것이라고 생각합니다.

 

본 대화를 보기 전에 David가 염려하는 설계 손실에 대한 예제(the gist David prepared)를 먼저 보십시오. 무척 그리운 Jim Weirich* hexagonal architecture 으로의 시도에 대한 동영상(explores this approach to a hexagonal architecture)도 보는 것을 권장합니다.

* 역자주) Jim Weirich 2014 2월에 타계하신 분이어서 무척 그립다(much-missed)라는 표현이 쓰였습니다.

 

회의록

Martin : , 이 질문으로 토론을 시작해보죠. TDD가 설계 손실을 발생 시킬 수 있나요? 손실이 실제로 손실로 이어 지나요? 어떻게 설계가 손실을 입었다고 판단할 수 있나요?

 

David : 저는 이 코드 예제(the gist he posted earlier)를 통해 답을 드릴 수 있겠네요. 사람들이 수 많은 mock객체를 사용하는 TDD를 쓰기 때문에 도달하게 되는 아키텍처를 예로 들어 보겠습니다. 애플리케이션의 각 레이어는 엄격하게 분리되어 있습니다. 가령, 컨트롤러는 실제 모델, 데이터베이스, 혹은 요청/응답 사이클을 사용 없이 테스트 할 수 있습니다. 그리 구체적인 예제를 보여주지는 않았습니다만, 단독 테스트를 쉽게 만들기 위해 너무나도 많은 불필요한 간접참조와 지나친 복잡도가 필요합니다.

 

Kent테스트-유도 손실을 TDD 탓으로 돌리는 것은 마치 자동차가 옳지 않은 장소에 주차되어 있다고 해서 차를 비난 하는 것과 같습니다. David가 보여준 설계는 TDD 때문이 아니었죠, 실제 이슈는 이러한 간접참조가 경우에 따라서 모두 좋은 트릭이 될 수 있다는 것이며, 우리는 이것이 가치가 있는지 없는지에 대해 이해할 필요가 있습니다.

 

David : 그 부분에 동의하지 않습니다. TDD (혹은 자동차)에 한번 올라 타면, 매번 기괴하고도 흉물스러운 테스트를 하게끔 명확한 길로 인도하고 있어요.

 

Kent : 그 부분은 설계 결정 이죠. TDD는 설계에 점진적인 영향을 줍니다, 사람들은 그들의 테스트 커버리지율이 얼마나 되는지에 대한 사항에 대해서는 호불호가 갈리죠David에게 묻겠습니다. gist 에서 보여준 어떠한 코드들이 시스템 구조를 어렵게 만드나요? (“누군가 신경 쓰는 무언가가 눈 앞에 있다면- 그때가 바로 문제가 되는 설계를 바꾸고 싶은 때입니다.)

 

David : 코드의 크기와 코드 변경 용이성간에는 명확한 상관관계가 있습니다. 이러한 모든 간접참조는 반드시 동기화가 되어야 하며, 10 라인의 코드가 60 라인의 코드보다 이해하기도 쉽고, 변경하기도 쉽죠. 간접참조의 모든 레이어는 높은 비용을 지불해야 합니다. TDD의 붉은색/초록색/리팩토링 흐름은 무척 중독성이 강하고 (Kent는 세상에서 가장 가난한 마약 중개업자임을 밝혔습니다.), 이 중독은 사람들이 좋지 못한 결정을 하게 만듭니다.

 

Martin : 저는 그 의견에 반대합니다. 이러한 상황 (이번 사례는 Rails) TDD 때문에 발생한 것이 아니라 hexagonal architecture의 핵심인 환경으로부터의 고립에 대한 바람에 의한 것이죠.

 

David : 사람들이 고립을 원하는 이유가 바로 TDD입니다. 고립에 대한 다양한 논쟁에 대해 들어왔고, 그 중에 테스팅을 위한 고립만이 의미가 있다는 것이죠. rails 애플리케이션을 커맨드-라인 애플리케이션으로 변경하는 건 터무니 없는 일이라고 생각하며, 비슷한 사례로 인-메모리 저장소와 웹 서비스 호출은 각각의 운영상 특징이 달라서 서로 교환할 수 없는 것과 같은 이치입니다. 이런 교환 가능성에 대한 꿈이 진짜 목적은 아닙니다. - 진짜 목적은 단독 테스팅이죠.

 

Kent : -메모리와 웹 서비스를 같은 걸로 대할 수 없다는 것에 동의합니다. (여러분은 아마도 분리했다고 생각 할 수 있지만, 정말로, 정말로 아닙니다. ) 실패 케이스가 서로 다르기 때문이죠. 요소들간의 경계는 무너지게 마련입니다. 질문은요소들간의 디커플링의 정도를 알아내는 데 얼마나 많은 시간을 할애하고 싶은가?”입니다10 라인 코드 내부의 응집도와 60 라인 코드 내부의 응집도도 서로 다르죠.

 

David : 그 의견에 동의합니다만, 응집도와 결합력은 언제나 대립됩니다. 좋은 응집도를 얻기 위한 결합력 상승의 대가는 대부분 가치가 있죠.

 

Kent : 외부 의존성을 제거하기 위해 다른 방법도 존재하며, 컴파일러와 같이 중간 결과를 활용 할 수도 있습니다. 설계 통찰이 필요한 간접참조는 테스트 하기가 어렵습니다만, 대부분 테스트 가능성을 높여주는 더 나은 설계를 하게 만드는 통찰을 찾는 것이 유용합니다.

 

David : 테스팅이 더 나은 설계를 만들어낼 수 있다는 것에는 동의합니다만, 저의 경험상 그렇지 못 한 경우도 잦았으며, 테스트 하기에는 좋지 않은 설계였습니다.

 

Kent : David 는 스스로에 대한 확신이 부족하군요, 오늘은 통찰을 볼 수 없을지도 모르겠습니다. 그러는 동안에도 앞으로 나아가기 위해 노력해야만 하고요. 하지만 당신의 낙관적인 시각 덕분에 우연히 나마 그러한 통찰들을 찾게 될 것입니다.

 

David : 저는 이런 상황을신앙적인 TDD”라 생각합니다 - 이러한 감정을 종종 느꼈습니다만, 존재하지 않는 이상적인 해결책을 찾지 못 할 때 빠지는 우울한 루프 안에 꼼짝없이 갇혀버렸었죠.

 

Kent : David TDD에 관해서 얘기하고 있지 않고 일반적인 소프트웨어 설계에 관하여 이야기하고 있군요, 당신의 문제는 TDD 때문이 아니라 어떻게 피드백을 받을 수 있느냐에 관한 문제라고 명확하게 말할 수 있습니다. 소프트웨어 설계에 관해 생각 해 봅시다. 좋은 설계 통찰로 인하여 얻을 수 있는 이득은 무척이나 크죠. 이러한 통찰을 얻는 다는 것은 당신의 작업 흐름에 관한 것이 아니라, 언제 일하고 언제 쉬고, 다른 장소로부터의 영향도를 파악하고 다른 사람들과 협업하는 방식에 대해 알아가는 것과 같습니다.

 

우리는 다음 번 주제를 통해 프로그래밍 중에 어떻게 피드백을 찾아낼 수 있는 지에 관한 트레이드오프에 관해 이야기 해보자고 말하면서 이번 세션을 마무리 하였습니다.

 

더 읽을 거리

·  David의 염려하는 설계 손실에 대한 예제(David's gist). gist Jim Weirich에 의한 대화(a talk by Jim Weirich)를 통해 주어진 hexagonal Rails 아키텍처의 탐구에 기초를 두고 있음.

·  David 의 블로그 포스트 중 테스트-유도 설계 손실의 문제점에 대한 소개(introducing the problem of test-induced design damage).

·  "hexagonal architecture" 라는 용어를 만든 Alistair Cockburn의 글(originally coined by Alistair Cockburn), “포트와 어댑터로도 소수 알려져 있음.

·  hexagonal Rails 아키텍처의 출현과 이를 사용하는데 있어서의 트레이드오프에 대한 Martin Flower의 글 (the nature of a hexagonal Rails architecture and trade-offs around using it).

 

3: 피드백과 QA

20 May 2014 / video / audio

우리는 프로그램을 하는 동안 피드백을 받고 QA로써 개발자에게 피드백을 주는 다양한 방법에 대해 토론하였습니다.

 

회의록

Kent : TDD를 수반하는 의사결정은 트레이드오프에 관한 것입니다.  “어떤 이상적인 세계에서는 우리의 프로그래밍 결정에 대하여 즉각적이고 틀림없는 피드백을 받기도 합니다.” … “내가 만든 모든 코드는 배포할 준비가 되었다면, 그 즉시 배포합니다.” 하지만 이러한 이상적인 상황은 현재 불가능하기 때문에, 질문은 바로이런 이상에서부터 얼마나 멀리 떨어져 있는가?” 라는 것이죠. 트레이드오프에 대한 여러 가지 제약 사항들을 나열해 보겠습니다.

·  빈번도: 얼마나 빨리 피드백을 받고 싶어 하나?

·  충실도: 얼마나 정확한 붉은색/초록색 신호를 원하나?

·  오버헤드: 얼마나 지불할 준비가 되어 있나?

·  수명: 이 소프트웨어의 라이프사이클은 어떤가? 시간과의 개연성이 얼마나 되는 가?

4개가 우리가 비교해 볼 필요가 있다고 생각하는 제약사항들입니다. 우리는 서로 동의하기 위해 이 행아웃에 참여하고 있는 것이 아닙니다 - 제 개인적인 목적은 단지 나의 아이디어를 건설적인 방식에서 멀찌감치 몰아내기 위해 준비 되어진 사람들에게 나의 의견을 명확하게 전달함으로써 서로의 트레이오프들에 대해 이해하는 것입니다.

 

Martin : 우리가 피드백을 받기 위해 살펴봐야 할 3가지에 대해 강조하고 싶습니다.

·  소프트웨어가 사용자에게 유용한 무언가를 하고 있나? 급여 계산과 같은 경우에는 테스트가 도움이 되지만, html 렌더링과 같은 경우에는 도움이 되지 않습니다.

·   내가 무언가를 망가뜨렸나? “이 부분에서 만큼은 자가-테스팅 코드는 마치 구세주이죠.” 저는 적어도 한번쯤은 모든 테스트가 실패하는 것을 보고 싶어요.

·  나의 코드-기반이 건강한가? 건강하다면 저는 빠르게 빌드를 계속 할 수 있습니다. 이 부분은 당신의 코드를 누가 인수 할지 명확하지 않을 때 더욱 까다로울 수 있습니다.

 

David : QA를 쓸모 없게 만드는데 TDD가 한 몫 했다는 주제를 제시하고 싶습니다. 많은 회사가 TDD를 택하고 QA을 없앴고, Basecamp 2년 전까지만 하더라도 QA가 없었습니다. 저는 TDD가 프로그래머들이나는 QA가 없다는 것에 대해 무척 자랑스러워라고 생각하게 만들었다고 생각하고 있었습니다. 오래된 모델이 제 기능을 동작하고 있지 못하고 있는 동안에, 시계 추는 너무나도 멀리 흔들리고 있었죠: “저는 당신이 물리적인 품질에 관한 어떤 작업도 수행 할 수 없다고 생각하며, 당신이 아닌 누군가가 테스트 하지 않는 한, 훌륭한 소프트웨어를 만들 수 없을 것이라고 생각합니다.” 저는 QA가 팀에 합류하는 것이 얼마나 강력한 힘을 발휘하는 지 보았기 때문에, 이러한 상황이 실망스러웠습니다.

 

David : 다른 이슈는 트레이드오프에 대해서 이해하려면 비용에 대해 반드시 이해해야 하고, TDD에 대한 모든 이야기는 TDD로 인한 이득에 관한 이야기이라는 것이죠. 이 비용을 고려 하지 않는 것 때문에, 사람들은 테스트로 인한 손실이 있다는 것을 충분히 이해하지 못하는 겁니다. 신뢰성에 대한 비용을 생각해봅시다: 99%에서 99.999%로 가는 것은 99%에 머무르는 것보다 기하급수적으로 많은 비용을 필요로 합니다. 높은 신뢰성은 우주 왕복선이나 레이스의 선두주자들에게나 중요한 이야기지, 실험적인 웹 사이트에게는 필요가 없습니다. 운영환경에서 사용하는 코드는 테스트 코드 없이 작성하지 않는 다는 규칙과 시스템의 중요성과는 상관관계가 없다고 봐야 합니다. (역자주: 시스템이 중요하지 않다고 해서 운영환경의 소스 코드를 테스트 코드 없이 작동해도 된다라는 건 옳지 않다는 뜻이네요.)

 

Kent : QA 에 관한 이슈로 돌아가보죠, QA와의 오래된 관계는 제대로 동작하지 않는 다고 생각합니다. 제 사무실의 페이스북에서 들고 나온 포스터에는페이스북에서는 어떠한 것도 다른 누간가의 문제점이 될 수 없다.”라고 말하고 있으며, 페이스북이 회사의 규모에 비해서 이 말을 잘 지키고 있다고 느끼고 있습니다. 페이스북은 최근까지도 QA가 없었으며 프로그래머는 QA에 대한 책임까지 가지고 있었습니다.  “그럼 무엇과 비교하실 건가요?” 라고 묻는 다면, 효과적인 QA를 가지는 것이 QA가 없는 것 보다는 낫지만, 과거의 제대로 동작하지 않는 관계라면 QA가 없는 것이 낫다고 생각합니다.

 

Martin : ThoughtWorks에서 일할 때 항상 QA가 있었습니다. 저도 역시 90년대와 비교해보면 잘 동작하지 않던 대립적인 관계도 사라졌고, 수작업으로 진행하던 스크립트 기반 테스트도 사라졌다는 것을 느끼고 있습니다. 그리고 스타트업들이 QA 없이 운영할 수 있는 건 그들 마음 이죠.

 

David : 초기 스피드를 위하여 심사숙고한 QA와의 트레이드오프에 대해서는 동의합니다만, 어떤 경우에는 프로그래머의 테스트가 지나칠 정도도 있어 왔으며, 실험적인 테스팅에서 어떠한 가치도 찾지 못 하기도 합니다. 만약 개발자들이 QA 없이도 충분히 높은 품질의 소프트웨어를 만들 수 있다면, 당신의 테스트들은 모두 초록색이겠지만, 운영환경에서의 사용자들은 당신이 예상하지 않았던 행동을 하게 마련이라는 거죠. 무엇보다 나쁜 것은 개발자들이 고객 서비스의 일부분이 아니라는 점입니다. 많은 프로그래머들은 단조롭고 지루하다는 이유로 전화 응대를 하고 싶어 하지 않습니다만, 그 또한 피드백 루프죠. 초록색 테스트를 통과한 코드는 당신이 원하는 범위 내에서는 안정기에 접어들었다고 할 수도 있습니다.

 

Kent : 이 제약사항에 관하여 다시 생각하기 위해 초록색 바 안에 빨간색 픽셀 몇 개를 심어야만 한다고 생각합니다. “전화 응대는 당신이 작성하지 않은 테스트를 가르쳐주기 위한 피드백 루프입니다.” 페이스북 프로그래머들은 전화응대를 해야만 하며, 모두들 그것에 대해 불평하고 있지만, 어느 누구도 전화응대를 피할 수는 없습니다. 당신이 더 이상 실수를 저지르지 않는다고 생각하는 그 순간, 그 것이 바로 실수이며, 당신은 성장 할 수 없습니다. 결국세상은 당신이 아무것도 망치지 않은 척 하게 내버려두지 않을 것입니다.” 저는 이른 새벽 2시에 받은 전화 한 통을 통해 꽤 값진 경험을 하였습니다.

 

Martin : 우리가 테스팅 비용에 관하여 더 이상 얘기하지 않는 것을 확인하고, 이번 세션을 마무리하였고, 다음 기회에 다시 한번 살펴 보자고 제안하였습니다. 또한 같은 주제로 Mike Bland가 제 사이트에 올린 을 보는 것도 좋을 것이라고 언급하였습니다.

 

4: 테스팅 비용

27 May 2014 / video / audio

우리는 테스팅과 TDD에 대한 덜 긍정적인 부분에 대해 토론하였습니다: 당신은 테스팅을 너무 지치게 하고 있지 않은가, 그리고 기능적인 코드보다 테스트에 더 많은 가치를 부여 하는 것이 팀에 문제가 되고 있는가?

 

회의록

David : 트레이드오프에 대해서 얘기하기 위해서는, 결점에 대해서 명확하게 이해하고 있어야만 합니다. 만약 결점이 없다면 트레이드오프도 없기 때문이죠. 저는 TDD가 어떤 것을 강제로 하라고 하지는 않지만, 명확한 방향으로 부추기고는 있습니다. 지나친 테스팅을 첫 번째 이슈로 얘기해보죠. 여러분은 결함 테스트가 없는 코드를 작성하면 안 된다는 얘기를 자주 듣죠, 처음에는 괜찮아 보입니다만, 지나친 테스팅을 하게 만들기도 합니다. 가령, 운영 코드의 매 라인을 위한 4 라인짜리 테스트 코드가 있는 것과 같은 것을 말하죠. 이 말은 당신이 무언가를 변경하려고 하면, 변경할 코드가 더 많아 진다는 뜻 입니다.

 

Kent : 사람들은 테스트 코드를 작성하기 위한 비용을 지불하는 것이 아니라, 충분히 확신을 하기 위해 작성하고 있는 것입니다.

 

David : 그럼 여러분(Kent Martin)은 운영 코드의 각 라인을 작성하기 전에 매번 테스트 코드를 작성하시나요?

 

Kent : 상황에 따라 다르죠, 그리고 이 대답은 흥미로운 질문들에 대한 모든 나의 답변의 시작부분과 같다고 할 수 있습니다. JUnit을 사용하는 운영 코드는 엄격하게 테스트 코드를 먼저 작성하게 되며, 이러한 과정 속에서 모습이 들어나는 자신의 모습(역자주 : 운영코드)으로 인해 무척이나 행복해합니다 - 그렇기 때문에 저는 TDD를 사용할 때 항상 지나친 테스팅을 하게 된다고 생각하지 않습니다.

 

Herb Derby : 델타 커버리지 개념에 대해 언급하고 싶군요 - 이러한 테스트는 중복되지 않는 비율이 얼마나 되나요? 제로 델타 커버리지 테스트는 그들이 의사소통 목적과 같은 것을 제공하지 않는 한, 제거되어야만 합니다. 저는 자주 system-y 테스트를 작성하고, 구현을 하며, 리팩토링을 거치고 나면, 결국 초기 테스트는 버려지게 되고 맙니다. 많은 사람들이 테스트들을 버리는 것에 대해 흥분하지만, 그들이 당신에게 아무것도 사주지 않는다면 당신도 흥분하게 될 것이라고도 했죠. 같은 것이 여러 방식으로 테스트 된다면, 그것이 바로 결합(커플링)이며 결합 비용이 발생합니다.

 

Martin : 지나친 테스트 코드는 분명 존재합니다, ThoughtWorks는 강한 테스팅 문화를 가지고 있기 때문에, ThoughtWorks에서도 발생하죠.  적정 수준의 테스트의 양을 정의하는 건 무척 어렵습니다. 어떨 때는 지나칠 때도 있고, 어떨 때는 적을 때도 있죠. 저는 가끔 지나치게 테스트하기를 원하며, 테스트가 너무 방대하지 않는 한 그렇게 하는 것에 있어 걱정하지 않습니다. 모든 라인의 코드를 테스트 하느냐라는 포인트에 대해서는 제가 다음 질문을 드리죠: “제가 이 코드를 망치는 것이 테스트를 실패하게 만드는 건가요?” 저는 때때로 고의로 코드 라인을 주석처리 하거나 조건을 반대로 바꾸고 나서 실패할 것이 확신한 테스트를 돌려보기도 합니다. 저의 반대쪽 머리의 (Kent로부터 온) 테스트는 그저 실패할 수도 있는 것들을 테스트하는 것입니다. 라이브러리들은 (정말 불안정하지 않는 한) 잘 동작한다고 가정합니다. 제가 라이브러리를 잘 못 사용하고 있는 지와 실수의 결과가 얼마나 심각한지 묻고 싶군요.

 

Kent : 테스트 코드 라인수와 운영 코드 라인수와의 비율은 믿기 어렵습니다. 저의 기억에 남는 경험은 Christopher Glaeser가 컴파일러를 작성하는 것을 보는 것이었으며, 그는 컴파일러 코드의 각 라인을 위한 4라인의 테스트 코드를 가지고 있었습니다. 간단한 시스템은 더욱 낮은 비율을 나타내겠죠.

 

David : 코드의 한 라인을 임시 주석 처리(comment out) 한 것이 눈에 띌 정도면 테스트 커버리지율이 100%라는 것을 의미합니다. 임시 주석 처리로 인한 소스 쪼개기가 어떤 경우에 값지다고 할 수 있는 지 생각해 봅시다. Rails의 선언적 주석문은 가치 있는 테스팅을 위하여 소스를 충분히 쪼개지 않습니다. 그렇기 때문에 저는 100% 이하의 커버리지율에도 충분히 만족합니다.

 

Martin : 만약 당신이 코드를 자신 있게 변경 할 수 없다면, 당신의 테스트는 (혹은 좋은 테스트) 충분하지 못 하다는 것을 의미합니다. 지나치다는 신호는 당신이 코드를 변경할 때, 코드를 변경하는 것 보다 테스트를 변경하는 노력이 더 많이 든다고 느낄 때를 말하는 거죠. 여러분은 Goldilocks zone* 안에 들어가길 원합니다만, 당신 혹은 당신의 팀이 어떠한 실수를 하는 경향이 있는 지와 누가 문제를 일으키지 않는 지에 대해 알아가는 경험과 함께 들어갈 수 있는 거죠. 저는 제가 확신이 없을 때코드의 한 라인을 임시 주석 처리 해도 되나라는 시도를 하는 것을 좋아하며, 그 시도가 시발점이지만, 그 환경에서 더 일하다 보면 더 나은 발견을 하게 됩니다. 

* 역자주> Goldilocks zone은 태양계에서 생명체가 살기 적합한 영역을 말합니다.


David : 이러한 튜닝은 잘 모르는 팀과 함께 코드를 제어하고 더 많은 테스트가 필요로 하는 컨설팅 팀과 상대적으로 더 안정적인 운영팀에게는 서로 다른 것으로 느껴지는 군요.

 

Kent : 테스트 우선 원칙에 대해 배운 것이 좋았으며, 그건 마치 까다로운 개발을 위한 4륜자동차의 저단 기어와 비슷한 거죠.

 

David : 다음 이슈로 넘어가보죠: 많은 사람들이 코드보다 문서화가 더 중요하다고 생각하곤 합니다. 지금 제가 걱정하는 것은 사람들이 기능 코드보다 테스트를 더 중요하게 생각한다는 것이죠. 이 부분은 TDD 사이클의 리팩토링 파트가 강조하는 부분과 연결이 됩니다. 이러한 모든 것들이 코드를 리팩토링하고 깨끗하게 유지 하는 것에 충분하지도 않은 에너지를 쏟아 붓게 만듭니다.

 

Kent : 운영 코드임에도 불구하고 버려졌지만, 테스트를 계속하고 재구현한 사례가 있습니다. 저는 새로운 코드가 잘 동작하고 있다는 것을 알려주는 테스트를 무척이나 좋아합니다.

 

David : 한 가지 흥미로운 질문이 떠오르는 군요: 꽤 많은 코드를 버리고 테스트 코드를 유지한 적이 있나요? 아니면 반대 상황이 있었나요? 각 상황에 맞는 답을 주셨으면 합니다.

 

Kent : 저는 테스트 코드를 읽을 때 코드가 어떻게 동작하는 지 쉽게 이해할 수 있습니다. 둘 중에 무엇이 더 중요하다고 생각하지는 않습니다 - 가장 중요한 포인트는 테스트 코드와 기능 코드가 서로 맞지 않으면, 그 부분에 에러가 있다는 것을 더블 체크 하는 것입니다. 저도 때로는 테스트 코드가 종료를 의미하는 것이기 때문에, 팀들이 사용자를 지원하는 것 보다 테스팅 환경에 더 많은 에너지를 쓰는 좋지 않은 상황을 만들기에 David의 의견에 동의합니다. 저는 코드가 완성되었을 때의 쾌감도 즐기지만, 가장 스릴이 넘치는 부분은 새로운 기능을 추가 했을 때죠, 속임수로 보일 수도 있지만, 코드 작성이 쉬워집니다. 이 모든 것들이 클린 코드에 의한 것입니다만, 코드를 깨끗하게 유지하는 거 하고, 쾌감을 느끼는 것 하곤 차이가 있습니다.


Kent Jeff Eastman를 비유로 설명하였습니다. 지문으로 담기에는 한계가 있군요. 그는 큰 설계 단순화를 설명하기 시작했습니다. 그는 신규 테스트가 동작하게 하는 것의 가치를 설명하는 것은 쉬우나, 설계를 깨끗하게 유지하는 것의 가치를 설명하기에는 어렵다고 말하였습니다.

 

David : 사람들은 정량적인 것들에 집중하기 마련이지만, 설계 품질을 숫자로 표현 할 수 없습니다 - 해서 사람들은 테스트 속도, 테스트 커버리지율, 테스트 비율 등에 대한 것 들은 우선순위에서 밀려나는 거죠. 이러한 것들은 꿀 팁과 같죠, 우리는 이러한 것들의 싸이렌 소리에 귀 기울일 필요가 있습니다. 운영 코드보다 테스팅 환경에 더 신경 쓰게 되는 것에 대하여 생각할 필요가 있습니다. 이는 오로지 비기술적인 이해당사자들에게만 유용한 지표가 될 수 있습니다. TDD를 파는 것이 중요하곤 했지만, TDD는 모든 것을 정복했으며, 우리는 TDD의 단점에 대해 살펴 볼 필요가 있습니다.

 

Martin : 저는 TDD가 지배적인 위치에 있었다고 생각하지 않습니다. 아직도 TDD를 적용하려고 하는 곳도 많거든요.

 

더 읽을 거리

·  측정을 잘못하는 경우의 토픽을 위해서 Pat Kua의 다음 글을 읽어 보세요. an appropriate use of metrics.

·   Martin Flower의 테스트 커버리지율의 사용법과 잘못된 사용법(use and misuse of test coverage).

 

5: Q&A

4 June 2014 / video / audio

우리는 시청자들의 질문에 답변을 주었습니다: TDD의 오픈소스 예제는 무엇인가, 우리가 TDD를 사용하는 방법을 변경하게 만드는 변화가 무엇인가, TDD를 경험하지 못한 개발자에게 TDD를 잘 적용하게 하는 방법은 무엇인가. 우리는 TDD의 건제함에 대한 관점에 대해 정리하면서 마무리 하였습니다.

 

회의록

Martin : 시청자들이 올려 놓은 질문 중 일부에 답변을 드리겠습니다. David Mike Harris “TDD를 활용한 오픈소스 프로젝트는 어떤 것이 있으며, 테스트-유도 설계 손실 혹은 TDD를 잘 활용한 사례가 있는가라는 질문에 답변을 드리는 걸로 본 세션을 시작하겠습니다.

 

David : 좋은 사례를 찾기 쉽지 않으며, 이 또한 논의 해볼만한 문제입니다. 우리에게는 일반적인 상황의 좋은 애플리케이션 사례가 없습니다. 왜냐하면 오픈소스 협력자들은 대개 개인적인 애플리케이션과 오픈소스 공통 프레임워크, 라이브러리들을 대상으로 작업하기 때문입니다. 다른 관점에서 이 논의의 결론을 내자면, 어떤 것이 실제로 의견충돌이 발생하는 것 보다 더 많은 의견충돌을 만들게 하는가에 대한 답이 필요합니다. 사람들은 철학적인 원칙보다는 실제 코드를 가지고 옵니다. 우리의 코드 예제는 사람들이 실제로 작업하고 있는 것에 비해서 그다지 중요하지 않습니다. 해서 당신은 설계 손실 설명을 위해 사용한 Jim Weirich의 예제를 위한 PT자료로 사람들을 이해해야만 합니다. 좋은 Rails 코드는 책에서 보여주는 표준 테스팅 방안에서 찾아 볼 수 있습니다.

 

Martin : 실제 코드를 이해하기 위해서는 많은 노력이 필요합니다. 저도 저희 팀의 코드 기반을 파고 들어가곤 합니다만, 무척 시간이 많이 걸리며, 팀과 일하는 경우 모두 같은 수준으로 이해하지 못합니다.

 

Kent : JUnit TDD를 엄격하게 사용하는 프로젝트 예제이며 잘 동작합니다. 하지만 이 논의의 좋은 예제로 들 수는 없겠군요. 왜냐하면 JUnit TDD를 위한 최고의 방안을 명확한 인터페이스를 통해 제공하기 때문입니다. 우리는 상이한 종류의 애플리케이션에 관해 얘기 하고 있습니다. 만약, 좋은 예제를 가지고 계신 분이 계시면, 꼭 내용을 공유해주시기 바랍니다.

 

David : 우리는 프로그래밍을 과학으로 대할 수 없습니다 - 우리는 기술을 객관적으로 평가 할 수 없습니다. 가치가 없는 논의를 하고 있다는 뜻은 아닙니다. 우리는 완전한 답을 얻을 수 없으며, 이치에 맞게 만드는 작업은 여러분의 몫입니다.

 

Kent : 동의합니다. 우리는 실험을 복제할 수는 없습니다만, 과학적인 사고방식으로 개개인이 바라볼 수는 있습니다. 우리는 우리 스스로 경험에 기반하여 시도해볼 수는 있겠습니다만, 일반적인 답변을 드릴 수는 없겠군요.

 

Martin : 다음 질문으로 넘어가겠습니다. Graham Lee님이 주신 질문입니다: Kent Martin에게 묻겠습니다. 소프트웨어 작성시 TDD를 사용하지 못 하게 하는 혹은 쓸모 없게 만드는 것은 무엇일까요? David에게는 이런 질문을 드리고 싶군요. 어떤 것이 TDD가 유용하게 동작하게 할 수 있을까요?

 

Kent : 제 포스트(RIP TDD post)를 한번 보시죠. TDD는 여러 문제점들을 해결하며, 확신을 갖기 시작하게 만듭니다. 또한 TDD는 문제점들을 작은 단위로 쪼개지게 해주며, 한번에 일반적인 문제를 해결하는 것 없이 구체적인 문제점을 걸고 넘어집니다. 저는 TDD가 단지 어렵다는 이유로 포기할 생각이 없습니다.

 

Martin : 저는 TDD를 쓸모 없게 만드는 것에 대해서 이야기 하기 보다는 다른 관점에서 TDD의 적용 가능성에 대해 말씀 드리겠습니다저는 훌륭한 설계를 우연히 접하였을 때 차분한 '신속한 느긋함'을 이용하여 기계적인 방식으로 TDD를 따르고 있습니다. 근래 대부분의 저의 프로그래밍은 제 웹 사이트 툴체인이며, 조금씩 진전이 있을 때마다 훌륭한 회귀 테스트가 딸려 있죠 - 저는 TDD 적용가능성을 찾지 못하였습니다. 하지만 제가 infodeck 코드를 빌드할 때면, TDD가 효과적이었던 애플리케이션이 있었습니다. 어떤 애플리케이션에서는 TDD가 무척 잘 들어 맞지만, 아닌 경우도 있습니다. 그리고 사람들은 그들의 성격을 애플리케이션에 반영하죠.

 

David : 제 경험도 비슷합니다. 저는 TDD를 통한 테스팅이 좋았고 모든 곳에 적용하려고 노력하였습니다만, MVC 웹 애플리케이션의 많은 영역에서는 TDD가 잘 맞지 않다는 것을 서서히 깨닫게 되었습니다. 이는 TDD가 어떤 상황에 대하여 효과적이 않다고 말씀 드리는 것이 아니고, 단지 제 작업의 작은 부분에 이런 사례가 있었다는 것입니다. 하지만 TDD를 사용하지 않게 되는 것이 자기-테스트 코드를 포기 하고 싶다는 것은 아닙니다 - 이것이 항상 저에게는TDD의 가치라고 생각합니다.

 

Martin : 제가 정확하게 TDD(혹은 어떤 기술)를 받아 들이는 방법을 알려드리겠습니다. 시험해 보고, 남용한 다음에, 여러분에게 잘 들어맞는 방식에 안착하세요. 그리고 조금 더 깊이 들여다보세요. “TDD는 자가-테스팅 코드를 향한 마약의 출입구입니다.”

 

Kent : 사람들은 결국 이러한 프로세스를 수행하는 작업 흐름을 가지게 됩니다. 제가 경험한 TDD David의 경험과는 다릅니다. 제가 개발할 때 어려운 부분을 만나게 되면, 저는 그 부분을 간단하게 만드는 명확한 체계를 가진 객체에 대한 아이디어를 얻습니다. TDD는 그러한 아이디어, 시도 그리고 API의 사용 예제와 구현 방법에 대한 피드백을 신속하게 가져다 주는 메커니즘을 제공합니다. 물론, TDD가 잘 맞지 않는 경우도 있죠. 그런 경우 command-R이 피드백을 받기 위한 좋은 방법인 것을 찾았습니다만, 그러한 순간에도 단순한 객체를 만들고 TDD를 시도하는 것을 원하기도 합니다.

 

Martin : Tudor Pavel님의 질문을 한번 볼까요? "경험이 적은 개발자들에게 TDD는 어떻게 동작합니까?" TDD는 사람들에게 작은 조각에 집중할 수 있게 강요하며, 인터페이스를 구현체로부터 분리하게 도와줍니다.  TDD가 훌륭한 결과를 보장해주지는 않습니다. 왜냐하면 경험 없이는 좋은 설계를 할 수 없기 때문이죠. 대개 경험이 적은 사람들이 TDD를 하는 경우에는 리팩토링을 충분히 하지 않으며, 적당히 최적화된 설계를 하게 마련입니다. 여러분은 경험이 없는 개발자의 산출물과 경험이 있는 개발자의 산출물은 비교할 수 없습니다. 반드시 경험이 없는 개발자가 TDD 없이 작업한 결과물과 비교 해야만 합니다. 비록 측정할 수는 없지만, 이로울 것으로 보이며, 나중에 리팩토링을 통해서 개선하는 것 보다 쉽게 자가 테스트 코드를 만듭니다. 해서, TDD는 여러분에게 좋은 시작점을 제공합니다.

 

David : TDD로부터 얻은 가치에 대해 말씀 드리겠습니다. TDD를 시작할 때, TDD는 훌륭한 학습도구였습니다. (하지만 이번 논의는 충분히 나아가고 있지 않는 듯 하군요.) 저는 사람들이 신규 인력들에게 그대로 따르지 않을지라도, 간단하고도, 직관적이고, 겉만 번지르르한 조언을 달라고 말할 때마다 회의적이었습니다. 이는 제가 가르치는 것에 대한 확신이 부족하다는 것을 보여줍니다.

 

Martin : 저는 그런 독단적인 내용에 대해서는 동의하지 않습니다. 저는 제가 설명하고 있는 것에 반하는 논쟁거리를 찾지 못할 때 의심을 갖게 됩니다. 여하튼, 우리는 신규 인력에게 소개 세션을 반복하고 있습니다. 어떤 사람들은 기초를 반복하는 것일 싫어하거든요.

 

David : 바로 이러한 것들 때문에 우리가 지금 대화를 나누고 있다고 생각합니다. 사람들은 그들의 의견을 기초에 더했다고 말하곤 합니다만, 10년 뒤에는 시작지점 보다 한참이나 내려오게 될 것이며, 좋은 장소에는 있지 못하게 됩니다. 여러분은 리셋 버튼을 누를 필요가 있으며, 대충 무마 하는 것처럼 보이지만, 효율적입니다. 제가 TDD가 죽었다고 말할 때, 저는 현재의 변화에 대해 언급하였습니다 - 우리는 첫 번째 원칙으로 돌아가야만 합니다.

 

Kent : 제가 David의 원래의 키노트에 대한 본능적인 반응을 보인 것이 바로 그 부분입니다. 프로그래머들은 빈번하게 같은 작업을 반복하고, 코드를 지나치게 복잡하게 만들며, 제대로 동작하지 않는 시스템과 씨름을 할 것입니다. 저는 첫 번째 원칙으로 돌아가자는 것에 동의하지만, 지난 10년간 프로그램에 관한 사람들의 기대감의 발전을 잃고 싶지는 않습니다여러분은 반드시 확신을 느낄 수 있어야 하며, 전진하고 있다고 주장 할 수 있어야 하고, 생산적이고 기술적으로 협업 할 수 있어야 합니다. 저는 경력이 시작할 무렵에는 무척 부족하였습니다만, 이제서야 모든 일을 스스로 하고 있다고 느끼고 있습니다.

 

David : TDD, XP 그리고 Ruby는 동시에 우리에게 다가왔습니다. 사람들은 프로그램은 즐거워야만 한다는 말에 비웃었지만, 저는 Rails를 개발하면서 그 말을 계속하고 싶었어요. 제 생각에는 Ruby 세상에서는 그 행복이 찾아온 듯 하군요 - 그 말이 이겼습니다 - 바로 애자일을 가졌기 때문이죠.

 

Martin : 저는 애자일이 이겼다는 것에는 동의할 수 없습니다 - 애자일이라는 라벨이 이긴거죠. 그러나 많은 사람들이 애자일을 한다고 말하지만, 실제로 하고 있지는 않아요. 저는 이런 전형적인 현상을 나타내는 프로세스를 의미적인 유포(semantic diffusion)라고 말합니다. 큰 승리는 오늘날 우리가 애자일을 고객과 공개적으로 할 수 있게 된 점이죠.

 

David : 이러한 재시도 문제점은 다른 것들도 있어요 - 10년 뒤에 여러분은 싫은 것이 많아 질겁니다. 2 가지 맛으로만 시작하였던 Pinkberry를 예로 들어볼까요? 지금은 다른 아이스크림들과 마찬가지로 복잡한 범위의 맛들을 가지고 있죠 - "대부분의 사람들은 좋은 아이디어를 혼자 내버려두지 않으려고 하죠"

 

Kent : 저는 David가 경험한 TDD를 여태 본적이 없어요. 저는 언제나 첫 번째 원칙으로부터 TDD를 적용해왔으니까요. 하지만, TDD에 붙어 있는 따개비들을 떼어내야 한다고 주의를 준 David에게 감사를 표합니다.


David : Rails에서 비슷한 이슈를 본 적이 있습니다. 저는 Rails를 기초적인 폼 안에서 사용해 왔는데, 제가 본 일부 Rails 코드는 충격적이었죠.

 

Kent : XP가 주목 받기 시작할 때의 최초 OOPSLA가 생각나는군요.

 

Jim Rumbauch : David는 앞으로 지난 10년 동안 XP*에 벌어진 일들을 깨닫지 못할 것입니다. (그는 옳았습니다.) TDD는 성공하였고, 다른 대안들은 날아오르지 못했죠기술이 내재하고 있는 어떤 것 때문에 혹은 기술을 잘 못 사용한 것 때문에 나쁜 현상이 벌어지고 있다고 말하는 것은 언제나 어려운 일입니다. 우리가 할 수 있는 건, 기초적인 것과 좋은 교훈을 꾸준히 반복하는 것뿐이죠.

*역자주> XP : eXtreme Programming, SW 개발 방법론 중 애자일 실천 방법 중 하나

 

David : 동의 합니다. 당신은 영웅으로 죽거나 악당이 될 수도 있겠죠. Ruby는 프로그래밍에 관하여 좋은 아이디어의 재시도였습니다. 함수형 프로그래밍은 또 다른 재시도이죠. 이러한 재시도들은 건강합니다. 저는 Rails TDD가 오랫동안 함께 해온 것에 감명 받았습니다. 저는 Rails 이전에는 PHP로 작업을 했어요. 여러분은 잘 만하면 PHP로 좋은 코드를 작성할 수 있으며, 다른 프로그래밍 언어들로도 힘을 북돋아주는 좋은 사례들을 만들 수 있다고 느낍니다. 저는 MVC 기반 웹 애플리케이션에 TDD를 잘 사용하는 것은 깨끗한 PHP 코드를 작성하는 것 보다 어렵다고 생각합니다.

 

Kent : 전 제가 언제든지 TDD를 사용할 수 있다고 믿기 때문에, 그렇지 않은 경우를 찾지 못하겠군요. 저는 언제든지 다른 길로도 TDD로의 탐험을 하길 원합니다. 저는 제 경험과 함께 꾸준히 탐험할 것입니다. 지나치게 많이도 해보고, 충분하지 않게도 해보고, goldilocks zone도 찾아보며, 근본적인 원인을 이해할 것입니다. 저는 명확하게 David의 의견에 반박합니다. TDD는 죽지 않았습니다. 하지만 David TDD에 불을 질렀고, 마치 불사조처럼 튀어 나오게 된 점에 대하여 기쁘게 생각합니다.

 

David : 제가 이 논의를 시작하게 된 이유는 사람들이 TDD가 효과적으로 사용되지 않는 케이스에 대해 이야기 하려고 하지 않았기 때문입니다. 그들은 기분이 좋지도 않았거나 확신이 없었음에도 불구하고 반드시 TDD를 사용해야만 한다고 말하곤 했죠. 저는 타당한 반응에 대한 영역을 열기를 원했고, 이로 인해 우리는 TDD가 적절한 지 아니면 적절하지 않은 지에 대해 논의 할 수 있었습니다. 인터넷의 많은 사람들이 TDD가 얼마나 좋은지 말하고 있지만, TDD가 그들에게 잘 동작하고 있지 않다고 말하는 것을 두려워하고 있었습니다. 저에게 자가-테스팅 코드는 우리가 TDD에 대해 미심쩍어 할 때에도 잃고 싶지 않는 존재입니다.

 

Martin : (처음 시작하기 전부터 기대 했듯이) 우리는 많은 부분에 동의하였습니다. 우리 모두는 자가-테스팅 코드에 많은 가치를 얻고 있으며, 우리 모두 TDD가 어떤 곳에서는 가치가 있지만, 얼마나 많은 곳에서 가치가 있는지에 대해서는 (비록 말하기 어렵지만) 일부 동의하지 못하였죠. 만약, 여러분이 소프트웨어 개발을 하고 있다면, 이 점에 대해 반드시 깊게 생각해야만 한다는 것 그리고 당신과 당신의 팀을 위하여 잘 맞는 사례를 찾아내야 만 한다는 것, 그리고 여러분은 장님처럼 아무 기술이나 가져다 쓰면 안 된다는 것에 의견이 좁혀졌다고 봅니다. 여러분은 TDD를 시도할 필요가 있으며, 사용해야 하며, 남용도 해보고, 여러분과 여러분의 팀에 잘 동작하는 것이 무엇인지 찾을 필요가 있습니다. 우리는 공식으로 뒤덮인 과학 안에 있지 않습니다. 그렇기에 우리 스스로의 경험 기반으로 함께 일을 해야만 합니다.

 

Martin Fowler

 

설정

트랙백

댓글


 


번역가 : 송준이

현재 로엔에서 빅데이터 관련 업무를 하고 있다. Hadoop, Elasticsearch와 같은 빅데이터 관련 업무에 관심이 많다.


한글화 프로젝트는 프로그래머의 다양한 지식 습득을 위해 KSUG, JBUG와 지앤선이 함께 하는 프로젝트 입니다.

 

원문링크

 


스타트업이 비행하는 법

The Flight of the Startup. 



최근 반년 동안 스타트업에 대한 고민을 하다가 이상한 점을 발견했다. 나는 농장에서 살기 때문에 하루의 많은 시간을 삽질을 하면서(진짜 삽으로 땅을 파면서) 매일 팟캐스트를 듣는다. 팟캐스트에는 다양한 이야기가 있었는데, 그 중에는 스타트업에 대한 팟캐스트도 있었다. 그리고 해당 팟캐스트를 들으면서 깨달은 점은 1) 갓 시작한 회사임에도 불구하고 정보가 엄청나게 많다는 사실과 2) 이러한 정보들 중 몇 가지는 엄격히 보자면 서로 모순된다는 점이었다.

 

내가 읽고 들은 모든 내용에 공통적으로 드러나는 한 가지 테마는 바로 자본 효율성(capital efficiency)이다. 자본 효율성이란 스타트업이 위험 요소나 불확실성을 헤쳐나갈 때, 스타트업이 각 단계를 더 적은 비용으로 처리한다면 성공가능성이 훨씬 높아진다는 것이다. 스타트업은 너무 많은 불확실성을 내포하고 있으므로, 스타트업에게 가장 중요한 활동은 바로 실험이다. 적은 비용으로 실험을 더 많이 할 수 있다면, 스타트업이 살아남을 수 있는 가능성은 그만큼 더 높아지게 된다.

 

어렵더라도 이해하려고 노력하는 편이라, 서로 모순된 조언들 사이에서 타협점을 찾기 위해 노력했다. 마침내, 스타트업이 뚜렷하게 구분되는 단계들을 거친다고 가정하자 모순된 조언들을 이해할 수 있게 되었다. 팟캐스트에 의하면 각 단계마다 기법, 원칙, 기술, 심지어 가치조차도 변하게 된다. 그러나 그 조언들은 서로 모순된 것이 아니라, 적용되는 단계가 다름에도 불구하고  “스타트업이라는 하나의 단어로 뭉뚱그렸기 때문이었다. 스타트업의 단계는 비행기의 이륙과정에 비유할 수 있다.

 

1.            택시(Taxi) - 자리 잡기

2.            이륙(Takeoff) - 완전히 이륙하기 전까지는 적당한 한 방향을 향해 힘을 쏟기

3.            비상(Climb) - 상승세를 가파르게 유지할 수 있도록 전력을 다하기

4.            순항(Cruise) - 명확한 목표를 향해 조금씩 나아가기

 

이번 글에서는 각 단계를 간략히 살펴보고자 한다. 여기서는 각 단계를 특징짓는 개발 방식의 차이점에 대해 설명하겠다. 그리고 다음 글을 통해 각 단계를 전환하는 방법에 대해서 논의하도록 하겠다.

 

택시

첫 단계는 실질적인 필요성을 찾는 일이다. 이 단계는 몇 년이 걸릴 수 있다. “, 이 정도면 꽤 괜찮은 아이디어 같은데와 같은 감이 오는 단계이며, 전력을 다할만한 가치가 있는지 확인할 필요까지는 없는 단계다.

 

JUnit Max의 경우 택시 단계를 거치는데 11년이 걸렸다. 많은 사람들이 테스트를 작성하고 실행하는 일을 즐겼다. 바로 거기에서 사업으로 이끌어 낼만한 요소가 있을 거라고 확신했다. 수 많은 실험들을 진행했고, 마침내 머리 속에 무언가가번뜩하고 떠올랐다. 그리고 마침내 작년 12, 사람들이 돈을 내서라도 구입할 정도로 절실해 보이는 요구사항을 찾을 수 있었다. 바로, 테스트를 통한 피드백의 시간을 줄여 온전히 코딩하는 데만 집중할 수 있게 해주는 것이다. 광범위한 단위 테스트 속에서 코딩하는 프로그래머에게 이러한 요구사항은 실질적인 요구사항이라고 볼 수 있다.

 

택시 단계에서는 실험의 범위, 속도, 그리고 무엇보다도 실험 비용이 가장 중요하다. 많고 다양한 요구사항들과 관련된 아이디어를 시험해야 한다. 택시 단계에서는 실험결과의 정확도보다는 다양한 실험들을 가능한 많이 진행하는 것이 중요하다. 택시 단계의 위험 요인은 실질적인 요구사항을 찾지 못하는 일이다. 그러므로 위험 요인을 줄이기 위해 가능하면 많은 실험을 진행해야 한다. 이를 위해서는 실험 비용을 낮추는 일이 중요하다.

 

이륙

실질적인 요구사항을 찾았다면, 온 힘을 쏟아야 한다. 이전의 택시 단계에서 실험을 광범위하게 진행했다면, 불필요한 요구사항을 충족시키기 위해 자원이 소모되는 위험 요인은 충분히 모면할 수 있게 된다. 하지만 실질적 요구사항 모두가 사업성을 갖지는 않는다. 이륙 단계는 바로 이러한 사업성을 보장하는 고객을 찾고 수익을 창출하는 과정이다. 비행기의 바퀴가 땅에서 이륙하기 위해선 강한 추진력을 필요로 한다. 이와 마찬가지로, 스타트업의 이륙단계에서도 자력이든 아니면 투자를 유치하든 현금 흐름이 지속적으로 투입되어야 한다.

 

시장도 성숙했고 아이디어도 훌륭하더라도, 고객이 지갑을 열게 하는 기능을 반드시 찾아내야 한다. 이륙 단계에서는 광범위한 아이디어를 빠르게 훑는 조사보다는 주어진 요구사항을 해결할 수 있는 제품에 대한 구체적 연구가 더 중요해진다. 각 실험은 수익을 창출하거나, 또는 수익을 낼 수 없다는 결론이 나야 끝이 난다.

 

열렬한 잠재고객과 실제 비용을 지불하는 고객 사이의 간극은 상당히 크다. 시장이 존재함을 확인할 수 있어야 한다. 이륙 단계에서는 개발 주기 중 일부 시간을 포기해서라도 확신을 가질 수 있게 피드백을 받기 위한 시간을 내야 한다. 이륙 단계의 개발 주기는 가능한 아주 작은 제품을 출시하는 것이다. 이 제품이 구매할 만한 가치가 있는지 확인하기 위해 제품을 사는 사람이 있을 정도의 제품이면 충분하다. (이러한 제품을 규정하기는 어렵지만, 최소 요건 제품(Minimum Viable Product)이라고 부른다).  최신의 소프트웨어 개발과 마케팅 방법을 적용하면 다양한 시도를 통해 위험을 감소시킬 수 있을 정도로 자본 효율성을 충분히 높일 수 있다. Max를 만들 때 내가 따랐던(그리고 이전의 여러 벤처에서는 따르지 않았던) 충고는 “부끄럽지 않은 제품을 내었다면, 실험에 너무 많은 시간을 허비한 것이다.

 

(일부 스타트업 단체에서는 확장이 우선이며, 상품화는 그 다음이라고 주장하기도 한다. 나는 그 방법을 따르기에는 자금도 없었고, 그만큼 훌륭한 아이디어도 없었다. 만약 여러분도 나와 같은 상황이라면, 앞의 내용들에서수익사용처로 바꿔 보기 바란다. 또한 수익을 뒤로 미룰 수 있는 행복한 상황이라면, 스타트업을 어떻게 꾸려나가는지에 대한 여기 조언들이 큰 도움이 되지 못할 것이다.)

 

JUnit Max는 현재 이륙 단계에 있다. 실질적인 필요성을 해결하고 있다고 확신할 정도로는 수익이 나고 있지만, 자체적으로 더 성장하기에는 수익이 충분치 않다. 하지만 위험한 가정들을 검증하는 첫 단계는 이미 넘어섰기 때문에, 동일한 테마를 바탕으로 제품을 지속적으로 실험하고자 한다.

 

비상

제품의 핵심 기능들을 만들어서 수익이 나기 시작했다면, 다음 단계는 제품이 실질적인 수익을 창출하도록 빠르게 비상하는 일이다. 비상 단계에서는 조직에서 기술 파트와 비즈니스 파트가 중요해진다. 마케팅부가 이전 단계에는 테스트를 위해 수백 정도의 사람에게 제품을 전달했다면, 이제는 제품을 십만 명에게 전달해야 한다. 영업부는 이전 단계에서 소량을 판매해도 충분했지만, 이제는 수천 개를 판매해야 한다. 기술 파트에서는 이전에는 적은 수의 사용자를 감당할 수 있을 정도의 소프트웨어를 구축하면 충분했지만, 이제는 사용자 수가 크게 늘어나더라도 감당할 수 있는 소프트웨어를 구축해야 한다. 또한 팀 전체는 수천만 또는 수억이 넘는 간단한 사용자 대화뿐만 아니라 꽤 많은 심도 깊은 대화를 통해 얻은 피드백에서도 배워야 한다.

 

비상 단계에서는 매일 새로운 문제가 발생한다. 따라서 비상 단계에서는 문제가 하나라도 발생하면 문제를 해결한 후 다음 문제를 대비하는 일이 가장 중요한 역량이다(만약 문제를 쌓이도록 방치하면, 결국에는 문제들에 싸여 꼼짝 못하게 된다).

 

비상 단계에서는 자금 효율성 또한 그 의미가 바뀐다. 이 단계에서는 수익이 나거나 또는 투자를 받게 된다. 그리고 돈을 지출하면 문제를 해결할 수 있다. 비상 단계의 자금 효율성은 얼마나 돈을 덜 썼는지가 아니라 얼마나 돈을 효율적으로 썼는지 측정해야 한다. 물론 이 단계에서도 예산은 빡빡하다. 고객수의 자릿수를 한 단계 높이기 위해서 더 적은 돈을 쓸 수 있다면, 고객수의 자릿수를 한 단계 높이는데 걸리는 시간은 더 짧아지게 된다.

 

순항

언젠가는 출근했을 때 새로운 문제가 하나도 없는 단계가 된다. 이제 과거에 한번 발생했던 문제만이 생기게 되고, 이들 문제는 모두 어떻게 해결할지 습득한 상태다. 이러한 상황이 되면 비상 단계에서 순항 단계로 단계가 전환된다. 순항 단계의 목표는 여전히 자본 효율성이지만, 이제는 확장이 아니라 이윤을 추구하게 된다.

 

순항 단계에서는 장기/단기 절충안을 만드는 일이 바람직하게 된다. 이 단계에서는 불확실성이 충분히 가라 앉게 되고, 옵션 가치(Option Value)로 사업 결정을 평가하기 보다는 할인현금 수입 가치(Discounted Cash Flow)가 더 합리적인 사업 평가 기준이 된다.

 

그리고 순항 단계에서는 원가 인하가 수익성을 주도하게 된다. 개발자 테스트와 같은 실천법은 이륙 단계에서는 적당히 유용했고, 비상 단계에서는 생존의 문제였지만, 순항 단계에서는 원가를 절감하여 이윤을 높이는데 도움이 된다.

 

결론

제품이 순항 단계에 접어들면, 새로운 아이디어가 파생하게 되고 작은 규모의 스타트업을 새롭게 비행시켜야 할 순간이 오게 된다. 기법, 기술, 원칙, 가치는 이제 다시 이전의 택시 단계로 전환해서 새로운 싹을 틔워서 살아남을 수 있는 최적의 기회를 모색해야 한다. 놀랍게도(적어도 내가 보기에) 스타트업 비행 모델은 일반적으로 대기업 내부의 프로젝트에서도 유효하다. 이 주제에 대해서는 다음 번에 다루도록 하겠다.

 

(문득 이륙 단계를 위한 효과적인 기술이 없다는 생각이 들었다. 나의 경우, AppEngine처럼 관리가 편하고 스몰토크처럼 유연하며 강력한 기능이 결합된 기술이 필요하다. 그렇다고 너무 방대한 기능을 구현하지 않아도 된다. 초기에 적으나마 매출이 일어날 수 있을 정도로 충분해 보인다. 하지만 이런 제품을 만들려면 스타트업을 새롭게 시작해야 할테고, 그러기에는 너무 바쁜 상황이라…)

 

스타트업에 대한 분명히 모순되는 조언들도 이처럼 4가지 단계로 생각하면 일리가 있다. 페이퍼 프로토타입 아니면 최소 요건 제품? 택시 또는 이륙? 영세함 아니면 빠른 성장? 이륙 또는 비상? 미친 듯이 기능 추가 아니면 무자비한 리팩토링? 이륙 또는 비상? 내일을 위한 투자? 당신은 순항 단계에 접어들었는지? 어떤 조언들도 잘못되지 않았다. 그저 명확하게 기술되지 않았을 뿐이다. 비행 단계 중 어느 단계에 있는지 알고 있다면, 다음 걸음을 내딛는데 도움이 될 것이다. 즐거운 비행이 되기를.



출판사 주: '비상'과 '순항'의 항목에 있는 그림은 원본 링크에서도 더이상 볼 수 없다고 표기되나 다른 항목과의 통일성을 위해 원본과 똑같이 작업 해 두었습니다.

 





설정

트랙백

댓글


사실 유명환님과는 평소 친분이 있어서 굉장히 화기애애하게 진행되었고, 다른 분들과 인터뷰를 진행 하면서 궁금했던 점에 대한 질문도 많이 이야기 나눌 수 있는 시간이었다. 자주 뵙는 분이었지만 인터뷰를 통해서 조금 더 많은 것을 알게 된 듯해서 개인적으로도 너무 좋은 시간이었다. 특히, 백승현님께서 게스트로 참석해주셔서 더욱 뜻 깊은 자리가 되었다.


 

Q 우선 본인 소개를 부탁 드립니다.

A 2013년까지는 이분투 대표였으나 합병 후 연구소장으로 근무 중이다. 현재 하는 일은 오픈소스 기반의 서버용 소프트웨어를 만들고, 휴대폰으로 웹서버나 데이터베이스 서버를 돌릴 수 있게끔 만들고 있다. 사실 휴대폰에 들어가는 ARM 어쩌구 했는데 잘 모르겠다 하드웨어를 직접 만드는 일들이다. 지금 하고 있는 일을 이분투에서도 하고자 했으나 회사가 작아서 하지 못하고 용역 위주의 일들을 많이 했었다. 용역은 주로 리눅스와 안드로이드 관련 일들이었다. 근 십 년, 공식적으로는 2005 11일부터 사업을 시작했다. 1997 ETRI에서 지원을 받으면서 시작했던 것이 공식적인 개발자로서의 첫 걸음이었다.

 

Q 프로그래머가 된 계기는 무엇인가요?

A 어렸을 때는 막연히 과학자가 되고 싶었다. (마징가라는 로봇 만드는 박사 같은 그런...) 그렇게 생각하다 보니 전공을 택하게 되었고, 컴퓨터는 대학에 가서 처음 접했다. 학점은 솔직히 의대에 갈 수 있는 수준이었다. ~~~~~~ 대학 때 unix로 처음 시작했다. (그냥 컴퓨터가 멋있어서…)

 

Q 그럼 대학 가기 전까지는 막연히 과학자가 되고 싶으셨던 거네요?

A 프로그래머라는 개념 자체를 그때까지 몰랐다. 대학 때도 전자회로나 이런 수업은 재미가 없어서 당구치고 놀았고 유일하게 재미있게 들은 수업이 c언어였다. 나머지는 거의 독학으로 배웠다.

 

Q 그럼 로봇은 어떻게 만드시려고 했나요?

A 그런 생각 자체가 없었다. 생각 없는 젊은이였다고 하셨다ㅋㅋㅋ 지금도 어쩌면 생각 없이 하고 싶은 것만 추구하고 있는 편이다. 첫 직장은 Java 프로그래머였는데, 그걸 다 포기하고 하드웨어 길로 접어든 이유도 그냥 재미있어서였다

 

Q 업계에 들어와서 가장 영향을 많이 받은 개발자가 있나요?

A 사실 내가 겪은 환경 자체가 다른 사람의 영향을 받기가 쉽지 않았다. 처음 공부할 때는 인터넷도 없었고 책도 별로 없었다. 그런데 개발자가 되게끔 영향을 준 사람은 2년 대학 선배였다. (지금은 n 포털사에서 근무하는 황모씨!!!) 그 선배가 정말 즐겁게 프로그래밍하는 개발자의 모습을 보여줬다. 그 전까지는 당구치거나 무협지나 만화가 더 재미있었는데 그  덕분에 컴퓨터가 재미있다는 것을 알게 되었고 술을 마시지 않아도 재미있게 할 수 있는 것을 처음 발견하게 되었다. 술을 안 마시고 밤을 샌 것도 처음이었다.

 

Q 개발자로서 가장 힘들었을 때는 언제인가요?

A 창업을 하고 사업 했을 때 힘들었다. 다시 돌아가라면 안 할 것 같다.

 

Q 그런데 그건 개발자이기 때문에 힘든 것은 아니지 않나요?

A 개발자이기 때문에 힘든 것이었다. 10년 가까이 사업을 하면서 요즘 와서 깨달은 것은 사업을 할 것인지 사장을 할 것인지가 중요하다는 것이다. 합병이 된 후 다시 연구소장으로 돌아가니 역시 나에게는 사장보다는 연구소장이 맞다는 것을 느끼고 있. 다시 프로그래밍을 하고 디버깅을 하는 지금이 너무 행복하다.

 

Q 그렇다고 업계에 들어오신 후 계속 사업을 하셔서 프로그래머로서 힘든 점은 별로 없으셨겠어요.

A 솔직히 말하자면, 수락산 중턱에 있는 터널(3.5km) 안에 우리가 개발한 장비가 들어가 있어서 오픈 전부터 오픈 후까지 3~4개월 정도를 지원을 나갔었는데 그때 육체적으로 힘들긴 했다. 하드웨어를 다루기 때문에 현장에서의 힘든 부분들이 있다.

 

Q 현장에서도 힘들었겠지만, 개발자이면서 사장이기 때문에 더 힘들었던 것 아닐까요?

A 어쩌면 현장에 나 혼자만 있는 것이 아니라 직원들이 함께 있고 그 직원들을 챙겨야 하는 입장이다보니


Q 같이 일하기 싫은 프로그래머가 있나요?

A 사실 싫다기 보다는 힘든 개발자는 끈기가 없는 개발자이다. 가끔 직원들에게도 이야기 하지만 개발자는 코딩 능력과 삽질 능력(문제를 파고 드는 근성이라고 해야 하나?)이 함께 있어야 하는데, 조금만 힘들어도 쉽게 포기하는 사람들과는 일하기 힘들다. 그런데 근성이 있고 코딩 능력이 되는데 소통이 안 되면 결국 끝까지 버티기 힘들더라. 아무리 작은 개발이라도 한두 달 안에 끝나는 일이 거의 없기 때문에 소통이 안 되면 지속되기가 어렵다.

 

Q 면접을 보실 때 개발 능력 외에 무엇을 가장 중요하게 보시나요?

A 면접을 한번도 본 적이 없다. 지금까지는 아는 사람만 뽑았다. 허걱 이력서도 입사 후 쓰도록 했다. 작은 회사이다 보니 나와 서로 잘 맞는지가 중요하더라. 그렇지만 대부분 커뮤니티를 통해서 최소한 2년 이상 알고 지내온 사람만 뽑았고, 오랜 시간 겪고 대화하면서 찾으려고 했다. 팀워크가 가능한 사람을 제일 중요시한다. 특히 하드웨어를 만드는 회사이다 보니 소프트웨어 개발자와 하드웨어 개발자의 융합이 중요하다. 지금까지는이라는 말을 강조하셨는데 지금은 어떠신지 모르겠다.

 

여러 인터뷰를 하면서 느끼게 된 것은 개발자는 정말 팀워크가 중요한 직업이라는 것이었다. 사실 일반인들이 막연히 떠올리는 개발자의 이미지는 혼자 방안에 앉아서 혼자 프로그램을 하는 그런 뭐랄까 오덕스러운 느낌이라고나 할까? 그런데 인터뷰를 통해 만난 모든 사람이 소통과 팀워크를 이야기 했다. 개발자가 어쩌면 다른 어떤 직업에 비해 팀워크가 더욱 필요한 직업이 아닐까?

 

Q 프로그래머라는 직업의 매력은 무엇이라고 생각하시나요?

A 문제를 해결했을 때 느끼는 짜릿함!!! 사실 개발자로서 제일 뿌듯하거나 보람을 느낄 때는, 내가 만든 제품을 다른 사람이 써주는 것만해도 감사한데, 그 사람들이 좋은 피드백을 줬을 때 더욱 기분이 좋다. 어떻게 보면 인정을 받았다는 것에 대한 뿌듯함일 수도 있다. 사실 회사가 작아 사업을 하면서 용역 일을 하다 보니 이런 인정을 통한 뿌듯한 느낌을 많이 못 받았던 거 같다. 그래서 어쩌면 가슴에 칼을 품었을지도 모른다

 

Q 학생들이 이쪽 분야가 자신에게 적성이 맞는지 아닌지 어떻게 알 수 있을까요?

A 다른 건 모르겠는데, 본인이 공부하는 것을 좋아하는지 아닌지에 대해서만큼은 알았으면 좋겠다. 이쪽 분야는 평생 공부가 필요하다고 생각한다. 그리고 개인적인 기준으로 보자면 호기심이 중요하다. 어느 것 하나도 그냥 지나치지 않고 자꾸 물음표를 던질 수 있다면 적성에 맞는 것 같다고 생각한다. 궁금증과 호기심이 넘치는 것은 나인데 코딩 능력만 부족하다고 말씀하셨다 오호호호~

 

Q 개발자에게 좋은 환경의 회사라는 것은 어떤 환경의 회사라고 생각하시나요?

A 자율적인 분위기!!! 물론 어떤 의미에서는 개발자에게 좋을 수도 있고 안 좋을 수도 있다. 알아서 스스로 개발할 수 있는 레벨의 개발자에게는 자유로운 분위기가 좋겠지만, 이제 막 시작한 개발자에게는 자유로운 분위기를 주면 오히려 성장을 막을 수도 있다. 이제 막 시작한 개발자에게는 성장할 수 있는 분위기를 주는 것이 좋은 환경이고, 어느 정도 성장한 개발자에게는 문제 해결에서 자유롭게 결정할 수 있는 권한을 줄 수 있는 분위기가 좋은 환경이라고 생각한다. 모든 개발자를 아우른다면 정당한 대가를 특히 돈을 받을 수 있는 환경이라고 생각한다. 만족도를 꼭 돈으로 느끼는 것은 아니지만 돈도 무시할 수 없을 정도로 중요하다. 돈이 전부는 아니지만 일한만큼의 보상, 노력에 따른 정당한 대가는 중요한 것이라고 생각한다.

 

Q 이런 환경의 회사를 만들기 위해서 개발자 스스로 어떤 노력을 해야 한다고 생각하세요?

A 자기가 정말 이 회사에 녹아 들어서 기여하고 있는 지를 보고, 완성도에 대한 기준을 스스로 정하고 책임을 져야 한다고 생각한다. 모든 직업 중에 말을 잘하고 글을 잘 써야 하는 것이 개발자라고 생각한다. 왜냐하면 자신이 개발한 것을 설명하고 알려야 하니까 자기만의 언어가 아니라 소통을 할 수 있도록 노력해야 한다. 틀린 것이 아니라 다른 것을 이해하기 위해서도 소통의 노력이 필요하다. 결국 개발자뿐만 아니라 회사의 모든 사람들이 소통이 잘 되는 회사가 일하기 좋은 환경의 회사가 아닐까?

 

Q 사회 초년생에게 사회생활에 대해서 조언을 해주신다면?

A 계속 이야기 하고 있지만 의사소통을 중요하게 생각해라. 내가 커뮤니티에서 사람들을 오랜 시간 겪으면서 채용을 하는 이유는 그 사람의 태도와 여러 사람에게 어필하는 방법(의사소통)을 보기 위함이다. 직접 겪으면서 일하기 전까지는 코딩 능력을 알긴 어렵다. 이건 어떤 직업이든 마찬가지로 중요하다고 생각한다

 

Q 사용자나 고객을 이해하기 위해서 개발자에게 제일 필요한 것이 무엇이라고 생각하세요?

A 역지사지. 내가 만든 제품을 내가 쓴다면 어떨지에 대해서 생각해봐야 한다. 개발자가 자기가 만든 것에 몰입하는 능력은 정말 뛰어나다. 그러다 보면 사실 한 걸음 벗어나서 사용자의 입장을 생각 못할 때가 생긴다. 그래서 QA팀이 필요한 거라는 생각도 든다. 머리는 이해해도 가슴으로 이해는 못한다. 그래서 엄밀히 따지면 자기가 만든 것을 자기가 평가하면 안 된다. 그리고 그 평가에 대해서 인정하는 능력이 필요하다. 확신을 가지는 것은 좋지만 사업으로 생각할 수 있어야 한다. 불가능하긴 하지만 개발자가 영업을 해보면 좋겠다는 생각을 할 때가 있다. 개발만 했을 때는 몰랐는데 영업을 해보니 알게 되었다. (어쩌면 이런 것도 서로의 자리에서 서로의 일을 하되 서로 인정해주고 서로의 의견을 받아 들여준다면 가능하지 않을까 싶다.)

 

Q 프로그래머가 되지 않았다면 무엇이 되셨을까요?

A 개발 말고 잘 하는 것 중에 하나가 그림을 그리는 것이라 중학교 때까지도 가족의 지원이 있었다면 그림을 해보고 싶었다. 그리고 공부하는 것을 좋아해서 교직에 있었을지도 모르겠다

 

Q 재충전은 어떤 식으로 하시나요?

A 속상하면 하루 종일 만화책을 본다. 예전에는 술을 마셨는데, 너무 힘들더라. 그럴 때는 이 문제를 잠깐 피해서 너무 감정적이 되지 않으려고 한다. 주로 무협 혹은 SF 만화이다 보니 주인공이 온갖 난관을 극복해서 성공하는 내용이다. 그래서 더 힘을 얻는다

 

Q 보통 주말은 뭐하고 보내시나요?

A 이제까지 주말을 온종일 놀아 본적은 10년정도 없었고, 말도 안돼~ 가급적이면 애들하고 보드게임 등을 하면서 놀아주려고 한다. 그럼에도 불구하고 어느새 애들하고 놀아 준지 2주가 지났다. 조금 더 시간이 나면 동네 도서관에 간다

 

Q 최근에 개발 외에 관심 있는 건 어떤 것이 있으세요?

A 얼굴 살 빼기. 어떻게 하면 헬스를 일주일에 세 번 할 수 있을까? 최근 페이스북을 통해서 본 유명환 소장님의 글 : “오오오~ 운동 3주째... 드디어 배에이 보이기 시작했다!!! 그런데........... 금이 횡으로 보이는 게 정상인거지??? (-_-);;;;;;;”

 

Q 기술적으로는요?

A 기술적으로는 어떻게 하면 노트북을 예쁘게 만들 수 있을까 고민한다. 또 요즘 멘토링 해주는 팀이 있는데, 어떻게 하면 이 아이들이 내가 했던 고생을 하지 않고 창업할 수 있게 도와줄 수 있을지 올바른 방향으로 갈 수 있을지 관심이다.

 

Q 최근 가장 짜릿했던 경험은 어떤 것이 있었나요?

A 같은 회사의 하드웨어 개발 팀장을 정말 잘 뽑았다고 느꼈을 때 정말 짜릿했다. 농예학을 전공한 비 전공자인데다 개발 경력이 10년인데도 특별히 말할 수 있는 경력이 없었는데(어쩌면 기대치가 낮았는데)… 책임감 있는 행동과 문제해결 능력을 보면서 정말 뿌듯한 느낌이 들었다.

 

Q 10년이나 개발을 하셨는데 그 동안은 어떤 생각으로 하셨을까요?

A 기본적인 인성과 책임감을 갖춘 사람이다. 하고 싶은 욕망이 있었지만 전에 회사에서는 기회를 주지 않아서 충분한 능력을 도출해내지 못했던 것 같다. 지금도 힘들어 하지만 해결해 나가는 모습을 보이고 있어서 너무 행복하다는 생각이 든다. 유소장님이 그분의 발전하고 싶은 욕망을 잘 끌어줘서 가능했던 일이라고 생각한다.

 

Q 어떻게 보면 숨은 인재를 발굴해 낸 건가요? 그러고 보니, 저는 뛰어난 프로그래머가 뭔지 잘 모르겠어요~ 뛰어난 프로그래머란 어떤 건가요?

A 제일 간단한 건 어떻게든 문제를 해결해내는 사람. 어떤 문제가 생겼을 때 그 문제를 적시적소에 잘 해결해내는 사람. 문제를 해결할 때 원인을 얼마나 빨리 찾아내고 그것을 어떻게 고쳐 나가느냐 코딩능력과 삽질능력 그리고 소통능력을 두루 갖춰야 한다. 이런 모든 것들이 경험을 통해서 알 수 있는 것이다. 듣고 나니 더 무슨 소린지 모르겠음 ㅠ.

 

아이디어가 뛰어난 사람을 뛰어난 개발자라고 하지는 않는다. 문제를 해결했는데 또 다른 문제를 만들어내는 사람은 그냥 단지 그 문제만 해결한 사람일 뿐이다. 근원을 파고들어 문제를 해결하려고 하는 사람이 뛰어난 개발자이다. 자기의 한계를 스스로 낮게 정하지 않아야 한다. “난 그냥 이 정도만 하면 돼~”가 아니라 조금 더 하려고 하는 마음이 필요하다.

 

Q 꿈이 있으세요?

A 단기적인 꿈은 지금 만들고 있는 제품, ARM 서버가 잘 나와서 돈 잘 벌 수 있는 것이다. 그리고 멘토링 하고 있는 학생들에게 도움이 되어서 그 아이들이 올바른 길을 재미있게 갈 수 있도록 도와주고 싶다. 그리고 사적으로는  이사!!! 장기적인 꿈은 40대에는 공부한 것을 가지고 사업을 할 수 있고 50대에는 그 사업을 가지고 연구소를 하고 싶다는 꿈을 가지고 있다. 누구나 돈 걱정 없이 정말 재미있는 것을 할 수 있는 연구소를 만들고 싶다. 글로벌하게 런칭해서 60대에는 명예회장으로 전세계에 있는 나의 회사들을 다니면서 내 경험을 나누어주고, 좀더 크게는 가정이 어려운 학생들을 위해서 대학을 세우는 것이 최종적인 꿈이다. 내가 어렸을 때 어려운 가정환경 때문에 많은 것을 포기했기 때문에 꼭 그런 애들을 도와주고 싶다. 20대부터 가졌던 꿈이고, 그런 생각들을 하면 너무 즐겁다. 사실은 조금 더 솔직하게 말하자면 돈 많이 벌어서 엄청 예쁘고 멋진 여비서를 두는 것이 꿈이다. 엄청 거창한 것 같지만 유소장님을 잘 아는 사람들이라면 이 이야기를 들으며 고개를 끄덕이게 될 것이다. 특히 제일 마지막 부분에서언제나 참 솔직하신 분~

 

Q 스스로 자신을 어떤 개발자라고 정의할 수 있을까요?

A 나 스스로를 개발자라고 말하기에는 개발을 잘 못하는 것 같다. 개발자들이 개발을 잘 할 수 있는 환경을 만들어주거나 도와주는 서포터!!! 이 정도가 나한테 맞는 것 같다.

 

Q 게스트 번외 질문 : 당신은 어떻게 기억되고 싶은가요???

A 그렇게 말한다면, 개발자로 기억되고 싶다. 죽을 때까지 개발자로 남고 싶다. 다른 사람에게 동기부여를 줄 수 있었음 좋겠고, 재미있는 개발자가 되고 싶다. (이 사람과 만나면 정말 재미있다 라고 말하는…) 그래서 어쩌면 때론 가벼워 보인다는 이야기를 들으시면서도 끊임없이 농담을 던지시는 것이 아닐까 하는 생각이 들었다. 재미있는 개발자로 기억되고 싶으셔서

 

Q 후배 개발자들에게 해주고 싶은 이야기 혹은 조언을 말씀해주세요.

A 지난 토요일에 모교를 방문해서 후배들에게 세미나를 했는데, 그때 일은 결국 사람이 하는 것이기 때문에 인성이나 태도가 제일 중요하다는 이야기를 했다. 어릴수록 욕심이 많은 것 같더라. 물론 욕심이 없는 것보다 낫다. 그렇지만 욕심에 대한 우선순위를 가졌으면 좋겠다. 쉽게 쉽게 유행을 쫓기 보다는 기본을 다져야 한다. 트렌드를 따라가다 보면 당장은 필요한 개발자인 것처럼 느껴질 수 있지만 결국 해를 거듭할수록 뒤쳐지게 된다.

 

그리고 의사소통 능력은 계속 이야기 했지만 중요하다. 요즘은 페이스북에 온갖 최신 정보가 나오니까 그걸 통해서 공부를 하더라도 내가 습득한 것에 대해서 내가 깨달은 것을 더해서 블로그를 쓰는 노력도 필요하다. 글을 잘 쓰고 말을 잘 하려면 책도 많이 읽고 발표도 많이 해봐야 한다. 모든 것은 연습이 필요하다.

 

 

유명환 소장님은 누구보다도 소통을 강조하셨다. 그리고 사람과 사람 사이의 관계에 대한 이야기를 많이 하셨다. 결국 개발도 사람이 하는 일이고 소프트웨어든 하드웨어든 사람에게 사람이 만드는 것이기 때문에 모든 작업에 그 사람의 마음이 담아져야만 하는 것이 아닐까란 생각이 들었다. 그렇기 때문에 지금까지도 오랜 시간에 걸쳐 지켜보고 알아 온 사람하고만 함께 일을 하시는 것이 아닐까?

 

인터뷰를 올리기 전 최종본을 확인받기 위해 보내드린 메일의 답장은 뭔지 모를 감동을 주셨다.

우선 먼저 너무나 고맙다는 얘기부터 할게요. 너무 고마워요.

인터뷰 글을 읽다 보니 그간 바빠서 자칫 잊을 뻔 했던 생각들이 하나 둘씩 떠올라 다시금 자체 힐링이 되어서 기운이 돋았어요. 너무나 고맙습니다.”

저 역시 너무나 고맙습니다.

설정

트랙백

댓글


 


번역가 : 송준이

현재 로엔에서 빅데이터 관련 업무를 하고 있다. Hadoop, Elasticsearch와 같은 빅데이터 관련 업무에 관심이 많다.


한글화 프로젝트는 프로그래머의 다양한 지식 습득을 위해 KSUG, JBUG와 지앤선이 함께 하는 프로젝트 입니다.

 

원문링크

 

테스트 하느냐 마느냐, 그것은 좋은 문제로다.

To Test or Not to Test? That’s a Good Question. 


소프트웨어 개발 분야에서 영구 불변의 진리는 영구 불변하는 것은 없다.’이다. 이는 테스트의 역할에 대해서 이야기할 때도 마찬가지이다.

 

과거에는 테스트는 우리(프로그래머)가 아닌 다른 사람의 몫이라고 생각할 때도 있었다. XP의 등장으로 많은 프로그래머의 생각이 바뀌었다. 테스트는 우리 모두의 일이며, 지속적으로 해야 한다고 믿게 되었다. 그러나 이는 테스트를 작성할 수 있다면 반드시 해야 한다는 테스트 지상주의를 맹신하게 만들기도 했다.

 

나는 테스트를 항상 작성해야 한다고 고집했는데, 이러한 경험을 통해 시간이 허락한다면 무엇이든 테스트를 할 수 있다는 사실을 배울 수 있었다. 또한 테스트는 믿을 수 없을 만큼 기술적, 심리적, 사회적, 경제적 가치가 있다는 사실을 알게 되었다. 하지만 테스트에 대한 이러한 내 전략을 뒷받침하는 가정이 하나 있는데, 이러한 가정이 맞는지는 최근까지도 분명하지 않았다.

 

소프트웨어 개발은 종종 긴 게임이 되곤 한다. 내 생각에 소프트웨어 사업 중 최고는 단연코 MVS PL/1 컴파일러다. 심지어 MVS PL/1 컴파일러는 고작 3명의 직원만으로 매년 300만달러를 벌어들인 때도 있었다는 소문까지 듣기도 했다. 이 정도까지 사업이 번창하려면, 인내심을 가져야 하며, 향후 수십 년 동안 소프트웨어가 유지될 수 있도록 투자해야 한다.

 

테스트에 대한 내 가정을 불분명하게 만드는 것이 바로 이 종종이라는 부분이다. 골프에서도 긴 게임과 짧은 게임이 있고, 각 게임마다 필요로 하는 기술은 서로 관련 있지만 완전히 같지는 않듯이, 마찬가지로 소프트웨어 개발에도 긴 게임과 짧은 게임이 있다. JUnit Max의 경우, 소프트웨어에서의 짧은 게임을 치르고 있다. 이 짧은 게임을 하면서 관련은 있지만 완전히 동일하지 않은 기술이 소프트웨어 개발에서 어떤 의미가 있는지를 깨우치고 있다.

 

두 가지 프로젝트

JUnit은 긴 게임이다. 사용자도 많고, 수입도 안정적이며(0$, !!!), 기능도 한정적이다. 우리는 모두 JUnit에 대해 알고 있다. 또한 사용자를 끌어들이고 유지할 수 있는 부분이 무엇인지도 이해하고 있다. 따라서 천천히 변경되는 요구사항들을 조금 앞서 해결하면 그만이다.

 

JUnit을 만들 때는 XP 실천법들 모두가 유용했다. 항상 테스트 주도로 개발했다. 그리고 가능하면 언제라도 리팩토링을 했으며, 마음에 드는 한가지 방법을 찾기 전에는 서너가지 방법을 시도한 적도 가끔 있었다.

 

JUnit은 지원 비용이 점근적으로는 0에 수렴해야 한다는 사실로 그 성공 여부가 판가름난다. JUnit을 실제로 사용하는 사용자의 숫자는 엄청나게 많았지만, 지원을 위한 예산은 없었기 때문이다. 따라서 성공하기 위한 방법은 명백했다. 천천히 진화시키고, 광범위하게 테스트하며, 릴리즈는 최소한으로 줄여야 했다.

 

JUnit Max를 개발하기 시작했을 때, 규칙이 바뀌었다는 사실을 천천히 깨닫게 되었다. JUnit Max가 살아남기 위한 핵심적인 질문은어떤 기능을 만들어야 비용을 지불할 사용자를 끌어들일 수 있는가?”였다(이다). 당연하게도 이 질문에 대해서는 대답할 수 없다. 만약 JUnit(또는 무료로 배포되는 다른 패키지)이 해당 기능들을 구현한다면, 어느 누구도 Max를 돈을 주면서까지 사용하지 않을 것이기 때문이다.

 

JUnit Max은 그 성공 여부가 자력으로 수입을 만들어내는데 달려 있다. 비용을 지불하는 사용자가 늘고, 사용자당 수익이 증가하며, 입소문을 통한 효과가 높아야 한다. 당연하게도 JUnit Max가 성공하기 위한 방법을 알지 못했기 때문에, 성공할 가능성을 높일 수 있는 방법이 무엇인지 알기 위해서 수많은 실험들을 하고, JUnit Max가 실제로 사용되고 적용된 피드백을 통합하는 것이었다.

 

테스트 하느냐 마느냐.

이러한 피드백 통합을 위한 한가지 방편으로 Max에서 발생한 내부적인 에러 모두를 중앙 서버로 전달했다. 긴 게임의 프로젝트와는 달리, 짧은 게임의 프로젝트의 경우 런타임 에러가 항상 나쁜 점은 아니다(이 주제에 대해서는 다음 글에서 다룬다). 반면 내가 알지 못하는 에러는 확실히 나쁜 점이다.

 

에러 로그를 찬찬히 살펴보면서, 나는 수정할 수 있는 두 가지 에러를 발견했다. 주어진 시간에 맞출 수 있는 실험들이 하나도 없었기 때문에, 두 가지 에러 모두를 고치기 시작했다.

 

첫 번째 결함은 간단했다. 닫힌 프로젝트가 예외를 발생시켰다. 테스트를 작성하는 일도 쉬웠다. 기존의 테스트를 복사한 후, Max를 실행하기 전에 프로젝트 닫도록 수정했다. 아니나 다를까 빨간 불이 떴다. 나중에 2개의 라인을 수정하니, 녹색 불이 떴다.

 

두 번째 결함의 경우, 딜레마에 빠지게 되었다. 문제를 해결할 방법은 알고 있지만, 자동화된 테스트를 작성하는데 필요한 것들을 배우려면 어림잡아 수시간이 걸릴 것 같았기 때문이다. 그래서 결정했다. 고치고 배포하자. 테스트는 없다.

 

나는 두 가지 결정 모두를 지지한다. 두 경우 모두에서 나는 수행할 수 있는 한 최대로 검증된 실험을 진행했다. 첫 번째 결함의 경우 테스트는 소프트웨어가 회귀하는 것을 방지하고, 스스로에게는 자신감을 심어주었으며, 미래에 개발할 작업들을 보완해 준다. 두 번째 결함의 경우 테스트를 작성하지 않았으므로, 새로운 기능을 개발할 시간을 벌어 주었다.

 

쉬운 정답은 없다

Max를 개발하기 시작했을 때 첫 한달 동안 나는 어떤 자동화된 테스트도 작성하지 않았다. 나는 모든 테스트를 수작업으로 진행했다. 몇 명의 초기 후원자가 나타난 후에야, 나는 이전 코드로 돌아가서 기존의 기능들에 대한 테스트를 작성했다. 이 경우도 마찬가지로, 나는 이러한 순서로 개발함으로써 단위 시간에 수행할 수 있는 검증된 실험들을 최대한으로 할 수 있었다고 믿는다. 코드가 없거나 적은 경우, 테스트를 작성하지 않으면 더 빠르게 시작할 수 있다(실제로 첫 테스트를 작성할 때 거의 일주일이나 걸렸다). 작성한 초기 코드가 나중에 유용하다는 판단이 들면(내 친구들 중 몇몇이 소프트웨어를 산다는 기준으로), 테스트를 만들어서 코드에 대해 빠르게 실험하고, 자신감을 얻을 수 있다.

 

자동화된 테스트를 작성하느냐 마느냐를 결정할 때 다양한 요소 사이에서 균형을 이뤄야 한다. 심지어 Max를 만들 때조차도 상당수의 테스트를 작성했다. 만약 테스트를 작성할 수 있는 값싼 방법이 있다면, 나는 모든 기능에 대해 인수 테스트를 먼저 작성했다. 특히 기능을 어떻게 구현할지 마땅한 방법이 떠오르지 않을 경우, 테스트를 작성함으로써 훌륭한 아이디어를 얻을 수 있었다. 반면 Max를 개발할 때 테스트를 작성하느냐 마느냐를 결정하는 기준은 테스트가 단위 시간에 더 많은 실험들을 검증할 수 있도록 돕느냐가 핵심이다. 돕는다면 테스트를 작성한다. 그렇지 않을 경우, 위험을 감수한다. 나는 Max가 순조롭게 출발할 수 있을 정도의 수입을 얻을 수 있는 기회를 최대화하려고 노력한다. 설계에 투자해야 하는지와 관련한 추론도 이와 비슷하게 복잡한데, 이 주제 역시도 다음 글에서 다루고자 한다.

 

언젠가는 Max도 긴 게임의 프로젝트가 될 것이고, 범위도 명확해지며, 오랫동안 지속할 수 있는 비용을 벌어들일 것이다. 유연성을 유지하면서 동시에 비용을 줄이는 것이 새로운 목표로 자리매김할 것이다. 테스트를 작성하는데 들인 시간들도 보상받게 될 것이다. 하지만 그때가 되기 전에는 나는 짧은 게임을 하고 있다는 사실을 잊지 말아야 한다.

설정

트랙백

댓글