소프트웨어 업계에서 근무한 지 얼마 되지 않았을 무렵엔 개별적으론 잘 동작하던 모듈도 한데 모으면, 도대체가 이해하기조차 어려운 형태로 모든 게 엉망이 되어 버리곤 했습니다. 하지만 지난 몇 년간, 통합은 프로젝트에서 가장 고생스러운 일에서 별 것 아닌 일로 축소되었습니다.
이렇게 된 가장 근본적인 원인은 좀더 자주 통합하는 실천 방법입니다. 한때는 매일 빌드하는 것을 야심 찬 목표로 생각한 적도 있었습니다. 지금 이야기하는 대부분의 프로젝트들은 하루에도 여러 차례 통합을 합니다. 참 이상하게도, 고생스러울수록 좀더 자주하는 것이 상책인 듯합니다.
지속적인 통합에 있어 흥미로운 것 중 하나는 지속적인 통합이 주는 효과에 사람들이 종종 놀란다는 겁니다. 우리는 사람들이 지속적인 통합의 효과를 별로 중요하지 않은 이점으로 치부해버리는 모습을 발견합니다. 하지만 지속적인 통합은 프로젝트에 완전히 다른 분위기를 불러일으킬 수 있습니다. 문제를 더 빨리 탐지해내기 때문에 가시성이 훨씬 좋아집니다. 잘못을 저지르고 그것을 발견해내는 간격이 줄기 때문에, 뭐가 변경됐는지 쉽게 살펴볼 수 있어서 원인을 찾아내는 데 도움이 되므로 결함을 찾아내기 더 쉽습니다. 이것이 테스트 프로그램과 결합하면, 버그를 획기적으로 줄일 수 있습니다. 그 결과, 개발자는 디버깅하는 데 시간을 덜 쓰고 기능을 넣는 데 시간을 더 쓰게 되며, 견고한 기초를 닦고 있다는 자신감을 갖게 됩니다.
물론, 통합을 더 자주하라고 말로만 해선 충분하지 않습니다. 이 간단한 캐치프레이즈 뒤에는 지속적인 통합을 현실로 만들어 주는 원칙과 실천 방법이 한 다발 있습니다. 원칙과 실천 방법에 관한 조언들은 대부분 여러 책과 인터넷에 흩어져 있었기 때문에 스스로 찾아서 탐구해야 했습니다.
그래서 폴이 이러한 정보들과 최고의 실천 방법들을 응집력 있는 한 권의 책으로 묶어서 이러한 책을 기다렸던 사람들에게 지침서를 만들어준 걸 보고 기뻤습니다. 간단한 실천 방법이 으레 그렇듯, 세세한 부분으로 들어가면 어려워집니다. 지난 몇 해에 걸쳐 우리는 그 같은 세부 사항에 대해 많은 것을 연구했고 어찌 대처하면 되는지를 공부했습니다. 이 책은 지속적인 통합이 소프트웨어 개발에 탄탄한 기초를 제공하듯, 지속적인 통합을 위한 탄탄한 기초를 마련해주는 이러한 교훈들을 모아 놓았습니다. --- '본문' 중에서
여러분이 프로젝트에 공을 들인 지 1년이 넘었다. 드디어, 모든 기능들이 실제로 완성된 것처럼 보이고, 대부분의 기능들을 위한 단위 테스트도 있다. 안도의 한숨을 쉬어도 좋다. 일은 끝났다.
정말 그럴까?
'기능이 완성되었다는 것'이 '제품을 출시할 준비가 되었음'을 뜻할까? 여러분의 시스템은 정말로 배치될 준비가 됐는가? 여러분이 없더라도, 시스템은 운영요원에 의해 잘 돌아가고 실제 사용자들과 부딪히는데 문제가 없겠는가? 한밤중에 비상 전화나 호출기가 울린다면 수렁에 빠지는 기분이 들지 않을까? 결국 지금까지 구현된 모든 기능보다 앞으로 개발할 것이 훨씬 많다는 사실을 알게 된다.
너무나 자주, 프로젝트 팀은 실전에서 (정말로 원활한) 운영을 목표로 삼는 대신, QA 테스트 통과를 목표로 삼는다. 즉, 여러분이 하는 많은 일들은 십중팔구 테스트 통과에 초점을 맞춘다. 그러나 테스트만으로(애자일 테스트, 실용주의 테스트, 자동화된 테스트일지라도) 소프트웨어가 실제 세상에 나갈 준비가 되었다는 것을 증명하는 데는 충분하지 않다. 유별난 실제 사용자, 엄청난 트래픽, 들어보지도 못한 나라의 바이러스를 만드는 일당으로 가득한 실제 세상의 스트레스와 스트레인(strain)은, 우리가 테스트의 대상으로 삼았던 것들을 훌쩍 뛰어넘는다.
여러분의 소프트웨어가 실제 세상의 가혹한 현실에 맞설 준비가 되었는지 확인해야 한다. 이 책의 목적은 이러한 문제들이 어디에 있는지, 문제들을 극복하려면 무엇이 필요한지 보여주는 데 있다. 그러나 시작하기 전에, 널리 알려진 몇 가지 오해에 대해 얘기해 보자.
우선, 온갖 노력을 다해 계획했어도, 나쁜 일들은 여전히 생긴다는 사실을 받아들여야 한다. 물론 가능하다면 나쁜 일을 예방하는 것이 현명하다. 그러나 가능한 모든 나쁜 사건들을 예측하여 제거했다고 가정하는 것은 너무나 치명적이다. 대신에, 여러분은 가능한 조치를 취하고 예방할 수 있기를 바라야 하지만, 예상치 못한 심각한 트라우마가 시스템에 생기더라도 전체 시스템이 복구될 수 있다고 확신해야 한다.
둘째로, '릴리스 1.0(Release 1.0)'은 개발 프로젝트의 끝이 아니라 시스템의 삶이 시작되는 것임을 깨달아야 한다. 이런 상황은 부모가 다 자란 자녀를 처음으로 떠나 보내는 것과 비슷하다. ?러분은 성인 자녀가 돌아와 여러분과 함께 지내길 바라지 않을 것이다. 더구나 배우자, 손자 네 명, 개 두 마리 그리고 애완용 앵무새와 함께라면 말이다.
이처럼, 개발하는 동안 여러분이 내리는 설계 결정은 릴리스 1.0 이후에 펼쳐질 여러분 삶의 질에 큰 영향을 미칠 것이다. 실전 환경에 맞도록 시스템을 설계하는 데 실패한다면, 릴리스 이후 여러분의 삶은 '흥분'으로 채워질 것이다. 물론 좋은 의미의 흥분이 아니다. 이 책에서, 중요한 설계 트레이드오프(trade-off)를 살펴보고, 어떻게 영리하게 설계 트레이드오프를 결정하는지 알게 될 것이다.
그리고 마지막으로, 기술에 대한 우리들의 공동체적인 애착과 멋진 신기술, 근사한 시스템에도 불구하고, 여러분은 결국 이러한 기술들이 전혀 중요하지 않다는 사실과 마주쳐야 한다. 우리에게 일용할 양식을 주는 세계, 즉 비즈니스 세상에서 모든 것은 돈으로 귀착되기 때문이다. 시스템은 비용을 지출한다. 이 비용을 만회하기 위해 시스템은 직접적인 수익이나 비용을 절약하는 방법으로 돈을 벌어야 한다. 추가 작업은 비용을 지출하며 서비스 중단을 일으킨다. 자금과 운영 비용을 높이기 때문에 비효율적인 코드는 많은 돈을 지출케 한다. 여러분은 운영되고 있는 시스템을 이해하기 위해 이런 비용을 추적해야 한다. 그리고 여러분은 사업을 유지하기 위해 돈을 벌어야 한다. 아니면 적어도 잃지는 말아야 한다.
나는 이 책이 변화를 만들어서 여러분과 여러분의 조직이 거대한 손실과 일반적으로 엔터프라이즈 소프트웨어의 특성으로 표현되는 돈 낭비를 피하는 것을 도울 수 있기를 바란다.
--- '본문' 중에서