지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

98

Post on 22-Jul-2016

232 views

Category:

Documents


1 download

DESCRIPTION

폴 M. 듀발, 스티븐 M. 마티야스, 앤드류 글로버 지음 | 최재훈 옮김 | IT Leaders 시리즈 _ 005 | ISBN: 9788992939133 | 22,000원 | 2008년 03월 27일 발행 | 324쪽

TRANSCRIPT

Page 1: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기
Page 2: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

P {[ }

] |\

“‘ Integrate

?/

Shift

폴 M. 듀발

스티브 M. 마티야스

앤드류 글로버

최재훈

지속적인

통합소프트웨어

품질을

높이고

위험을

줄이기

Page 3: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

지속적인 통합소프트웨어 품질을 높이고 위험을 줄이기

Page 4: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

iv

목 차

역자서문 xii

마틴 파울러의 머릿말 xvi

폴 줄리어스의 머릿말 xviii

서문 xxi

PART I 지속적 통합의 배경: 원칙과 실천 방법

chapter1 시작하기 3

변경할 때마다 소프트웨어를 빌드하기 4

개발자 6

버전 관리 저장소 7

지속적인 통합 서버 8

빌드 스크립트 10

피드백 메커니즘 10

통합 빌드 머신 12

지속적인 통합의 특징 12

소스 코드 컴파일 12

데이터베이스 통합 14

테스트 15

검사 (Inspection) 17

배포 18

문서화와 피드백 20

요약 21

질문 21

P {[ }

] |\

“‘ Integrate

?/

Shift

Page 5: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

v

chapter2 지속적인 통합 도입하기 23

지속적인 통합과 함께 하는 하루 일과 25

지속적인 통합에는 어떤 가치가 있을까요? 29

위험을 줄여줍니다 29

반복적인 프로세스를 줄여줍니다 30

배포할 수 있는 소프트웨어를 생성합니다 31

프로젝트 가시성을 더 높입니다 31

제품에 대해 보다 큰 자신감을 갖게 됩니다 32

지속적인 통합을 왜 도입하지 못할까요? 32

'지속적인' 통합을 도입하려면 어떻게 해야 할까요? 33

언제, 어떻게 프로젝트에 지속적인 통합을 도입해야 할까요? 35

통합의 진화 36

지속적인 통합은 다른 개발 실천 방법을 어떻게 보완할까요? 37

지속적인 통합을 수립하려면 얼마나 걸릴까요? 38

지속적인 통합과 나 39

코드를 자주 커밋하세요 39

깨진 코드를 커밋해선 안 됩니다 41

빌드가 깨지면 즉시 고치세요 41

자동화된 개발자 테스트를 작성하세요 41

테스트와 검사는 모두 통과해야 합니다 42

개인 빌드를 돌리세요 42

깨진 코드는 가져오지 마세요 43

요약 44

질문 45

P {[ }

] |\

“‘ Integrate

?/

Shift

Page 6: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

vi

chapter3 지속적인 통합을 이용해 위험 줄이기 47

위험 요소: 배포 가능한 소프트웨어의 부재 49

시나리오: “내 컴퓨터에선 되는데요” 50

시나리오: 데이터베이스와 동기화하기 50

시나리오: 버튼을 안 눌렀어요 52

위험 요소: 뒤늦은 결함 발견 53

시나리오: 회귀 테스트 53

시나리오: 테스트 적용범위 (Test Coverage, 테스트 커버리지) 54

위험 요소: 프로젝트 가시성의 부재 55

시나리오: “제가 남긴 메모 보셨나요?” 56

시나리오: 소프트웨어를 시각화할 역량의 부재 56

위험 요소: 저품질의 소프트웨어 57

시나리오: 코딩 표준 준수 58

시나리오: 설계 지침 준수 59

시나리오: 중복 코드 60

요약 62

질문 62

chapter4 변경될 때마다 소프웨어를 빌드하기 65

빌드를 자동화하기 67

명령어 하나로 빌드를 수행하기 69

IDE에서 빌드 스크립트를 분리해내기 73

소프트웨어 자산을 중앙 집중화하기 74

일관성 있는 디렉터리 구조를 만들기 76

빌드를 빨리 실패하게 만들기 77

어떤 환경에서라도 빌드하기 77

P {[ }

] |\

“‘ Integrate

?/

Shift

P {[ }

] |\

“‘ Integrate

?/

Shift

Page 7: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

vii

빌드 유형과 메커니즘 78

빌드 유형 78

빌드 메커니즘 80

빌드 시작시키기 81

전용 통합 빌드 머신을 사용하기 81

지속적인 통합 서버를 사용하기 83

사람이 직접 통합 빌드를 돌리기 86

빌드 시간을 짧게 만들기 87

빌드 메트릭 수집하기 88

빌드 메트릭 분석하기 89

개선 방안을 고르고 실행하기 89

빌드를 여러 단계로 나누기 92

다시 평가하기 96

이런 게 과연 효과가 있을까요? 96

요약 101

질문 103

PART II 완전한 기능을 갖춘 지속적인 시스템 만들기

chapter5 지속적인 데이터베이스 통합 107

데이터베이스 통합을 자동화하기 110

데이터베이스 만들기 112

데이터베이스 조작하기 115

빌드 데이터베이스 편성 스크립트 만들기 116

로컬 데이터베이스 샌드박스를 사용하기 117

버전 관리 저장소를 사용해서 데이터베이스 자산을 공유하기 119

지속적인 데이터베이스 통합 122

P {[ }

] |\

“‘ Integrate

?/

Shift

Page 8: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

viii

개발자에게 데이터베이스를 수정할 권한을 주기 123

팀이 다 함께 깨진 빌드를 고치는 일에 집중하기 124

DBA를 개발 팀의 일원으로 만들기 124

데이터베이스 통합과 통합 버튼 125

테스트 125

검사 125

배포 126

피드백과 문서화 126

요약 126

질문 128

chapter6 지속적인 테스트 129

단위 테스트 자동화하기 132

컴포넌트 테스트 자동화하기 134

시스템 테스트 자동화하기 136

기능 테스트 자동화하기 137

개발자 테스트를 여러 범주로 나누기 138

시간이 덜 걸리는 테스트부터 실행하기 140

단위 테스트 141

컴포넌트 테스트 141

시스템 테스트 143

결함 검사용 테스트 작성하기 143

컴포넌트 테스트를 반복할 수 있게 만들기 148

테스트 케이스 하나에 어썰트(assert) 하나로 제한하기 156

요약 159

질문 160

P {[ }

] |\

“‘ Integrate

?/

Shift

Page 9: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

ix

chapter7 지속적인 검사 161

검사와 테스트는 무엇이 다를까요? 164

검사기를 얼마나 자주 돌려야 할까요? 165

코드 메트릭: 그 역사 166

코드 복잡도를 줄이기 167

설계 검토를 지속적으로 수행하기 170

코드 심사(Audit)를 하여 조직에서 정한 표준을 잘 지키게 하기 173

중복 코드를 줄이기 176

PMD-CPD 사용하기 177

Simian 사용하기 178

코드 적용범위를 평가하기 180

코드 품질을 지속적으로 평가하기 182

적용범위 테스트 수행 빈도 183

적용범위 테스트와 성능 185

요약 186

질문 187

chapter8 지속적인 배포 189

작동하는 소프트웨어를 언제, 어느 곳에서든 릴리즈하기 191

저장소 안의 자산에 꼬리표 붙이기 191

깨끗한 환경 만들기 194

각 빌드에 꼬리표 붙이기 195

테스트를 모두 돌리기 196

빌드 피드백 보고서 만들기 196

릴리즈를 롤백할 수 있는 능력 확보하기 199

P {[ }

] |\

“‘ Integrate

?/

Shift

P {[ }

] |\

“‘ Integrate

?/

Shift

Page 10: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

x

요약 200

질문 202

chapter9 지속적인 피드백 203

적절하게 205

적절한 정보 205

적절한 사람 207

적절한 시기 208

적절한 방법 209

지속적인 피드백 메커니즘 사용하기 209

이메일 210

SMS (문자 메시지) 212

앰비언트 오브와 X10 디바이스 214

윈도우 작업 표시줄 217

소리 218

와이드 스크린 모니터 220

요약 222

질문 222

epilogue 지속적인 통합의 미래 223

appendixA CI 관련 리소스 227

지속적인 통합 도구와 제품 229

빌드 스크립트 리소스 232

버전 관리 리소스 233

데이터베이스 리소스 234

테스트 리소스 236

자동화된 검사 리소스 239

P {[ }

] |\

“‘ Integrate

?/

Shift

P {[ }

] |\

“‘ Integrate

?/

Shift

P {[ }

] |\

“‘ Integrate

?/

Shift

Page 11: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

xi

배포 리소스 242

피드백 리소스 242

문서화 리소스 243

appendixB CI 도구 평가하기 245

도구를 평가할 때 고려할 점 247

기능성 248

내가 일하는 환경과의 호환성 253

안정성 254

수명 254

사용자 편의성 255

자동화된 빌드 도구 255

Ant 256

Maven 1 256

Maven 2 259

NAnt 261

Rake 262

빌드 스케줄러 도구 263

AnthillPro 264

Continuum 266

CruiseControl 266

CruiseControl.NET 268

Draco.NET 269

Luntbuild 271

결론 272

bibliography 참고 문헌 273

index 찾아보기 276

P {[ }

] |\

“‘ Integrate

?/

Shift

P {[ }

] |\

“‘ Integrate

?/

Shift

P {[ }

] |\

“‘ Integrate

?/

Shift

Page 12: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

xii

역 자 서 문

아침 일찍 출근하고 컴퓨터를 켠다. 윈도우 로고가 뜨는 사이, 가방 정리를 하고 컵

을 씻고 홍차를 준비한다. 그러다 윈도우 로그인 창이 뜨면 암호를 입력한다. 윈도

우 바탕화면이 뜨고 웹 브라우저를 연다. 차 한 모금을 입 안에 담고, 느긋하게 RSS

구독기를 통해 어제 밤 사이에 올라온 글을 읽는다.

뭔가 이상하지 않습니까? 다시 해볼까요?

암호를 입력한다. 윈도우 바탕화면이 뜨면, IDE를 실행시키고 소스 코드를 열심

히 살펴본다.

그래도 여전히 뭔가 이상한데요? 어떤 사람은 출근해서 웹툰부터 볼지도 모릅니

다. 너무 오래 만화 감상에 열중하지 않는다면, 만화를 보며 긴장을 풀어도 좋겠지

요. 하지만 여기서는 딱딱하게 ‘회사에선 일만 해라’ 라고 말하려는 게 아닙니다. 게

임 개발사에선 ‘게임을 즐기는 것조차 일’이라고 하더군요. 그런 면에선 저는 직무

유기를 한다는 소리를 들어야 할지도 모르겠습니다. 그렇다면 처음 제시한 시나리

오가 왜 이상하다는 걸까요? 한 번만 더 해보겠습니다.

암호를 입력한다. 시작 프로그램들이 뜬다. 윈도우 작업 표시줄에 CCTray 트레이

아이콘이 뜨더니, 이내 반가운 녹색 불빛이 들어온다. ‘아, 오늘 아침도 프로젝트는

안녕한가 보구나’. 안심하고 마음 편히 ‘마음의 소리’(웹툰)을 보러 간다.

CCTray는 CruiseControl .NET이라는 빌드 자동화 서버와 통신하고, 빌드가 깨지

지 않았는지, 테스트가 실패하지 않았는지 알려줍니다. 녹색 불빛은 ‘걱정하지 말라’

는 표시입니다. 아침에 출근해서 손수 소스 코드를 빌드해보지 않아도, 프로젝트가

잘 돌아가는지 알게 해주니 참 고마운 도구입니다.

생각해보세요. 여러분은 아침에 출근하면서, 전날에 밤을 샜다면 낮에 출근하면

서 이런 생각해본 적 없습니까? ‘오늘은 제발 프로그램을 띄워보기라도 하자’. 컴파

일은 어떻게든 되는데, 막상 돌려보면 어찌된 영문인지 이상한 행동만 보이고, 뭐가

Page 13: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

xiii

문제인지 알고 보면 한 달 전에 겪었던 문제이고, 끝이 없습니다. 회사 갈 생각만 해

도 머리가 지끈거리니 참 큰일입니다.

이 책은 두통거리를 제대로 다루는 방법에 대해 말합니다. CCTray만 봐도 안심하

고 일할 수 있는 그런 환경을 만드는 법을 알려줍니다.

사실 역자 서문이란 게 그리 흥미로운 대목은 아닙니다. 독자들이 알고 싶어하는

내용은 전부 저자들이 설명해놨고, 역자가 할 일이라곤 그저 이 책이 얼마나 훌륭한

지, 왜 이 책을 읽어야 하는지 간단히 설명하는 정도일 뿐이죠. 그러니 이쯤에서 마

침표를 찍겠습니다. 앞서 제시한 시나리오만으로도 명석한 여러분은 이 책이 왜 쓸

모 있는지, 이 책에서 무엇을 배우게 될지 알았을 겁니다.

그럼, 즐거운 시간이 되시길 바랍니다.

2008년 3월 어느 날,

역자 최재훈.

Page 14: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

xiv

폴 M. 듀발 ㅣ Paul M. Duvall

폴 M. 듀발은 컨설팅 회사인 Stelligent 사의 CTO이자, 소프트웨어 생산을 최적화함

으로써 개발 팀이 안정적이고 신속하게 더 나은 소프트웨어를 만들도록 돕는 사고

리더입니다. 그는 개발자와 테스터에서부터 아키텍트와 프로젝트 관리자에 이르기

까지, 소프트웨어 개발 프로젝트의 사실상 모든 역할을 다 맡아봤습니다. 폴은 금융,

주택, 정부, 보건, 그리고 큰 규모의 독립적 소프트웨어 벤더를 비롯해 다양한 산업

분야에서 고객들에게 컨설팅을 해왔습니다. 그는 여러 앞서가는 소프트웨어 컨퍼런

스에서 대표 연설자를 맡고 있습니다. 그는 IBM developerWorks에 사람을 위한 자

동화(Automation for the People) 시리즈를 썼고,『NFJS 2007 Anthology』(실용주의 프로그래

머, 2007)의 공저자이며,『UML 2 Toolkit』(Wiley, 2003)의 공헌 저자이기도 합니다.

폴은 특허 신청을 해놓은 의료 연구 데이터 관리 시스템의 공동 발명가입니다. 그는

www.testearly.com와 www.integratebutton.com에서 열심히 블로깅을 합니다.

스티브 M. 마티야스 3세 ㅣ Stephen M. Matyas III

스티브 M. 마티야스 3세는 5AM Solutions 사의 서비스 부분인 AutomateIt의 부사

장인데, 이 회사는 조직이 자동화를 통해 소프트웨어 개발을 개선하도록 돕습니다.

스티브는 응용 소프트웨어 공학에서 다양한 배경을 갖고 있으며, 민간 기업과 정부

고객 모두를 경험해보았습니다. 스티브는 아주 다양한 역할을 수행해왔는데, 비즈

니스 분석가와 프로젝트 관리자부터 개발자, 설계자 및 아키텍트까지 경험해봤습

니다. 그는『UML 2 Toolkit』(Wiley, 2003)의 공헌 저자입니다. 스티브는 애자일과

Rational Unified Process(RUP)를 비롯해 다양한 반복적이고 점진적인 방법론을 실천

하는 사람입니다. 그는 방법론과 소프트웨어 품질, 그리고 프로세스 개선에 있어 특

화를 해야 하는 자바/J2EE 사용자 주문 소프트웨어 개발 및 서비스 산업에서 풍부

한 실무 경험을 가지고 있습니다. 스티브는 Virginia Polytechnic Institute and State

University(버지니아 공대)에서 컴퓨터 과학 분야의 학사 학위를 획득했습니다

저 자 · 역 자 소 개

Page 15: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

xv

앤드류 글로버 ㅣ Andrew Glover

앤드류 글로버는 컨설팅 회사인 Stelligent 사의 사장이자, 소프트웨어 생산을 최

적화함으로써 개발 팀이 안정적이고 신속하게 더 나은 소프트웨어를 만들 수 있도

록 돕는 사고 리더입니다. 앤디는 북 아메리카에서 벌어지는 다양한 컨퍼런스에

서 자주 연사로 활동하며 No Fluff Just Stuff 소프트웨어 심포지움 그룹에서도 연설

을 맡습니다. 그리고 앤디는『Groovy in Action』(Manning, 2007),『Java Testing

Patterns』 (Wiley, 2004),『NFJS 2006 Anthology』(Pragmatic Programmers, 2006)의

공동 저자입니다. 그는 IBM의 developerWorks와 오라일리의 ONJava, ONLamp,

Dev2Dev 등 다양한 온라인 출판물의 저자이기도 합니다. 또 www.thediscoblog.

com와 www.testearly.com에서 소프트웨어 품질에 대해 열심히 블로깅을 합니다.

최재훈 http://kaistizen.net, [email protected]

게임 개발을 업으로 삼는 프로그래머다. 게임 개발에 있어선 이제 막 반년이 지난

초보이지만, 흥미롭고 생소한 기술을 많이 접하고, 익숙하진 않지만 독특한 분위기

를 누리느라 항상 즐겁다.

여전히 스타크래프트는 무한맵에서 하고, 올해에 나올 게임 기대작으론 스포어

(Spore)를 손에 꼽는다. 게임 개발자답지 않게 평소엔 게임을 즐겨 하지 않지만, 기

대작이 나오면 다른 일은 제쳐놓고 삼매경에 빠진다. 유머 사이트에 떠도는, ‘슈퍼

로봇대전 OGS’의 엔딩을 보고 싶다고 적은 휴가 계획서를 보고 그 용기가 멋지다고

생각하는 사람이다.

락 밴드는 U2가 최고라 생각하고, 15년째 ‘배철수의 음악 캠프’를 들은 애청자이다.

『Ship it! 성공적인 소프트웨어 개발 프로젝트를 위한 실용 가이드』에 이어 이번이

두 번째 역서이다. 번역을 마치고 몇 번이나 검토를 해도, 여전히 고칠 부분이 많아

부끄럽다. 그저 전작 때보단 좀더 제대로 번역했다는 소리를 듣고 싶다.

Page 16: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

xvi

소프트웨어 업계에서 근무한 지 얼마 되지 않았을 무렵엔 개별적으론 잘 동작하던

모듈도 한데 모으면, 도대체가 이해하기조차 어려운 형태로 모든 게 엉망이 되어 버

리곤 했습니다. 하지만 지난 몇 년간, 통합은 프로젝트에서 가장 고생스러운 일에서

별 것 아닌 일로 축소되었습니다.

이렇게 된 가장 근본적인 원인은 좀더 자주 통합하는 실천 방법입니다. 한때는 매

일 빌드하는 것을 야심찬 목표로 생각한 적도 있었습니다. 지금 이야기하는 대부분

의 프로젝트들은 하루에도 여러 차례 통합을 합니다. 참 이상하게도, 고생스러울수

록 좀더 자주하는 것이 상책인 듯합니다.

지속적인 통합에 있어 흥미로운 점 중 하나는 지속적인 통합이 주는 효과에 사람

들이 종종 놀란다는 사실입니다. 우리는 사람들이 지속적인 통합의 효과를 별로 중

요하지 않은 이점으로 치부해버리는 모습을 발견합니다. 하지만 지속적인 통합은

프로젝트에 완전히 다른 분위기를 불러일으킬 수 있습니다. 문제를 더 빨리 탐지해

내기 때문에 가시성이 훨씬 좋아집니다. 잘못을 저지르고 그것을 발견해내는 간격

이 줄기 때문에, 뭐가 변경됐는지 쉽게 살펴볼 수 있어서 원인을 찾아내는 데 도움

이 되므로 결함을 찾아내기 더 쉽습니다. 이것이 테스트 프로그램과 결합하면, 버그

를 획기적으로 줄일 수 있습니다. 그 결과, 개발자는 디버깅하는 데 시간을 덜 쓰고

기능을 넣는 데 시간을 더 쓰게 되며, 견고한 기초를 닦고 있다는 자신감을 갖게 됩

니다.

물론, 통합을 더 자주하라고 말로만 해선 충분하지 않습니다. 이 간단한 캐치 프

레이즈 뒤에는 지속적인 통합을 현실로 만들어 주는 원칙과 실천 방법이 한 다발 있

습니다. 원칙과 실천 방법에 관한 조언들은 대부분 여러 책과 인터넷에 흩어져 있었

기 때문에 스스로 찾아서 탐구해야 했습니다.

마 틴 파 울 러 1 ) 의 머 릿 말

1) 마틴 파울러는 마틴 파울러 시리즈의 편집자이며, ThoughtWorks 사의 선임 과학자입니다.

Page 17: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

xvii

그래서 폴이 이러한 정보들과 최고의 실천 방법들을 응집력 있는 한 권의 책으로

묶어서 이러한 책을 기다렸던 사람들에게 지침서를 만들어준 걸 보고 기뻤습니다.

간단한 실천 방법이 으레 그렇듯, 세세한 부분으로 들어가면 어려워집니다. 지난 몇

해에 걸쳐 우리는 그 같은 세부 사항에 대해 많이 연구했고 어찌 대처하면 되는지를

공부했습니다. 이 책은 지속적인 통합이 소프트웨어 개발에 탄탄한 기초를 제공하듯,

지속적인 통합을 위한 탄탄한 기초를 마련해주는 교훈들을 모아놓았습니다.

Page 18: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

xviii

누군가 하루 속히 이런 책을 써주길 바라왔습니다. 이런 책을 쓰게 될 사람이 제가

되길 남몰래 바라왔지요. 하지만 폴, 스티브, 그리고 앤드가 마침내 모든 것을 한데

묶어 응집력 있고 사려 깊은 전문 서적으로 만들어내서 기쁩니다.

저는 영원처럼 느껴질 정도로 오랜 세월 지속적인 통합에 푹 빠져 지내왔습니다.

2001년 3월에 CruiseControl 오픈소스 프로젝트를 공동 설립하고 관리자로 일하기

시작했습니다. 낮에는 ThoughtWorks 사에서 컨설팅 업무를 맡아 고객이 지속적인

통합의 원칙과 도구를 활용하여, 테스트 솔루션을 구조화하고 빌드하며 배포하는

일을 도왔습니다.

CruiseControl 메일링 리스트에서의 활동은 2003년에야 시작됐습니다. 수천 가지

의 서로 다른 지속적인 통합 시나리오에 대한 글을 읽을 기회가 있었습니다. 소프

트웨어 개발자들이 겪는 문제는 다양하고 복잡했습니다. 개발자들이 이러한 작업

에 달려드는 이유가 점점 명확해지고 분명해졌습니다. (빠른 피드백, 빠른 배포, 그

리고 반복 가능한 자동화된 테스트 같은) 지속적인 통합의 장점은 그 복잡함을 훨씬

웃돌았습니다. 하지만 이런 종류의 환경을 만들 땐 목표를 잘못 겨냥하기 쉽습니다.

그리고 제가 처음 CruiseControl을 출시할 때는 사람들이 자신의 소프트웨어 개발

프로세스를 개선하기 위해, 지속적인 통합을 이토록 흥미로운 방식으로 쓸 줄은 몰

랐습니다.

2000년, 저는 대규모 J2EE 애플리케이션 개발 프로젝트에 참가했는데 명세가 제

공하는 모든 기능을 사용했습니다. 애플리케이션은 그 자체로 훌륭했지만, 빌드하

기가 힘들었습니다. 이때 빌드라 함은 컴파일하고, 테스트하고, 자바 아카이브를 생

성하며 기능 테스트를 수행하는 과정을 말합니다. Ant는 아직 초기 단계였고 자바

애플리케이션을 위한 사실상의 표준이 되기 전이었습니다. 우리는 섬세하게 조정한

일련의 셸 스크립트를 이용해 모든 걸 컴파일하고 단위 테스트를 돌렸습니다. 또 다

른 일련의 셸 스크립트로는 모든 걸 묶어서 배포 가능한 아카이브로 묶어냈습니다.

결국, JAR 파일을 배포하고 기능 테스트 수트를 실행시키려면 하나하나 직접 해나

폴 줄 리 어 스 의 머 릿 말

Page 19: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

xix

갈 수밖에 없었습니다. 말할 것도 없이, 이러한 과정은 인내를 요하고 지루하기 때

문에 실수가 따르기 마련이었습니다.

그래서 ‘버튼 하나’만 누르면 재현 가능한 ‘빌드’를 만들어주는 뭔가를 만들려는 저

의 모험이 시작됐습니다(그 당시에 마틴 파울러의 이야깃거리 중 하나였습니다).

Ant가 교차 플랫폼 빌드 스크립트를 만드는 문제는 해결해줬습니다. 남은 부분은

배포, 기능 테스트, 결과 보고하기 같은 지루한 단계를 다뤄 줄 무엇이었습니다. 당

시에 저는 기존 솔루션을 조사했지만 쓸 만한 게 없었습니다. 그 프로젝트에 적용하

고픈 방식대로 모든 게 작동하는 걸 찾을 수 없었습니다. 그 애플리케이션은 성공적

으로 개발을 마치고 실제 환경으로 넘겨졌지만, 저는 그 일들을 좀더 잘 할 수 있었

다는 걸 알았습니다.

그 프로젝트가 끝나고 다음 프로젝트가 시작되기 전, 바로 그 사이에 저는 해답을

찾았습니다. 마틴 파울러와 매트 포멜Matt Foemmel이 지속적인 통합에 관한 세미나 기

사를 때마침 발표했던 겁니다. 운 좋게도, 저는 파울러와 포멜이 제시한 시스템을

재사용할 수 있는 솔루션으로 만들어내는 일을 하는 ThoughtWorks 사의 직원 몇

명과 함께 일하게 됐습니다. 과장하지 않더라도 저는 무척 흥분했습니다! 지난 프로

젝트 때부터 해온 기도에 대한 대답이란 걸 알았던 거지요. 몇 주 만에 우리는 모든

준비를 마치고 우리가 만든 새로운 시스템을 여러 프로젝트에 사용하기 시작했습니

다. CruiseControl의 베타 테스트 사이트를 방문해서 베타 버전을 대규모 프로젝트

에 설치해 보기도 했습니다. 그 직후 우리는 이 시스템을 오픈소스로 공개했습니다.

저의 경우엔, 이를 후회한 적이 한 번도 없었습니다.

ThoughtWorks 사의 컨설턴트로서, 저는 몇몇 매우 복잡한 엔터프라이즈 배포 아

키텍처 작업에 참여했습니다. 고객들은 광고가 약속한 이점을 대충 이해한 나머지

문제를 빨리 고칠 방법을 찾을 때가 많습니다. 어느 기술이라도, 기술이 기업을 쉽

게 변화시킬 수 있다는 잘못된 믿음이 조금씩은 있습니다. 만약 컨설팅을 해온 수년

간의 경험으로 배운 게 있다면, 보기만큼 쉬운 건 없다는 겁니다.

Page 20: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

xx

저는 고객들에게 지속적인 통합의 원칙들을 실용적으로 적용하는 법에 대해 즐겨

말합니다. 지속적인 통합의 이점을 진정으로 활용하려면 개발 ‘리듬’을 바꾸는 게 중

요하다고 강조하길 좋아합니다. 만약 개발자들이 한 달에 한 번만 체크인을 하고, 자

동화된 테스트에 주의를 기울이지 않거나, 깨진 빌드를 고쳐야 한다는 아무런 사회

적 책무가 없다면, 지속적인 통합의 혜택을 전부 거두기 위해 반드시 해결해야 할 큰

문제가 있는 겁니다.

그렇다고 이러한 실천 방법들이 정착되기 전까진 IT 관리자들이 지속적인 통합에

대해 잊어야 한다는 뜻일까요? 아닙니다. 사실, CI(지속적인 통합) 실천 방법들을

사용하는 것이야말로 변화를 향한 가장 빠른 동기부여 방법 중 하나가 될 수 있습니

다. 저는 CruiseControl 같은 지속적인 통합 도구를 설치하면 소프트웨어 팀이 고무

되어, 적극적인 정도를 넘어 미래를 내다보고 반응하게끔 된다는 걸 발견했습니다.

변화는 하룻밤 사이에 일어나지는 않습니다. 여러분은 자신의 기대를 적절하게 설

정해야 합니다. 끈기를 갖고 밑에 깔린 원칙들을 잘 이해한다면, 가장 복잡한 환경

일지라도 이해하기가 더 쉬워지고, 테스트하기가 더 쉬워지며, 빨리 생산하기도 더

쉬워질 수 있습니다.

저자들은 이 책으로 프로젝트 개발 현장을 다듬어 왔습니다. 저는 이 책이 포괄

적이면서 폭넓다는 걸 알게 됐습니다. 지속적인 통합의 가장 중요한 측면을 깊이 있

게 다루었기 때문에 독자들이 제대로 알고 결정을 내릴 수 있게 해줄 겁니다. 폭넓

은 범위의 주제는 오늘날 지속적인 통합의 광경을 지배하는 접근 방법들을 광범위

하게 다루며, 독자들이 결정해야 할 교환조건(tradeoff)을 저울질하는 데 도움이 될 겁

니다. 마지막으로 지속적인 통합 커뮤니티에서 여러 사람이 달성하려 그토록 노력

했던 작업이 더 나은 혁신을 위한 기초로써 형태를 갖추게 되어 매우 기쁩니다. 이

러한 이유로 저는 이 책을 지속적인 통합의 마술을 이용하여 대규모 애플리케이션

의 복잡함을 이해하는 데 있어 꼭 필요한 책으로 추천합니다.

Page 21: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

xxi

서 문

경력 초창기에 저는 한 잡지에서 엔터 키처럼 생기고 ‘통합하기Integrate’라 적힌 키보

드 키가 한 쪽 가득 그려진 광고를 보았습니다(그림 P-1을 보세요). 그 그림 아래에

는 “이렇게 쉽게 일이 풀려준다면,”이란 문구가 있었습니다. 누구를 위한 광고인지,

무엇을 위한 광고인지 확실하진 않지만, 마음에 와 닿았습니다. 소프트웨어 개발에

있어서 그런 일은 실현 가능성이 없다고 생각했습니다. 왜냐하면 제가 참여한 프로

젝트의 경우, 대부분의 프로젝트 일정표 끝 무렵에서 무수히 많은 소프트웨어 컴포

넌트를 꾸역꾸역 기워 맞추느라 며칠씩 ‘통합 지옥’을 헤매곤 했습니다. 하지만 전

그 개념이 좋았고, 그래서 광고를 잘라서 벽에 붙여놓았습니다. 제게 있어 그 광고

는 능력 있는 소프트웨어 개발자가 되고자 하면 달성해야 할 중요한 목표 중 하나

(반복가능하고 오류가 발생하기 쉬운 프로세스를 자동화하는)를 나타냈습니다. 게

다가 그 광고는 소프트웨어 통합을 ‘별 것 아닌 일’(nonevent, 마틴 파울러가 이렇게

불렀듯이)로 만들고자 하는 저의 믿음을 구체화시켰습니다–물론 그렇게 되었죠.

지속적인 통합(CI)은 통합을 별 것 아닌 일로 만드는 데 도움을 줄 수 있습니다.

그림 P-1 통합하기!

P {[ }

] |\

“‘ Integrate

?/

Shift

P {[ }

] |\

“‘ Integrate

?/

Shift

Page 22: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

xxii

무엇을 위한 책인가?

소프트웨어 프로젝트에서의 보다 전형적인 개발 프로세스를 한번 생각해봅시다. 코

드를 컴파일하고, 데이터베이스를 통해 코드를 정의하고 조작합니다. 테스트를 하고,

코드를 검토하고 최종적으론 소프트웨어를 배포합니다. 이와 더불어, 소프트웨어 상

태와 관련해서 여러 팀이 서로 의사소통 해야 할 필요성도 분명히 있을 겁니다. 버튼

하나만 눌러서 이런 모든 프로세스를 처리할 수 있다면 어떨지 상상해보세요.

이 책은 소프트웨어 개발 프로세스 상당수를 자동화하는 가상의 ‘통합’ 버튼을 어

떻게 만드는지 보여줍니다. 이뿐만 아니라, 우리는 이 ‘통합’ 버튼을 지속적으로 눌

러서, 배포 가능한 애플리케이션을 만드는 데 방해되는 뒤늦은 결함 발견과 저품질

의 코드와 같은 위험을 줄이는 방법을 보여줄 겁니다. CI 시스템을 만드는 과정에서,

이 같은 개발 프로세스 중 상당 부분이 자동화되며, 개발 중인 소프트웨어가 변경될

때마다 실행됩니다.

지속적인 통합은 무엇일까요?

소프트웨어를 통합하는 과정은 새삼스런 문제가 아닙니다. 소프트웨어 통합은 외부

시스템 의존성이 낮은 개인 프로젝트라면 그리 문제되지 않을지 모르지만, 프로젝

트의 복잡도가 증가하게 되면(단 한 명만 더 투입한다고 해도), 소프트웨어 컴포넌

트를 (초기에, 그리고 자주) 통합하고 이렇게 통합한 컴포넌트가 잘 작동하는지 확

인해야 합니다. 프로젝트 막판까지 통합을 미루면 온갖 종류의 소프트웨어 품질 문

제를 겪게 되는데, 이는 비용면에서 소모적일 뿐 아니라 프로젝트 지연으로 이어지

기도 합니다. 지속적인 통합은 이러한 위험을 보다 빨리, 그리고 점진적으로 해소해

줍니다.

마틴 파울러는 유명한 기사 “Continous Integration”1)에서 지속적인 통합을 이렇

게 묘사했습니다.

지속적인 통합은 팀 구성원들이 자신이 한 일을 자주 통합하는 소프트웨어 개발

실천 방법인데, 보통 각자 하루에 적어도 한 번 꼴로 통합합니다-결국 하루에 여러

1) www.martinfowler.com/articles/continuousIntegration.html를 참고하세요. 황상철씨의 번역글: http://moai.

tistory.com/224.

Page 23: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

xxiii

차례 통합하게 됩니다. 각 통합은 자동화된 빌드(테스트를 포함해서)가 검증하여

최대한 빨리 통합 오류를 탐지해냅니다. 이런 접근 방법을 사용하면 통합 문제를 상

당히 줄일 수 있고 응집력 있는 소프트웨어를 개발할 수 있다는 사실을 많은 팀이

알게 됐습니다.

저의 경험에 따르면, 이는 다음과 같은 의미가 있습니다.

개발자 모두가 버전 관리 저장소에 코드를 커밋해 넣기 전에 자신의 워크스테

이션에서 개인 빌드private build2)를 돌려서 자기가 변경한 내역이 통합 빌드를 깨

먹지 않는지 확인합니다.

개발자는 적어도 하루에 한 번 버전 관리 저장소에 코드를 커밋해 넣습니다.

통합 빌드가 빌드 컴퓨터 여러 대에서 하루에 예닐곱 번 정도 수행됩니다.

매 빌드마다 테스트를 100% 통과해야 합니다.

기능적인 면을 테스트할 수 있는 제품(예, WAR, 어셈블리, 실행 파일 등)을

생성해냅니다.

깨진 빌드를 고치는 일이 가장 우선순위가 높습니다.

개발자 몇몇은 빌드 과정에서 생성된 코딩 표준 및 의존성 분석 보고서 같은

보고서를 읽고 개선할 여지가 없는지 검토합니다.

계속 반복되고 오류가 발생하기 쉬운 프로세스를 자동화하면 여러 혜택을 볼 수 있

기 때문에 이 책은 지속적인 통합의 자동화된 측면을 논의합니다. 하지만 마틴 파울

러가 밝혔듯이, 지속적인 통합은 작업을 자주 통합하는 과정을 뜻하며, 자동화된 프

로세스만이 지속적인 통합의 자격이 있는 건 아닙니다. 지속적인 통합을 자동화된

프로세스로써 지원하는 훌륭한 도구가 많이 있으니, 지속적인 통합 서버를 사용해

서 CI 실천 방법을 자동화하는 게 효과적인 접근 방법이라고 우리는 확신합니다. 그

럼에도 불구하고, (자동화된 빌드를 활용해서) 사람이 직접 통합을 수행하는 접근

방법이 여러분의 팀에 잘 맞을 수도 있습니다.

2) 개인 (시스템) 빌드와 통합 빌드 패턴은 Stephen P. Berczuk 와 Brad Appleton가 쓴 『Software Configuration

Management Patterns』에서 다룹니다.

Page 24: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

xxiv

☆ 신속한 피드백

지속적인 통합을 사용하면 피드백을 받을 기회가 늘어납니다. 지속적인 통합을 수행하

면, 프로젝트의 상태에 대해 하루에도 여러 차례 배우게 됩니다. 지속적인 통합은 결함

이 발생하는 시점과 고쳐지는 시점의 간격을 줄이고, 그럼으로써 전체적인 소프트웨어

품질을 향상시키는 용도로 써도 됩니다.

개발 팀은 지속적인 통합 시스템이 자동화되었다고 해서 통합 문제로부터 안전할

거라 믿어선 안 됩니다. 개발 팀이 자동화된 도구를 소스 코드 컴파일 용도로만 사

용할지라도-어떤 이는 이를 두고 ‘빌드’라고 부르지만 사실은 그렇지 않습니다(1장

을 참고하세요)-이는 마찬가지입니다. CI를 효과적으로 실천하려면 도구 이상의 것

이 필요합니다.이 책에서 윤곽을 그릴 버전 관리 저장소로의 잦은 커밋, 깨진 빌드

즉시 고치기, 그리고 별도의 통합 빌드 머신 사용하기와 같은 실천 방법이 이에 해

당합니다.

CI 실천 방법은 피드백을 보다 빨리 받게 해줍니다. CI 실천 방법을 효과적으로

활용하면, 여러분은 개발 중인 소프트웨어의 전체적인 건강 상태를 하루에도 예닐

곱 번은 알게 될 겁니다. 더욱이, 지속적인 통합은 리팩토링과 테스트 주도 개발과

같은 실천 방법과도 잘 어울립니다. 왜냐하면 이런 실천 방법이 작은 변경을 가한다

는 개념에 중심을 두기 때문입니다. 지속적인 통합은 본질적으로, 변경 내역이 소프

트웨어의 나머지 부분과 제대로 작동한다는 걸 확인하는 안전망입니다. 좀더 높은

수준에서 보자면, 지속적인 통합은 팀 공동의 자신감을 증가시키고 프로젝트에 필

요한 인적 활동의 양을 줄여줍니다. 지속적인 통합은 소프트웨어가 변경될 때마다

자동으로 작동하는 프로세스이기 때문입니다.

☆ ‘지속적인’이란

우리가 이 책에 ‘지속적인’이란 용어를 사용하긴 하지만, 그 사용법은 기술적으로 봤을

때 정확하지 않습니다. ‘지속적인’이란 말에는 한번 시작하면 절대 멈추지 않는다, 라는

의미가 내포되어 있습니다. 이는 프로세스가 끊임없이 통합한다는 걸 암시하지만, 가

장 격렬한 CI 환경에서조차도 그렇지는 않습니다. 그러니, 우리가 이 책에서 묘사하는

것은 ‘빈번한 통합’에 보다 가깝습니다.

Page 25: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

xxv

누가 이 책을 읽어야 할까요?

우리의 경험에 따르면, 소프트웨어 개발을 업무(job)로 취급하는 사람과 전문적인 직

업(profession)으로 취급하는 사람 사이에는 뚜렷한 차이가 있습니다. 이 책은 직업인으

로서 일하면서 자신들이 프로젝트에서 똑같은 과정을 되풀이해 수행하고 있다고 느

끼는 사람을 위한 책입니다(반복되는 과정을 수행하는 줄 모르고 있다면, 우리가 여

러분을 도와 똑같은 일을 얼마나 자주 하는지 깨닫게 해드리겠습니다). 우리는 지속

적인 통합을 실천하는 방법과 그 장점을 설명하고 이런 실천 방법을 적용하기 위한

지식을 전달하여, 여러분의 시간과 전문 지식을 보다 중요하고 도전적인 이슈로 돌

릴 수 있도록 하겠습니다.

이 책은 지속적인 통합과 관련된 주요 주제를 다루는데, 지속적인 피드백, 테스트,

배포, 검사, 그리고 데이터베이스 통합을 이용해 지속적인 통합을 구현하는 방법을

포함합니다. 소프트웨어 개발에서 어떤 역할을 하든지, 지속적인 통합을 소프트웨

어 개발 프로세스에 도입할 수 있습니다. 만약 여러분이 점차 유능해지고자 하는 소

프트웨어 전문가라면, 더 많은 일을 점점 더 믿음직스럽게 해나가고자 하는 사람이

라면, 이 책에서 많은 걸 가져갈 수 있을 겁니다.

개발자

사용자를 위한 소프트웨어를 개발하는 데 집중하지 못하고 소프트웨어 통합 문제

때문에 씨름하고 있다면, 이 책이 여러분이 겪을 거라고 생각하는 ‘통합의 난항’에서

어려움 없이 빠져나올 수 있도록 도울 것입니다. 이 책은 여러분에게 통합하는 데

시간을 더 쓰라고 요구하진 않습니다. 이 책이 바로 소프트웨어 통합 문제를 별 것

아닌 일로 만들어주기 때문입니다. 따라서 여러분이 가장 좋아하는 일, 바로 소프트

웨어를 개발하는 일에 집중할 수 있게 해줍니다. 이 책에서 소개하는 실천 방법이나

예제 상당수는 효과적인 CI 시스템을 어떻게 구현하는지 실지로 보여줍니다.

빌드/형상/릴리즈 관리

여러분이 하는 일이 소프트웨어를 세상 밖으로 내놓는 것이라면, 버전 관리 저장소

에 변경 내역이 적용될 때마다 프로세스들을 돌림으로써, 응집력 있고 잘 작동하는

소프트웨어를 생성해낼 수 있다는 걸 우리가 보여주면 이 책이 아주 흥미롭다고 생

Page 26: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

xxvi

각할 겁니다. 여러 사람이 프로젝트 내에서 개발 같은 다른 역할을 이행하면서 빌드

를 관리하고 있습니다. CI는 여러분을 위해 어느 정도 ‘생각’을 대신해주고, 개발 생

명주기의 끝까지 기다리지 않아도, 배포 가능하고 테스트 가능한 소프트웨어를 하

루에도 여러 번 만들어냅니다.

테스터

지속적인 통합은 ‘버그 수정’이 적용된 후에도 결함이 다시 발생하는 전통적인 고통

을 거의 제거함으로써 소프트웨어 개발에 신속한 피드백 접근 방법을 제공합니다.

CI를 사용하면 테스터는 좀더 만족감을 얻게 되고 프로젝트에서 자신이 맡은 역할

에 더욱 관심을 갖게 되기 마련입니다. 테스트할 소프트웨어가 더 자주 준비될 뿐만

아니라 그 범위도 조금씩 커지기 때문입니다. 개발 생명주기에 CI 시스템을 갖춰놓

는다면, 뒤늦게 테스트를 하거나 아예 테스트를 하지 않는 전형적인 ‘모 아니면 도’

시나리오를 따르지 않고, 줄곧 테스트를 해나갈 수 있습니다.

관리자

만약 팀이 작동하는 소프트웨어를 견실히 그리고 되풀이하여 전달할 수 있다는 자

신감을 키우고 싶다면, 이 책이 큰 영향을 미칠 것입니다. 여러분은 시간, 비용, 그

리고 품질을 훨씬 더 효과적으로 관리할 수 있게 될 텐데, 이는 단순히 프로젝트 일

정상의 작업 항목에만 의존하지 않고, 작동하는 소프트웨어와 더불어 실제적인 피

드백과 메트릭에 기반을 두고 의사결정을 하게 될 것이기 때문입니다.

이 책의 구성

이 책은 두 부분으로 나뉩니다. 1부는 CI를 소개하고 그 개념과 실천 방법을 밑바닥

부터 점검합니다. 1부는 CI의 핵심 실천 방법에 친숙하지 않은 독자에게 맞췄습니다.

하지만 테스트, 검사, 배포, 그리고 피드백과 같은 CI의 핵심 개념을 CI 시스템이 수

행하는 다른 효과적인 프로세스로 자연스럽게 확장해주는 2부가 없다면, CI의 실천

방법이 완전하다고 생각하지는 않습니다

Page 27: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

xxvii

1부: 지속적인 통합의 배경-원칙과 실천 방법

1장 ‘시작하기’는 지속적인 통합을 활용해서 소프트웨어를 지속적으로 빌드하는 고

수준의 사례를 제시함으로써 곧바로 적용할 수 있게끔 해줍니다.

2장 ‘지속적인 통합 도입하기’는 공통적인 실천 방법과 우리가 CI를 도입했던 방

식에 친숙해지게 해줍니다.

3장 ‘지속적인 통합을 사용해서 위험 줄이기’는 시나리오에 기반한 사례를 사용하

여 CI가 완화시켜 줄 수 있는 핵심 위험 요소를 알아봅니다.

4장 ‘코드가 변경될 때마다 소프트웨어를 빌드하기’는 자동화된 빌드를 활용하여

변경 내역마다 소프트웨어를 통합하는 실천 방법을 탐구합니다.

2부: 완전한 기능을 갖춘 지속적인 통합 시스템 만들기

5장 ‘지속적인 데이터베이스 통합’은 데이터베이스를 다시 빌드하고 테스트 데이터

를 모든 통합 빌드의 일부로써 적용하는 프로세스와 관련된 보다 발전한 개념으로

이어갑니다.

6장 ‘지속적인 테스트’는 통합 빌드를 할 때마다 소프트웨어를 테스트하는 개념과

전략을 다룹니다.

7장 ‘지속적인 검사’는 다른 도구와 기법을 사용하여 자동화되고 지속적인 검사(정

적 및 동적 분석)를 하는 방법을 소개합니다.

8장 ‘지속적인 배포’는 지속적인 통합 시스템을 사용하여 소프트웨어를 배포하여,

소프트웨어를 기능적으로 테스트할 수 있게 하는 프로세스를 탐구합니다.

9장 ‘지속적인 피드백’은 지속적인 피드백 장치(이메일, RSS, X10 그리고 앰비언

트 오브와 같은)를 사용하여, 빌드가 끝나면 성공 또는 실패 여부를 통지 받을 수 있

는 방법을 설명하고 보여줍니다.

‘후기’는 지속적인 통합의 향후 가능성을 탐구합니다.

부록

부록 A ‘지속적인 통합 관련 리소스’엔 지속적인 통합과 관련된 웹 주소, 도구, 그리

고 문서가 있습니다.

부록 B ‘지속적인 통합 도구 평가하기’는 시장에 나와 있는 다양한 지속적인 통합

서버와 관련된 도구를 평가하고, 책에서 설명한 실천 방법에 적용할 수 있는지 여부

Page 28: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

xxviii

를 논의하고, 각각의 장점과 단점을 알아보며, 보다 흥미로운 특징 중 일부를 사용

하는 법을 설명합니다.

그 밖의 특징

이 책은 본문에서 설명한 내용을 여러분이 더 잘 배우고 적용할 수 있게 도와주는

특징을 담고 있습니다.

실천 방법 – 이 책에는 40가지가 넘는 CI와 관련된 실천 방법을 다룹니다. 여

러 장(Chapter)의 작은 표제는 실천 방법을 담고 있습니다. 대부분의 장 도입부

에 제시된 그림은 어떤 실천 방법을 다루는지 보여주고, 흥미를 끄는 영역을

찾을 수 있게 해줍니다. 예를 들어, “전용 통합 빌드 머신을 사용하라”와 “코드

를 자주 커밋하라”는 이 책에서 논의되는 실천 방법의 사례라 하겠습니다.

예제 – 다양한 언어와 플랫폼으로 구성된 다양한 예제를 사용함으로써 이런

실천 방법을 어떻게 적용하면 되는지 보여줍니다.

질문 – 각 장은 프로젝트의 CI 실천 방법을 응용할 때 도움이 될 만한 질문

목록을 제시하고 끝납니다.

웹 사이트 – 이 책의 자매 웹 사이트 www.integratebutton.com에는 책의 최

신 정보, 코드 예제, 그밖의 자료가 있습니다.

무엇을 배우게 되는가

이 책을 읽음으로써, 응집력 있고 잘 작동하는 소프트웨어를 하루에도 여러 번 만들

어낼 수 있는 개념과 실천 방법을 배우게 될 겁니다. 우리는 실천 방법을 먼저 제시

하고, 이런 실천 방법을 응용하는 방법이 뒤따르도록 하고, 가능하면 실제로 사용할

수 있는 예제를 포함하려고 집중했습니다. 예제는 자바, 마이크로소프트 닷넷, 그

리고 심지어 루비와 같은 서로 다른 개발 플랫폼을 사용합니다. CruiseControl(자

바와 닷넷 버전)은 줄곧 주요 CI 서버로 사용됩니다. 하지만 자매 웹사이트(www.

integratebutton.com)와 부록 B에서 소개한 다른 서버와 도구를 사용해서도 비슷한

예제를 만들어봤습니다.

이 책을 따라가다 보면, 다음과 같은 통찰을 얻게 됩니다.

Page 29: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

xxix

CI를 구현하면 어떤 식으로 개발 생명주기의 매 단계마다 배포 가능한 소프트

웨어를 생산해내게 되는지.

CI가 어떤 식으로 결함이 발생하는 시점과 결함이 탐지되는 시점의 간격을 줄

이고, 그럼으로써 결함을 고치는 비용을 줄이는지.

어떻게 하면 개발 주기 막판까지 기다리지 않고 소프트웨어를 자주 빌드함으

로써 소프트웨어에 품질을 구축해 넣을 수 있는지.

이 책이 다루지 않는 것

이 책은 지속적인 통합 시스템을 이루는 모든 도구-빌드 스케줄링, 프로그래밍 환경,

버전 관리 등-를 다루진 않습니다. 효율적인 CI 시스템을 개발하기 위한 CI 실천 방

법을 구현하는 데 초점을 둡니다. CI 실천 방법을 우선 논의합니다. 만약 예시된 특

정 도구를 더 이상 사용하지 않는다든가 그 도구가 특정 요구에 부합하지 않는다면,

다른 도구를 통해 실천 방법을 적용하여 똑같은 효과를 달성하면 됩니다.

이뿐만 아니라 CI 시스템에 사용되는 모든 종류의 테스트, 피드백 메커니즘, 자동

화된 검사기, 그리고 배포 유형을 다루기란 가능하지 않고 실용적이지도 않습니다.

이 책에서 내내 언급하듯, 자매 웹 사이트인 www.integratebutton.com 에는 책에

서 다루지 않는 다른 도구와 프로그래밍 언어를 사용한 예제가 있습니다.

작가 소개

이 책은 세 명의 공저자와 한 명의 기고자가 썼습니다. 많은 장을 제가 썼고 스티브

마티야스는 4, 5, 7, 8장, 부록 A, 이와 더불어 책에 수록된 몇몇 예제를 작성하는 데

기여했습니다. 앤디 글로버는 6, 7, 8장을 썼으며 예제를 제공하고, 다른 부분에도

기여했습니다. 에릭 타블라는 부록 B를 썼습니다. 그러니 일인칭 대명사를 쓰는 문

장이 있어서 누가 쓴 글인지 헷갈릴 때, 이 점을 고려하면 누가 무슨 말을 했는지 명

확해질 겁니다.

Page 30: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

xxx

책 표지에 대해 3)

우리가 쓴 책이 명성 높은 마틴 파울러 서명 시리즈의 일부가 된다는 걸 알고 저는

무척 흥분했습니다. 그때 저는 책 표지로 다리를 선택해야겠다고 마음 먹었습니다.

공저자들과 저는 워싱턴 D.C에서 자란 희귀종들입니다. 워싱턴 D.C 출신이 아닌

여러분이 이해할 수 있게 말하자면, 그곳은 공허한 지역입니다. 좀더 구체적으로 말

하자면, 우리는 노던 버지니아 출신이어서 버지니아 주의 내추럴 브리지(Natural Bridge)

를 선택한다면 고향에 알맞은 헌정을 하는 셈이라고 생각했습니다. 저는 책 표지로

그 다리를 선택한 직후인 2007년 초가 되어서야 그 다리에 처음 가봤습니다. 그 다

리는 매우 흥미로운 역사를 간직하고 있었고, 매일 같이 자동차가 그 위를 지나다니

는 기능적인 다리라는 사실을 알고 경이로움을 느꼈습니다(물론, 제 자신도 차를 몰

고 다리 위를 여러 번 오갔습니다). 여러분이 이 책을 읽고 나서 CI를 다음 번 소프

트웨어 개발 프로젝트의 자연스런 일부로 받아들여줬으면 합니다.

3) 원서 표지에 대한 설명입니다.

Page 31: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

xxxi

감사의 말

얼마나 많이 감사의 말을 읽었는지, 그리고 그때마다 작가들이 “~가 없었다면 이 일

을 결코 해내지 못했을 것이다”라는 식의 말을 써놓았는지 모릅니다. 저는 항상 속으

로 이렇게 생각했습니다. “지나치게 겸손한 거겠지.” 하지만 제가 제대로 헛짚었습니

다. 이 책은 제가 여기서 열거한 고마운 사람들이 엄청나게 도와준 결과물입니다.

출판사인 애디슨 웨슬리에 감사를 전하고 싶습니다. 특히, 책임 편집자인 Chris

Guzikowski에게 이 진 빠지는 작업 내내 저와 함께 일해준 것에 대해 고마움을 표

현하고 싶습니다. 그의 경험, 통찰, 그리고 격려는 대단했습니다. 그리고 여러 교

정 및 편집 주기 내내 탄탄한 충고를 해준 개발 편집자인 Chris Zahn에게도 감사

를 전합니다. K Karen Gettman, Michelle Housley, Jessica D’Amico, Julie Nahil,

Rebecca Greenberg 그리고 마지막으로 누구보다 첫 번째 책임 편집자였던 Mary O’

Brien에게 감사를 전하고 싶습니다.

Rich Mills는 책을 위해 CVS 서버를 호스팅해줬으며 브레인스토밍 세션 동안에

멋진 아이디어를 제안해줬습니다. 2002년에 직업적 글쓰기로 나를 이끌어주고 글

쓰는 과정 내내 유난히 상세한 검토를 해준 저의 멘터이자 친구인 Rob Daly에게 감

사를 전하고 싶습니다. John Steven은 이 책을 쓰는 과정을 시작할 때 도움을 줬습

니다.

공동 저자, 편집자, 공헌 저자들에게도 사의를 표하고 싶습니다. 스티브 마티야스

와 저는 여러분이 오늘 읽고 있는 이 책을 만들어내느라 여러 밤을 잠 못 이루고 견

뎌냈습니다. 앤디 글로버는 자신이 프로젝트에서 쌓아온 상당한 개발자 테스트 경

험을 제공해준 대단한 글쓴이였습니다.

공헌 편집자인 리사 포터는 지치지 않고 주요 교정판을 모두 자세히 검토하고 책

의 품질을 높이는 데 도움이 된 교정과 충고를 제공해줬습니다. 지속적인 통합 도

구 부록을 써준 에릭 타블라와 부록 B에서 Maven2에 대한 자신의 경험을 제공해준

Levent Gurses 에게도 감사를 전합니다.

이 프로젝트 내내 훌륭한 피드백을 제공해준 개인적인 기술 검토자들이 많았습

니다. Tom Copeland, Rob Daly, Sally Duvall, Casper Hornstrup, Joe Hunt, Erin

Jackson, Joe Konior, Rich Mills, Leslie Power, David Sisk, Carl Tallis, Eric Tavela,

Dan Taylor, 그리고 Sajit Vasudevan 등이 그들이었습니다.

Page 32: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

xxxii

Charles Murray와 Cristalle Belonia, 그리고 Unbancode의 Maciej Zawadzki와

Eric Minick에게도 도와줘서 고맙다고 전하고 싶습니다.

Stelligent사에서 매일 나에게 영감을 준 Burke Cox, Mandy Owens, David

Wood, 그리고 Ron Wright 을 비롯한 여러 훌륭한 사람들의 도움에도 사의를 표합

니다. Rich Campbell, David Fado, Mike Fraser, Brent Gendleman, Jon Hughes,

Jeff Hwang, Sherry Hwang, Sandi Kyle, Brian Lyons, Susan Mason, Brian Messer,

Sandy Miller, John Newman, Marcus Owen, Chris Painter, Paulette Rogers, Mark

Simonik, Joe Stusnick, 그리고 Mike Trail 등은 여러 해에 걸쳐 나의 일에 영감을 주

었습니다.

Scott Ambler, Brad Appleton, Jon Eaves, Martin Fowler, Paul Holser, Paul

Julius, Kirk Knoernschild, Mike Melia, Julian Simpson, Andy Trigg, Bas Vodde,

Michael Ward, 그리고 Jason Yip으로 구성된 애디슨 웨슬리 기술 검토 팀에서 준

철저한 피드백에도 감사를 전합니다.

2006년 시카고에서 열린 지속적인 통합과 테스팅 컨퍼런스(CITCON)에 참여한 사

람들에게도 지속적인 통합과 테스트에 대한 자신의 경험을 우리 모두에게 나눠준

것에 감사를 전합니다. 컨퍼런스를 조직해준 폴 줄리어스와 제프리 프레데릭과 이

행사에 참여한 모든 사람에게 감사합니다. 마지막으로 이 책을 만드느라 우여곡절

을 겪는 내내 함께 있어주고 꾸준히 지원해준 아내 Jenn에게도 감사를 전하고 싶

습니다.

폴 M. 듀발

버지니아주 페어팩스에서

2007년 3월

Page 33: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

xxxiii

리사 포터는 미국 정부에 네트워크 보안 솔루션을 제공하는 컨설팅 회사의 선임 테

크니컬 라이터(Technical Writer)입니다. 리사는 이 책을 펴내기에 앞서 기술 편집을 해줬

습니다. 초창기에는 여러 개의 애플리케이션을 개발하는 대규모 소프트웨어 개발

프로젝트를 지원했는데, 거기서 그녀는 요구 사항 결정과 프로젝트 성숙도/역량 활

동에 대해 많은 걸 배웠습니다. 리사는 외국어 번역과 건축학/공학 산업 분야에 기

술적 글쓰기의 원칙들을 적용해왔습니다. 리사는 2002년부터 책과 온라인 출판물

을 편집해왔습니다.

에릭 타블라는 5AM Solutions사의 아키텍트 책임자인데, 이 곳은 생명과학연구

커뮤니티를 위해 소프트웨어 엔지니어링의 최고의 실천 방법들을 적용하는 데 초점

을 맞춘 소프트웨어 개발 회사입니다. 에릭은 주로 자바/J2EE 애플리케이션을 설계

하고 구현하고 객체 지향 소프트웨어 개발과 UML 모델링 분야에서 개발자들을 멘

토링해왔습니다.

공 헌 자 소 개

Page 34: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기
Page 35: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

1

지속적 통합의 배경:

원칙과 실천 방법

part1 P {

[ }] |

\“‘ Integrate

?/

Shift

Page 36: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

2

P {[ }

] |\

“‘ Integrate

?/

Shift

Page 37: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

3

Javaranch.com의 설립자인 케이시 시에라Kathy Sierra는 자신의 블로그에서 이렇게 말

했습니다. “ ‘매일 사과 하나를 먹어라’ 라고 말하는 것과 실제로 사과를 먹는 것 사

이엔 커다란 차이가 있다.”1) 소프트웨어 프로젝트에 적용해야 할 기초적인 실천 방

법을 따를 때도 마찬가지입니다. “테스트해봐야 효율적이지 않아” 라든가 “코드 검

토는 시간 낭비야” 라든가 잦은 소프트웨어 빌드는 따르기엔 좋지 않은 실천 방법이

라고 말하는 사람은 드뭅니다. 하지만 겉보기엔 기초적인 것 같은 이런 실천 방법도

설교보다는 실천하는 데 보다 중점을 둬야 합니다. 이런 실천 방법이 프로젝트에 적

용되는 빈도가 비참할 정도로 낮기 때문입니다.

통합 빌드를 자주 돌리고, 그렇게 해서 통합 빌드를 대수롭지 않은 일로 만들고

싶다면, 지속적인 통합(Continuous Integration, CI)이 많은 도움이 될 것입니다. 지속적인 통

합은 컴파일 및 데이터베이스 재빌드, 자동화된 테스트와 검사, 소프트웨어 배포,

사용자 피드백 받기 등의 과정을 포함합니다. 1장에서는 이 같은 기초적인 소프트

웨어 실천 방법을 토대로 하는 CI 시스템에서 공통적으로 볼 수 있는 특징에 대해

알아볼 겁니다.

1) 출처: http://headrush.typepad.com

■ 변경할 때마다 소프트웨어 빌드하기

chapter1 시작하기

먼저, 기초부터 통달하라

- 래리 버드(Larry Bird, 미국 프로 농구 선수)

P {[ }

] |\

“‘ Integrate

?/

Shift

Page 38: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

Continuous Integration

지속적인 통합의 기초는 이해하기 무척 쉬우므로, 이러한 기초적인 실천방법들을

금방 적용할 수 있을 겁니다.

변경할 때마다 소프트웨어를 빌드하기

책을 읽을 때, 저는 먼저 예제를 보고 뒤이어 ‘왜 그런지’를 배우고 싶어합니다. 왜냐

하면 예제를 보면 글의 문맥에 따라 ‘왜 그런지’ 이해할 수 있기 때문입니다. 이 책에

서도 전형적인 구현 방식에 근거를 두고 CI 시나리오를 설명합니다. 독자분들은 CI

시스템을 구축하는 방법이 상당히 다양하다는 것에 놀랄지 모르지만, 이를 통해 전

형적인 CI 시스템의 여러 요소를 더 잘 이해할 수 있게 될 것이라고 믿습니다.

☆ 빌드란?

빌드는 컴파일(또는 동적 언어에서와 같은 변형된 형태)보다 훨씬 많은 걸 의미합니다.

빌드에는 컴파일과 테스트, 검사, 배포 등의 과정들이 포함될 수 있습니다. 빌드라 함

은 소스 코드를 한 곳에 모아보고, 소프트웨어가 응집력 있는 하나의 단위로써 작동하

는지 확인하는 과정이라 하겠습니다.

CI 시나리오는 개발자가 소스 코드 저장소에 코드를 커밋할 때 시작됩니다. 보통의

프로젝트라면, 프로젝트에서 제각기 다른 역할을 맡은 사람들이 변경 사항을 커밋

할 테고, 그때 CI 주기가 시작됩니다. 이는 개발자가 소스 코드를 변경하고, 데이터

베이스 관리자(DBA)가 테이블 정의를 고치고, 빌드 팀이나 배포 팀에서 설정 파일을

변경하고, 인터페이스 팀이 DTD/XSD 명세를 변경하는 것 등을 모두 포함합니다.

☆ 최신 예제 보기

책에 ‘실제’ 예제를 써넣으면 위험이 따르는데, 금세 시대에 뒤진 예제가 될 수 있기 때

문입니다. 지속적인 통합과 같이 동적인 주제라면 특히 그렇습니다. 이 책이 출판된 후

발생할지 모르는 차이를 줄이려고, 우리는 자매 웹 사이트인 www.integratebutton.

com에 CruiseControl과 Ant 뿐만 아니라 다른 CI 서버와 도구에 관한 예제도 갱신해

넣을 것입니다.

Page 39: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

chapter1 시작하기

지속적인 통합 시나리오라면 일반적인 각 단계는 다음과 같습니다.

개발자가 버전 관리 저장소에 코드를 커밋해 넣습니다. 그 사이, 통합 빌드 컴

퓨터에 설치된 CI 서버가 변경 사항이 없는지 이 저장소를 계속 확인합니다.

이를 테면, 몇 분마다 확인(폴링: polling)할 수 있습니다.

커밋이 되면 곧이어, CI 서버가 버전 관리 저장소에서 변경 내역을 감지해냅

니다. 그리고 CI 서버는 저장소에서 최신 소스 코드 복사본을 가져와서 빌드

스크립트를 실행하고 소프트웨어를 통합합니다.

CI 서버는 지정된 프로젝트 구성원들에게 이메일로 빌드 결과를 보냄으로써

피드백을 줍니다.

CI 서버는 버전 관리 저장소에 변경 사항이 들어왔는지 계속해서 폴링합니다.

그림 1-1은 CI 시스템의 이런 측면을 묘사합니다.

그림 1-1에 나와있는 도구와 참가자들에 대해서는 이어지는 글에서 자세히 설명

합니다.

그림 1-1 ㅣ CI 시스템의 컴포넌트

1.

2.

3.

4.

Page 40: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

Continuous Integration

개발자

작업 내용과 관련된 수정 작업이 끝나면, 개발자는 개인 빌드(private build, 개인 빌드는

팀의 다른 개발자들이 작업한 최신 내용을 작업 PC에 다운받아 컴파일하는 것을 의

미합니다)를 수행하고, 그러고 나서 변경 내역을 버전 관리 저장소에 커밋합니다.

이 과정은 언제라도 발생할 수 있으며, CI 프로세스의 이후 과정엔 영향을 주지 않

습니다. 통합 빌드는 변경사항이 버전 관리 저장소에 적용될 때 비로소 시작됩니다.

목록 1-1은 명령줄에서 Ant 빌드 스크립트를 호출하여 개인 빌드를 실행시키는

예제입니다. 이 스크립트가 서브버전 버전 관리 저장소에서 최신 업데이트를 가져

오는 걸 눈여겨 보시기 바랍니다.

★ 자주 빌드하여 문제를 보다 이른 시기에 찾아내세요

일단 빌드가 자동화되어 있고, 명령어 하나로 빌드를 실행시킬 수 있게 됐다면, CI를 수

행할 준비가 되었다고 할 수 있습니다. 프로젝트의 버전 관리 시스템에 변경 사항이 커밋

될 때마다 자동화된 빌드를 돌리면, 다음과 같은 질문에 팀이 대답할 수 있게 됩니다.

모든 소프트웨어 컴포넌트가 함께 작동합니까?

코드 복잡도는 얼마나 됩니까?

팀이 정해진 코딩 표준을 잘 지킵니까?

자동화된 테스트가 적용되는 코드가 얼마나 됩니까?

가장 최근의 변경 사항을 반영한 후에 모든 테스트가 성공했습니까?

애플리케이션이 성능 요구사항을 여전히 충족시킵니까?

마지막 배포에 아무런 문제가 없었습니까?

마지막 변경 사항이 적용된 후에 소프트웨어가 성공적으로 ‘빌드됐다’는 사실을 아는 것

도 도움이 되지만, 소프트웨어가 올바르게 빌드됐다는 걸 안다면 더할 나위 없을 겁니다.

소프트웨어 결함은 의심할 여지 없이 어느 시점엔가 코드 베이스에 슬그머니 들어올 것이

기 때문이죠. 빌드를 지속적으로 하려는 것도 피드백을 신속히 받으면 개발 생명주기 내

내 문제를 발견하고 해결할 수 있기 때문입니다.

Page 41: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

chapter1 시작하기

목 록 1-1 | Ant를 사용해서 개인 빌드 실행시키기

> ant integrateBuildfile: build.xmlclean:svn-update:all:compile-src:compile-tests:integrate-database:run-tests:run-inspections:package:deploy:BUILD SUCCESSFULTotal time: 3 minutes 13 seconds

개인 빌드가 성공하면, 이제 새로운 파일이나 변경된 파일을 저장소에 체크인할 수

있습니다. 목록 1-2가 보여주듯, 대부분의 버전 관리 시스템은 이런 과정을 위한 간

단한 명령어를 제공합니다.

목 록 1-2 | 변경 사항을 서브버전 저장소에 커밋해 넣기

> svn commit –m "Added CRUD capabilities to DAO"

Sending src\BeerDaoImpl.java

Transmitting file data .

Committed revision 52.

통합 개발 환경(IDE)을 쓰더라도 빌드 스크립트를 실행시키고 저장소에 변경 사항을

커밋해 넣을 수 있습니다. 단지 명령줄에서도 두 가지 일(빌드 스크립트를 실행시키

고 저장소에 변경 사항을 커밋해 넣는)을 수행할 수 있게끔 해둬야 합니다. 그래야

IDE나 버전 관리 시스템에 지나치게 의존하지 않는다는 걸 확신할 수 있습니다.

버전 관리 저장소

단언하건대, 지속적인 통합을 수행하려면 버전 관리 저장소를 반드시 사용해야 합

니다. 사실, CI를 쓰지 않는다 해도, 버전 관리 저장소는 프로젝트의 표준이 되어야

합니다. 버전 관리 저장소의 목적은 접근 제어형 저장소를 사용하여 소스 코드와 다

른 소프트웨어 자산에 가해지는 변경 사항을 관리하는 것입니다. 버전 관리 저장소

는 ‘단일 출처’를 제공하므로 한 곳에서 모든 소스 코드를 가져올 수 있습니다. 버전

Page 42: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

Continuous Integration

관리 저장소는 시간을 거슬러 올라가 다른 버전의 소스 코드와 기타 파일을 가져올

수 있게 해줍니다.

버전 관리 저장소의 주흐름mainline(예를 들어, CVS와 서브버전 같은 시스템에서 말

하는 헤드와 트렁크Head/Trunk에 대해 지속적인 통합을 돌리게 됩니다. 세상에는 다양

한 버전 관리 시스템이 있습니다. 이 책에 쓰인 대부분의 예제에서 서브버전을 사

용하는데, 그 기능 집합이 뛰어날 뿐만 아니라 무료로 쓸 수 있기 때문입니다. 다

른 소프트웨어 형상 관리(Software Configuration Management, SCM)/버전 관리 도구에는 CVS,

Perforce, PVCS, ClearCase, MKS, Visual SourceSafe가 있습니다. 소프트웨어 형

상 관리를 효과적으로 수행하는 기법을 배우고 싶다면, Stephen Berczuk와 Brad

Appleton이 쓴 『Software Configuration Management Patterns』을 참고하세요.

지속적인 통합 서버

지속적인 통합 서버는 버전 관리 저장소에 변경 사항이 커밋되어 들어올 때마다 통합

빌드를 돌립니다. 대체로, 버전 관리 저장소에 변경 사항이 들어왔는지 몇 분 간격으

로 확인하도록 CI 서버를 설정하게 됩니다. 지속적인 통합 서버는 소스 파일을 가져와

서 빌드 스크립트나 다른 스크립트를 실행시킬 겁니다. 지속적인 통합 서버가 매 시간

마다 또는 일정 주기로 빌드하도록 일정을 잡을 수도 있습니다(하지만 이런 게 지속적

인 통합이라고 생각하진 마세요). 이뿐만 아니라 지속적인 통합 서버는 보통 빌드 결

과를 게시하는 편리한 대시보드를 제공합니다. 비록 권장되기는 하지만, 지속적인 통

합 서버가 반드시 지속적인 통합을 수행해야 하는 건 아닙니다. 스스로 자신만의 맞춤

형 스크립트를 작성할 수 있습니다. 더 나아가, 변경 사항이 저장소에 적용될 때마다

통합 빌드를 직접 돌릴 수도 있습니다. 지속적인 통합 서버를 사용하면2) 사람이 직접

작성해야 할 맞춤형 스크립트의 개수를 줄일 수 있습니다. 여러 지속적인 통합 서버가

무료이고 오픈소스입니다. 목록 1-3은 CruiseControl의 설정 파일 config.xml을 사용

해서 서브버전 저장소에 변경 사항이 들어왔는지 확인하는 예제입니다.

목 록 1-3 | 서브버전 저장소를 폴링하는 CruiseControl의 설정 파일 config.xml

<project name="brewery" >

<listeners>

<currentbuildstatuslistener file="logs/${project.name}/status.txt"/>

2) 지속적인 통합 서버에 대한 정보를 더 얻고 싶다면, 부록 B를 보세요.

Page 43: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

chapter1 시작하기

</listeners>

<modificationset quietperiod="30">

<svn RepositoryLocation="http://build.ib.com/trunk/brewery"

username="bfranklin"

password="G0Fly@Kite"/>

</modificationset>

<schedule interval="300">

<ant anthome="apache-ant-1.6.5" buildfile="bld-{project.name}.xml"/>

</schedule>

<log dir="logs/${project.name}">

<merge dir="projects/${project.name}/impl/logs/junit"/>

<merge dir="projects/${project.name}/impl/logs/cobertura"/>

</log>

<publishers>

<artifactspublisher dir="projects/${project.name}/impl/logs"

dest="artifacts/${project.name}"/>

<artifactspublisher dir="projects/${project.name}/impl/logs"

dest="artifacts/${project.name}"/>

</publishers>

</project>

목록 1-3을 보면, schedule 태스크task의 interval 속성attribute이 서브버전 저장소에

변경 사항이 들어왔는지, CruiseControl이 얼마나 자주 변경 사항을 확인해야 하

는지 지시합니다(이 예제에서는 300초입니다). 만약 CruiseControl이 뭔가 변경됐

다는 걸 알아내면, 빌드를 위임(목록 1-3의 buildfile 속성에서)합니다. 위임한 빌

드(보이진 않지만)는 최신의 소스 코드를 저장소에서 가져와서 프로젝트 빌드 파

일을 실행시킵니다. 목록 1-3의 예제처럼 말이죠. 다른 CI 서버라면 관리하기 위해

웹 기반의 설정 인터페이스 또는 다른 용도의 인터페이스를 사용할지도 모릅니다.

CruiseControl엔 웹 애플리케이션이 딸려있어서 최근의 빌드 결과와 빌드 보고서를

볼 수 있습니다(테스트 보고서나 검사 보고서 같은). 그림 1-2는 CruiseControl 빌드

결과에 대한 예제입니다.

그림 1-2 ㅣ 최근의 빌드 상태를 보여주는 CruiseControl 대시보드

Page 44: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

Continuous Integration

�0

빌드 스크립트

빌드 스크립트는 코드 컴파일 및 검사, 배포 등의 작업들을 자동화하는 배치 스크

립트를 말합니다. 물론 지속적인 통합 시스템이 아니더라도 빌드 스크립트를 사용

할 수 있습니다. 이런 자동화 빌드 스크립트 도구로는 Ant나 NAnt, make, MSBuild,

Rake 등이 있지만, 이 도구들 자체가 CI를 구현해 주지는 않습니다. 물론 IDE로 빌

드하는 사람도 많습니다. 하지만 지속적인 통합은 ‘사람이 개입되지 않는hands-off’ 자

동화된 과정이어야 하므로, IDE 기반의 빌드를 이용해서는 진정한 지속적인 통합이

라 할 수 없습니다. 가능하다면, IDE 없이 빌드할 수 있어야 합니다. 목록 1-4에 일

반적으로 개인 빌드에 사용되는 Ant 스크립트의 예가 나와있습니다.3)

목 록 1-4 | 빌드를 수행하는 Ant 스크립트 껍데기

<?xml version="1.0" encoding="iso-8859-1"?>

<project name="brewery" default="all" basedir=".">

<target name="clean" />

<target name="svn-update" />

<target name="all" depends="clean,svn-update"/>

<target name="compile-src" />

<target name="compile-tests" />

<target name="integrate-database" />

<target name="run-tests" />

<target name="run-inspections" />

<target name="package" />

<target name="deploy" />

</project>

피드백 메커니즘

지속적인 통합을 사용하는 주 목적 중 하나는 통합 빌드 시, 이에 대한 피드백을 즉

시 주는 것입니다. 최신 빌드에 뭔가 문제가 있다면 최대한 빨리 그 사실을 알아야

하니까요. 피드백을 일찍 받으면 더 신속하게 문제를 해결할 수 있습니다. 그림 1-3

에서는 이메일로 피드백을 줍니다. 9장에선 좀더 다양한 피드백 장치에 대해 살펴

볼 것입니다. 문자 메시지(SMS)나 RSS를 통해 피드백을 줄 수도 있습니다.

3) 보다 구체적인 예제는 www.integratebutton.com에 있습니다.

Page 45: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

��

chapter1 시작하기

그림 1-3 ㅣ CI 서버가 보낸 이메일 메시지

목록 1-5는 CruiseControl CI 서버를 활용해서 프로젝트 구성원들에게 이메일을 보

내는 예제입니다.

목 록 1-5 | 이메일을 보내도록 설정한 CruiseControl 빌드 파일 config.xml

<project> … <publishers> <htmlemail css="./webapps/cruisecontrol/css/cruisecontrol.css" mailhost="localhost" xsldir="./webapps/cruisecontrol/xsl" returnaddress="pduvall@localhost" buildresultsurl="http://localhost:8080" mailport="225" username="pduvall" password="password" reportsuccess="always" spamwhilebroken="true"> <always address="pduvall@localhost"/> <always address="aglover@localhost"/> </htmlemail> </publishers> …</project>

Page 46: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

Continuous Integration

�2

통합 빌드 머신

통합 빌드 머신은 소프트웨어를 빌드하는 것을 그 유일한 존재 목적으로 삼는 별도

의 컴퓨터를 말합니다. 통합 빌드 컴퓨터에서 CI 서버가 돌아가고, CI 서버는 버전

관리 저장소를 폴링합니다.

지속적인 통합의 특징

이제 빌드할 때 쓸 수 있는 예제가 있으니, 지속적인 통합의 특징을 깊이 파고들 수

있습니다. 지속적인 통합이 요구하는 컴포넌트는 단 네 가지뿐입니다.

버전 관리 저장소로의 연결

빌드 스크립트

몇 종류의 피드백 메커니즘 (이메일 같은)

소스 코드 변경 내역을 통합하기 위한 프로세스 (수작업으로 하든, CI 서버를

활용하든)

이것이야말로 효과적인 CI 시스템의 핵심이라 하겠습니다. 버전 관리 시스템에 변

경 내역이 들어올 때마다 자동화된 빌드가 작동하도록 일단 만들어놓고 나면, CI 시

스템에 다른 기능을 넣을 수가 있습니다.

데이터베이스 통합, 테스트, 검사, 배포, 피드백을 자동화하고 지속적으로 수행함

으로써, CI 시스템은 프로젝트에서 흔히 발생하는 일반적인 위험 요소를 줄여줍니다.

또 이렇게 함으로써 프로젝트 수행에 대한 자신감을 키워주며, 의사소통이 더 잘 이

뤄지게 해줍니다. CI의 일부 특징은 다른 특징에 의존적인데, 예를 들면 자동화된

테스트는 소스 코드 컴파일에 의존적입니다.

이렇게 반복 가능한 프로세스는 개발 생명 주기를 통틀어 발생할 법한 위험을 경감

시키는 데 도움이 될 수 있습니다. 이러한 하부 프로세스는 뒤이어 자세히 설명합니다.

소스 코드 컴파일

지속적인 소스 코드 컴파일은 CI의 가장 기본적이고 일반적인 특징 중 하나입니다.

사실, 지속적인 소스 코드 컴파일은 아주 흔하게 하는 일이라 CI와 동의어로 취급받

Page 47: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

�3

chapter1 시작하기

을 정도입니다. 컴파일이란 인간이 읽을 수 있는 소스 코드로부터 실행 가능한 코드

를 만들어내는 일과 관련이 있습니다. 그럼에도 불구하고 지속적인 통합은 소스 코

드 컴파일보다 훨씬 더 나아간 개념입니다. 동적 언어-파이썬, PHP, 루비 등등-가

널리 쓰이게 되면서, 이런 환경에서의 컴파일은 미묘하게 다른 개념이 됐습니다. 비

록 동적 언어를 사용해서 바이너리를 생성하진 않더라도, 여러 동적 언어가 엄격한

★ 통합 버튼

통합 버튼(그림 1-4를 보세요)은 완벽하게 작동하는 자동화된 통합 빌드(빌드를 별 것

아닌 일로 만드는)를 시각화한 것입니다. 여기엔 소프트웨어가 의도한 바대로 작동하게

해주는 여러 과정이 포함됩니다. 여러분은 컴파일하고, 테스트 데이터로 데이터베이스를

재구축하고, 테스트를 돌리고, 검사하고, 배포하고, 피드백을 제공할 수 있습니다. 빌드

를 자동화하면, 버튼 하나만 눌러도 이 많은 과정을 수행할 수 있게 됩니다.

그림 1-4 ㅣ 통합 버튼의 시각화

Page 48: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

Continuous Integration

��

점검(strict check)을 수행하는 기능을 제공하므로, 이런 언어의 관점에서는 엄격한 점검

을 컴파일로 간주할 수 있습니다. 이런 미묘함에도 불구하고, 동적 언어 환경은 지

속적인 통합 빌드 과정에서 실행되는 다른 활동으로부터 혜택을 받습니다.

데이터베이스 통합

소스 코드 통합과 데이터베이스 통합을-언제나 서로 다른 부서가 수행하는-완전히

별개의 업무로 생각하는 사람도 있습니다. 이는 상당히 잘못된 생각인데, 왜냐하면

데이터베이스는 대부분의 애플리케이션에 있어 없어서는 안될 우주의 중심이라고

할 수 있기 때문입니다. 그러므로 CI 시스템에 데이터베이스 통합은 반드시 포함되

어야 하며 이를 통해 단일 소스, 즉 동일한 버전 관리 저장소를 통해 데이터베이스

역시 통합되어 확실한 결과를 얻을 수 있어야 합니다.

그림 1-5는 CI 시스템의 빌드 시 데이터베이스 역시 통합되고 있는 것을 보여줍니

다. 데이터베이스 소스 코드-데이터 정의 언어(DDL) 스크립트, 데이터 조작 언어(DML)

스크립트, 저장 프로시저, 분할 등등-역시 다른 소스 코드와 똑같이 취급합니다. 예

를 들어, 누군가(개발자나 DB 관리자) 데이터베이스 스크립트를 수정하고 그것을

버전 관리 시스템에 커밋한다면, 빌드 스크립트가 이를 이용하여 DB를 생성하고 데

이터도 빌드합니다.

목록 1-6에서는 Ant의 SQL 작업을 이용하여 MySQL DB를 삭제(drop)하고 생성(create)

합니다. DB와 테스트 데이터를 다시 빌드하려면 좀더 해야 할 일이 많습니다. 이

예제에서는 설명을 위해 일부러 매개변수들을 하드 코딩해 넣었습니다.

목 록 1-6 | MySQL과 Ant

<target name="db:create-database”>

<sql driver="com.mysql.jdbc.Driver"

url="jdbc:mysql://localhost:3306/"

userid="root"

password="sa"

classpathref="db.lib.path"

delimiter=";">

<fileset file="${database.dir}/drop-database.sql"/>

<fileset file="${database.dir}/create-database.sql "/>

</sql>

</target>

5장에선 데이터베이스 통합 예제와 접근 방법, 그리고 그 장점을 보여주겠습니다.

Page 49: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

��

chapter1 시작하기

그림 1-5 ㅣ 데이터베이스 통합 설계

테스트

자동화되고 지속적인 테스트가 구비되어 있지 않은 CI는 CI가 아니라고 생각하는

사람이 많습니다. 전적으로 동의합니다. 자동화된 테스트가 없다면, 개발자나 다른

프로젝트 인원들이 자신감을 갖고 소프트웨어를 수정하기 어렵습니다. 그렇기 때

문에, 대부분의 CI 시스템을 이용하는 프로젝트에서는 JUnit이나 NUnit 또는 기타

xUnit 프레임워크의 단위 테스트 도구를 사용하여 테스트를 돌립니다. 물론 테스트

를 여러 범주로 나눠서 번갈아가며 돌리는 식으로 빌드 속도를 높여도 됩니다. 이런

테스트들에는 단위, 컴포넌트, 시스템, 부하 및 성능, 보안 테스트 등을 포함할 수

있습니다. 6장에서 이에 대해 자세히 논의하고자 합니다. 그림 1-6에 CruiseControl

에 사용되는 JUnit의 테스트 보고서가 나와 있습니다.

Page 50: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

Continuous Integration

��

그림 1.6 ㅣ JUnit을 사용한 단위 테스트 회귀 보고서

목록 1-7은 JUnit 테스트 배치를 돌리고, Ant 태스크를 사용해서 그림 1-6의 보고서

를 생성하는 예제를 보여줍니다.

목 록 1-7 | Ant와 JUnit

<?xml version="1.0" encoding="iso-8859-1"?>

<target name="run-tests">

<mkdir dir="${logs.junit.dir}" />

<junit fork="yes" haltonfailure="true" dir="${basedir}"

printsummary="yes">

<classpath refid="test.class.path" />

<classpath refid="project.class.path"/>

<formatter type="plain" usefile="true" />

<formatter type="xml" usefile="true" />

<batchtest fork="yes" todir="${logs.junit.dir}">

<fileset dir="${test.unit.dir}">

<patternset refid="test.sources.pattern"/>

</fileset>

</batchtest>

</junit>

<mkdir dir="${reports.junit.dir}" />

<junitreport todir="${reports.junit.dir}">

<fileset dir="${logs.junit.dir}">

<include name="TEST-*.xml" />

<include name="TEST-*.txt" />

</fileset>

<report format="frames" todir="${reports.junit.dir}" />

</junitreport>

</target>

</project>

Page 51: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

��

chapter1 시작하기

검사 (Inspection)

자동화된 코드 검사(이를테면, 정적 분석이나 동적 분석)는 여러 코딩 규칙을 강제

함으로써 소프트웨어의 품질을 높이는 데 사용할 수 있습니다. 예를 들어, 어떤 프

로젝트는 주석이 안 달린 코드가 300줄을 넘는 클래스가 있어선 안 된다는 규칙이

있을지 모릅니다. CI 시스템을 써서 코드 베이스에 대해 이런 규칙이 자동으로 지켜

지게 할 수 있습니다. 7장에서는 다양한 도구와 기법을 논의하고 보여줄 것입니다.

그림 1-7의 소프트웨어 검사 보고서 예제는 자바 코드를 검사하는 Checkstyle을

이용해 생성했습니다. 이 같은 보고서를 사용하면 코딩 표준과 품질 메트릭을 지속

적으로 모니터링할 수 있습니다.

목록 1-8은 Checkstyle 같은 정적 코드 분석 도구를 Ant와 함께 사용하는 예제를

보여줍니다. 이 예제는 그림 1-7의 보고서를 생성합니다.

그림 1-7 ㅣ Checkstyle를 사용하여 자동 생성한 검사 보고서

Page 52: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

Continuous Integration

��

목 록 1-8 | Ant를 사용한 Checkstyle 예제 4) 4)

<target name="run-inspections">

<taskdef resource="checkstyletask.properties"

classpath="${checkstyle.jar}"/>

<checkstyle config="${basedir}/checkstyle-rules.xml"

failOnViolation="false">

<formatter toFile="${checkstyle.data.file}" type="xml" />

<fileset dir="${src.dir}" includes="**/*.java" />

</checkstyle>

<xslt taskname="checkstyle"

in="${checkstyle.data.file}"

out="${checkstyle.report.file}"

style="${checkstyle.xsl.file}" />

</target>

배포

상당수 빌드 과정은 일종의 배포 과정이라 할 수 있습니다. 사실, 이 장에서 논의된

각 작업 과정 역시 배포 과정의 일부라고 할 수 있습니다. 배포를 지속적으로 하면 어

느 순간이라도 실제로 작동하는 소프트웨어를 배포할 수 있습니다. CI 시스템의 핵

심 목표는 항상 최근 코드를 가지고 소프트웨어를 빌드하고 테스트하는 것입니다.

무엇보다도, 버전 관리 저장소에서 소스 파일을 체크아웃하고, 빌드를 수행하고,

테스트와 검사를 전부 성공시키고, 릴리즈에 꼬리표를 붙이며, 배포 파일을 잘 꾸며

야 합니다.

CI를 이용하면 그림 1-8처럼 파일을 적절한 환경에 자동으로 배포하거나 설치할

수도 있습니다. 더욱이, 배포에는 배포할 때 적용된 모든 변경 사항을 자동으로 되

돌리는 능력이 있어야 합니다. 주의하세요. 개발할 때의 운영 환경(그림 1-8에 묘사

된 Jetty를 예로 들자면)은 통합 환경이나 테스트 환경(Tomcat)과는 약간 다를지도 모

릅니다. 여하튼, 매개변수만 약간 다를 뿐인 자동화된 빌드가 운영 환경이나 통합

및 테스트 환경에서 실행됩니다. 우리는 8장에서 이 같은 전략을 논의합니다.

4) 폴 듀발이 2006년 8월자 IBM developerWorks에 발표한 ‘사람을 위한 자동화: Continuous Inspection’이 출처입니다.

http://www.ibm.com/developerworks/kr/library/j-ap08016/

Page 53: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

��

chapter1 시작하기

그림 1-8 ㅣ 배포 환경

목록 1-9는 Ant와 웹 컨테이너 간의 인터페이스를 제공하는 Cargo란 도구를 사용하

는 걸 보여줍니다. 이 경우에는 Tomcat 서버에 배포를 합니다. Cargo는 시장에 나

온 유명한 웹 컨테이너 다수를 지원합니다.

목 록 1-9 | Ant와 Cargo를 이용해서 Tomcat에 배포한다

<target name="deploy">

<cargo containerId="tomcat5x" action="start"

wait="false" id="${tomcat-refid}">

<zipurlinstaller installurl="${tomcat-installer-url}"/>

<configuration type="standalone" home="${tomcatdir}">

<property name="cargo.remote.username" value="admin"/>

<property name="cargo.remote.password" value=""/>

<deployable type="war" file="${wardir}/${warfile}"/>

</configuration>

</cargo>

</target>

Page 54: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

Continuous Integration

20

문서화와 피드백

많은 개발자들이 문서는 소스 코드에 있는 법이라고 굳게 믿으며 일하는데, 사실 잘

선택한 클래스, 변수, 메소드 이름으로 무장한 깔끔하고 간명한 코드야말로 최고의

문서라 하겠습니다. 지속적인 통합 시스템은 고생하지 않아도 문서화의 이점을 제

공해줄 수 있습니다. Maven, Javadoc, NDoc 같은 도구를 이용하면 문서를 생성할

수 있습니다. 이뿐만 아니라 클래스 다이어그램과 기타 정보를 생성할 수 있는 도구

도 있는데, 모두가 버전 관리 저장소에 커밋된 소스 코드를 기반으로 삼습니다. 여

러분은 지속적인 통합 시스템을 활용하여 소스 코드와 프로젝트 상태 문서화를 실

시간에 획득했을 때 얻게 되는 어마어마한 이점을 알게 될 겁니다. 사람에 따라선

문서 산출물을 지속적으로 생성하기보단 주기적으로 생성하기로 결정하는 경우도

있을 겁니다.

좋은 CI 시스템의 핵심적인 특징은 속도입니다. 지속적인 통합 시스템의 정수는

개발자와 프로젝트 이해관계자들에게 시의 적절하게 피드백을 제공하는 겁니다. 지

속적인 통합 시스템에 이것저것 끼워 넣다보면(완벽하게 하려고), 한 주기를 끝마치

는 데 말도 안 되는 시간이 걸리기 쉽습니다. 그러니 결과를 신속하게 제공해야 할

필요성과 지속적인 통합 프로세스의 폭과 깊이 사이에서 균형을 잡아야 합니다. 이

것은 지속적인 테스트를 활용할 때 특히 중요합니다. 우리는 4장과 6장에서 빠른 빌

드를 만드는 기법에 대해 논의합니다.

Page 55: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

2�

chapter1 시작하기

요약

이 장에서는 지속적인 통합의 특징을 개략적으로 알아봤습니다. 그리고 포

괄적인 데이터베이스 통합, 테스트, 검사, 배포, 피드백과 같은 추가적인 프

로세스를 지속적인 통합 시스템에 집어넣는 방법도 살펴보았습니다. 이 책

의 나머지 부분에서는 지속적인 통합을 사용한 소프트웨어 개발과 연관 지

어 이러한 프로세스를 하나씩 구체적으로 들여다 볼 것입니다.

질문

지속적인 통합을 올바르게 수행하고 있는지 어떻게 알 수 있을까요? 다음과

같은 질문을 통해 프로젝트에 무엇이 부족한지 파악할 수 있습니다.

버전 관리 저장소(소프트웨어 형상 관리 도구)를 사용합니까?

빌드 과정이 자동화되고 똑같이 반복될 수 있습니까? 사람이 개입하지 않아도 빌드 과

정이 완전히 작동합니까?

자동화된 테스트를 작성해서 돌립니까?

빌드 과정의 일부로써 테스트를 실행합니까?

코딩 및 설계 표준을 어떻게 강제합니까?

자동화시킨 피드백 메커니즘에는 어떤 게 있습니까?

소프트웨어를 빌드할 때 별도의 통합 빌드 머신을 사용합니까?

2�

Page 56: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

22

P {[ }

] |\

“‘ Integrate

?/

Shift

22

Page 57: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

23

경력을 쌓던 초창기에, 어떤 기술을 사용하든지 간에 좋은 소프트웨어를 개발하려

면 결국 기본적인 실천 방법을 일관되게 수행하는 게 중요하다는 걸 배웠습니다. 제

경험에 따르면, 소프트웨어 개발에서 가장 심각한 문제 중 하나는 설익은 ‘가정’입니

다. 메소드의 매개변수들이 항상 정상적으로 넘어올 거라 가정한다면, 그 메소드는

실패할 겁니다. 모든 개발자들이 코딩 및 설계 표준안을 철저하게 지킬 것이라고 가

정해보세요. 그러면 유지보수하기에 최악인 소프트웨어가 나올 겁니다. 설정 파일

은 전혀 변경된 적이 없을 거라 가정해보세요. 그러면 귀중한 개발 시간을, 있지도

않은 문제를 디버깅하면서 날리고 말 것입니다. 소프트웨어 개발 시에 가정을 한다

면, 시간을 낭비하고 위험을 키우게 됩니다.

■ 코드를 자주 커밋하세요

■ 깨진 코드를 커밋해선 안 됩니다

■ 빌드가 깨지면 즉시 고치세요

■ 자동화된 개발자 테스트를 작성하세요

■ 모든 테스트와 검사를 통과해야 합니다

■ 개인 빌드를 돌리세요

■ 깨진 코드는 가져오지 마세요

chapter2 지속적인 통합 도입하기

억측은 일을 망치는 근원이다

- 웨던의 ‘판단 보류의 법칙’

P {[ }

] |\

“‘ Integrate

?/

Shift

Page 58: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

Continuous Integration

2�

☆ 가정을 줄이기

지속적인 통합은 버전 관리 시스템에 변경 사항이 적용될 때마다 소프트웨어를 다시

빌드함으로써 가정을 줄이는 데 도움이 될 수 있습니다.

가장 최신의, 가장 훌륭한 기술이 ‘은 탄환’(늑대인간을 한방에 잡는 탄환, 묘책, 특

효약의 뜻-역주)이 되어 모든 문제를 해결해 줄 것처럼 보이지만, 그런 일은 절대

로 일어나지 않습니다. 제가 회사 업무로 처음에 맡은 일 중 하나는 좋은 소프트웨

어 개발 실천 방법을 도입하는 것이었습니다. 우리는 좋은 소프트웨어를 개발하기

위해 널리 수용된 여러 가지 실천 방법을 이행해나갔습니다. 서로 다른 방법론을

사용하는 다양한 프로젝트를 접해보니, 제게는 반복적인 접근방법-애자일 실천 방

법-이 효과가 가장 좋았습니다. 프로젝트가 진행되는 내내 위험이 경감되어 나가

기 때문입니다. 소프트웨어를 개발할 때는 변경 계획을 수립하고, 지속적으로 그

결과를 관찰하며, 결과에 따라 점진적으로 진로를 수정해나가야 합니다. 이것이야

말로 지속적인 통합(Continuous Integration, CI)이 작동하는 방식입니다. 지속적인 통합은

소프트웨어를 변경할 능력을 개발자인 우리에게 부여하는 전술들을 한데 모은 것

이며, 소프트웨어가 깨지면 즉각적인 피드백을 받을 거라고 확신하게 해줍니다.

이렇게 피드백을 즉각 받기 때문에 진로를 수정하고 조정하여 문제를 더 빨리 고

칠 수 있습니다.

지속적인 통합은 개발의 근본에 관한 겁니다. 소프트웨어 개발에서 눈에 띄는 가

장 영광스러운 작업은 아닐지 몰라도, 소프트웨어를 통합하는 일은 오늘날의 복잡

한 프로젝트에선 극히 중요합니다. 소프트웨어의 사용자가 이렇게 말하는 경우는

좀처럼 없습니다. “우와, 최근에 릴리즈할 때 당신이 소프트웨어를 통합하는 방식은

정말 멋졌습니다.” 이런 일이 없다 보니, 무대 뒤에서 이런 노력을 기울일 가치가 있

을까 싶을 수도 있습니다. 하지만, CI와 같은 실천 방법을 써서 소프트웨어를 개발

하는 사람이라면, 소스 관리 저장소에 변경 사항이 들어올 때마다 시작되는 일관성

있고 반복 가능한 빌드 프로세스에게서 힘을 얻습니다.

Page 59: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

2�

chapter2 지속적인 통합 도입하기

☆ CI, 품질의 핵심.

지속적인 통합을 단순히 각 소프트웨어 컴포넌트를 한데 모으는 과정에 불과하다고 생

각하는 사람도 있지만, 우리는 CI를 소프트웨어 개발의 핵심이라고 생각합니다. 왜냐

하면 코드가 변경될 때마다 빌드를 돌림으로써 CI가 소프트웨어의 품질을 지켜주기 때

문입니다. 최신 통합빌드를 확인하기만 하면 현재 작업중인 소프트웨어의 품질을 확인

할 수 있습니다.

소프트웨어 개발에 있어 화려하진 않지만 기본이 되는 활동에 시간을 약간만 투자

하면, 우리가 하는 일을 흥미롭고 재미있게 해줄, 도전적이며 생각하게 하는 활동에

더 많은 시간을 쏟을 수 있습니다. 만약 개발 환경을 정의하고 소프트웨어를 빌드하

는 것 같은 기본에 집중하지 않으면, 나중에 저수준의 업무를 수행해야 할 겁니다.

그것도 가장 여유가 없을 때(소프트웨어를 출시하기 바로 직전이라든가) 그런 일이

벌어지기 마련이죠. 이럴 때는 실수를 저지르기 마련입니다. 빌드를 항상 ‘정상’ 상

태로 유지하는 훈련을 해두면, 뭔가 잘못된 것은 없는지 걱정하지 않아도 됩니다.

이는 운동과 비슷합니다-네, 맞습니다. 자기 수양이 필요합니다-하지만 이렇게 하면

정말 중요할 때 큰 경기에서 제대로 힘을 발휘할 수 있습니다.

이 장에선 프로젝트에서 지속적인 통합의 실천 방법을 실행하기로 결정을 내릴

때 고민할 만한 의문점에 대한 답변을 제시할 것입니다. 지속적인 통합의 장점과 단

점을 간략히 알아보고 지속적인 통합이 다른 소프트웨어 개발 실천 방법을 어떻게

보완해주는지 다룹니다. 지속적인 통합은 프로젝트의 ‘빌드 마스터’에게 맡겨버리

고 잊어버릴 수 있는 그런 실천 방법이 아닙니다. 지속적인 통합은 소프트웨어 개발

팀 모두에게 영향을 미치며, 그렇기에 우리는 팀 구성원 전원이 익혀서 실천해야 할

기법이라는 관점에서 지속적인 통합을 논의합니다.

CI를 사용하면 하루 일과가 어떨까요? 톰의 경험담을 살펴보도록 하겠습니다.

지속적인 통합과 함께 하는 하루 일과

톰이 문을 열고 회사 사무실에 들어서자, 실시간 프로젝트 정보를 펼쳐놓은 와이드

스크린 모니터가 눈에 들어옵니다. 모니터는 몇 분 전에 CI 서버가 마지막 통합 빌

드를 성공리에 마쳤음을 보여줍니다. 모니터는 가장 최근의 품질 목록을 도표로 보

Page 60: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

Continuous Integration

2�

여주는데, 여기에는 코딩 및 설계 표준 준수, 코드 중복 등이 포함됩니다. 톰은 온라

인 맥주 판매사를 위해 관리용 소프트웨어를 만드는 자바 프로젝트에 참여하고 있

는 15명의 개발자 중 한 명입니다. 그림 2-1에 톰의 일과에 벌어지는 활동이 일부 나

와있습니다.

하루 일이 시작되면, 톰은 CI 서버가 보내온 최신 보고서를 참고하여 중복 코드가

아주 많다고 보고된 부분을 리팩토링합니다. 서브버전에 고친 코드를 커밋하기에

앞서, 톰은 개인 빌드를 돌려 최신 소스 코드를 컴파일하고 단위 테스트를 돌립니다.

자신의 컴퓨터에서 빌드를 돌리고 나면 변경 사항을 서브버전에 커밋해 넣습니다.

그 와중에도 CruiseControl CI 서버는 서브버전 저장소를 폴링하고 있습니다. 몇 분

후에, CI 서버가 톰이 커밋해 넣은 변경 사항을 발견하고 통합 빌드를 돌립니다. 이

렇게 실행된 통합 빌드는 자동화된 검사 도구를 돌려서 모든 코드가 코딩 표준을 준

수했는지 여부를 가려냅니다. 톰은 코딩 표준 위반을 알리는 이메일을 받았고, 재빨

리 코드를 고쳐서 소스 코드를 다시 서브버전에 체크인합니다. CI 서버는 다시 한

번 빌드를 돌리고, 이번에는 성공합니다. CI 서버가 생성한 웹 기반 보고서를 검토

함으로써, 톰은 자신이 최근에 수행한 코드 리팩토링이 하위시스템에 있는 중복 코

드의 양을 성공적으로 줄여냈음을 확인합니다.

그림 2-1 ㅣ 하루 일과

Page 61: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

2�

chapter2 지속적인 통합 도입하기

그날 늦게, 프로젝트에 참여한 또 다른 개발자인 리사가 톰의 사무실로 뛰어들어

옵니다.

리사: 오늘 아침에 톰이 변경한 코드가 마지막 빌드를 깨뜨린 듯한데요.

톰: 흠… 하지만 테스트를 돌려봤는걸요.

리사: 아, 시간이 부족해서 테스트를 작성하지 못했어요.

톰: 우리가 수립했던 코드 적용범위 메트릭을 지키고 있어요?

이 토론이 있은 후, 톰과 리사는 코드 적용범위가 85% 이하이면 통합 빌드를 실패

처리하기로 결정했습니다. 리사는 결함을 테스트하는 코드를 짰고, 자신이 발견한

문제를 고쳤습니다. 톰과 대화를 나눈 덕분이죠. 통합 빌드는 ‘정상’ 상태를 유지해

나갔습니다.

★ 업계 용어

자동화된 – ‘무인’ 프로세스. 일단 완전히 자동화된 프로세스가 시작되고 나면, 사람이

간섭할 필요가 없습니다. 시스템 관리자는 이를 두고 ‘머리 없는(headless)’ 프로세스

라 부릅니다.

빌드 – 소프트웨어를 생성하고 테스트하고 검사하며 배포하기 위해 수행하는 행위의

집합

지속적인 – 엄밀히 말하자면, 지속적이라 하면 일단 시작되면 절대 멈추지 않는 것을 뜻

합니다. 이렇게 보면 빌드가 줄곧 돌아간다는 뜻이 됩니다. 하지만 이런 뜻은 아닙니다.

‘지속적인’이라 함은 CI의 문맥에서 봤을 때 ‘빈번하다’란 뜻에 가깝고, CI 서버의 경우엔

프로세스 하나가 떠서 버전 관리 저장소에 변경 사항이 들어오는지 계속해서 폴링합니다.

지속적인 통합 – 팀 구성원들이 자기가 한 일을 자주 통합하는 소프트웨어 개발 실천 방

법인데, 보통 각자가 적어도 하루에 한 번은 통합을 하며 결과적으로 하루에 여러 번 통합

을 하게 됩니다. 각 통합은 자동화된 빌드(테스트 코드를 포함한)가 검증하여 통합 오류를

최대한 신속하게 탐지해냅니다. 여러 팀이 이 같은 접근 방식을 통해 통합할 때 발생하는

문제를 극적으로 줄였으며, 응집력 있는 소프트웨어를 보다 재빨리 개발해냈습니다.1)

1) 출처: www.martinfowler.com/articles/continuousIntegration.html.

Page 62: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

Continuous Integration

2�

개발 환경 – 소프트웨어를 작성하는 환경을 말합니다. 개발 환경에는 IDE, 빌드 스크립

트, 도구, 외부 라이브러리, 서버, 설정 파일이 들어갑니다.

검사 – 내부적인 품질 특성을 파악하기 위한 소스 코드 또는 바이트코드 분석. 이 책의

문맥에서는, 자동화된 측면(정적 및 런타임 분석)을 소프트웨어 검사라고 일컫습니다.

통합 – 별도의 소스 코드 산출물을 하나로 합쳐, 그것들이 전체로써 잘 작동하는지 확인

하는 행위를 말합니다.

통합 빌드 – 통합 빌드는 소프트웨어 컴포넌트(프로그램과 파일들)를 하나의 소프트웨

어 시스템으로 합치는 행위를 말합니다. 통합 빌드에는, 프로젝트가 크다면 컴포넌트 여

러 개가 들어가기도 하며, 좀더 작은 프로젝트라면 저수준의 컴파일된 소스 파일만이 들

어갑니다. 일상 생활에서 우리는 빌드와 통합 빌드라는 용어가 마치 같은 말인 양 사용하

는 경향이 있지만, 이 책에서는 별도의 통합 빌드 컴퓨터에서 수행하는 경우만 통합 빌드

라 분류합니다.

개인 (시스템) 빌드 – 자신이 변경한 코드를 버전 관리 저장소에 커밋해 넣기 전에 로컬

컴퓨터에서 빌드를 수행하여, 방금 고친 코드 때문에 통합 빌드가 깨질 가능성을 줄입니

다.2)

품질 – 무료 온라인 컴퓨터 사전인 http://thefreedictionary.com/에서는 품질을

‘어떤 것의 본질적이고 다른 것과 구별해주는 특성’ 또는 ‘우수한 등급’이라고 정의합니다.

품질이란 용어는 남용될 때가 많고 품질이란 인식에 따라 달라질 수 있는 것이라 생각하

는 사람도 있습니다. 이 책에서 우리는 품질을 다른 것과 마찬가지로 측정할 수 있는 명

세라는 입장을 취합니다. 이는 유지보수성, 확장성, 보안, 성능, 가독성과 같은 특정한

품질 메트릭을 파악할 수 있다는 뜻입니다.

릴리즈 빌드 – 사용자에게 출시할 목적으로 소프트웨어를 준비합니다. 릴리즈 빌드는

각 주기 끝이나 다른 이정표에서 이뤄질 수도 있습니다. 그리고 릴리즈 빌드에는 인수 테

스트가 포함되어야 하며, 더 방대한 성능 및 부하 테스트가 포함될 수도 있습니다.

위험 – 문제가 발생할 잠재성을 말합니다. 현실화된 위험을 ‘문제’라 합니다. 우리는 가

장 일어날 법한, 좀더 우선 순위가 높은 위험(우리의 관심사와 목적에 해를 끼치는)에 집

중하게 됩니다.

2) Stephen Berczuk 와 Brad Appleton의 저서 Software Configuration Management Patterns 에서 인용했습니다.

Page 63: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

2�

chapter2 지속적인 통합 도입하기

지속적인 통합에는 어떤 가치가 있을까요?

크게 보면, CI에는 다음과 같은 가치가 있습니다.

위험을 줄여준다.

반복적인 수작업을 줄여준다.

언제 어느 때라도 배포할 수 있는 소프트웨어를 생성해낸다.

프로젝트 가시성을 보다 좋게 해준다.

개발 팀이 소프트웨어 제품에 대해 보다 큰 자신감을 갖게 해준다.

이러한 항목들이 무엇을 뜻하는지, 그리고 어떤 가치가 있는지 검토해보도록 하죠.

위험을 줄여줍니다

매일 여러 번 통합하면 프로젝트상의 위험을 줄일 수 있습니다. 이렇게 하면 결함의

발견, 소프트웨어 건강 측정, 그리고 가정의 감소를 촉진시킵니다.

결함을 발견하고 보다 조기에 수정합니다 – 하루에도 몇 번씩 테스트와

검사를 통합하고 돌리기 때문에, 개발 주기 후반에 이뤄지는 테스트 과정에서

가 아닌 결함이 생길 때(예를 들어 코드가 버전 관리 저장소에 체크인될 때)

이를 발견할 가능성이 커집니다.

소프트웨어 건강 상태를 측정할 수 있습니다 – 지속적인 테스트와 지속적

인 검사를 자동화된 통합 프로세스에 넣으면, 복잡도와 같은 소프트웨어 제품

의 건강을 나타내는 속성을 시간 흐름에 따라 추적할 수 있습니다.

테스트 – 소프트웨어가 설계된 대로 작동하는지 검증하는 일반적인 프로세스를 말합니다.

여기에 더해, 개발자 테스트를 객체, 패키지, 모듈, 소프트웨어 시스템이 설계한 대로 작

동하는지 확인하는 단위 테스트, 컴포넌트 테스트, 시스템 테스트와 같은 여러 범주로 나

눠 정의합니다. 기능 테스트나 부하 테스트 같이 여러 종류의 테스트가 있지만, CI의 관

점에서 보면 개발자가 작성하는 모든 단위 테스트는 빌드의 일부로써 실행됩니다(빌드에

따라 빠른 테스트를 먼저 돌리고, 뒤이어 느린 테스트를 돌리게 조작하기도 합니다).

Page 64: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

Continuous Integration

30

가정을 줄입니다 – 똑같은 프로세스와 스크립트를 사용하여 주기적으로 깨

끗한 환경에서 소프트웨어를 다시 빌드하고 테스트하면, 가정(외부 라이브러

리나 환경 변수가 얼마나 있든지 간에)을 줄일 수 있습니다.

지속적인 통합은 결함이 코드 베이스에 들어올 위험을 줄여줄 안전망을 제공합니다.

다음에 CI가 도움이 될 만한 위험 요소가 제시되어 있습니다. 다음 장에서 이러한

위험 요소뿐만 아니라 다른 위험 요소에 대해서도 논의하겠습니다.

응집력 있고 배포 가능한 소프트웨어의 부재

뒤늦은 결함 발견

저품질의 소프트웨어

프로젝트 가시성의 부재

반복적인 프로세스를 줄여줍니다

반복적인 프로세스를 줄이면 시간, 비용, 노력을 아끼게 됩니다. 뻔한 소리 같죠? 그

렇지 않습니까? 이 같은 반복적인 프로세스는 코드 컴파일, 데이터베이스 통합, 테

스트, 검사, 배포, 피드백을 비롯해 프로젝트 활동 전반에 걸쳐 일어납니다. 지속적

인 통합을 자동화하면, 다음에 제시된 모든 것을 보장할 수 있는 능력을 키울 수 있

습니다.

프로세스가 매번 동일한 방식으로 돌아갑니다.

순서에 맞춰 프로세스가 수행됩니다. 이를테면, 테스트를 돌리기에 앞서 검사

(정적 분석)부터 돌리게끔 빌드 스크립트를 작성할 수도 있습니다.

버전 관리 저장소에 커밋이 일어날 때마다 정해진 프로세스가 돌아갑니다.

이렇게 하면 다음과 같은 점을 촉진시키게 됩니다.

반복적인 프로세스에 들이는 노동력을 줄여서 사람들이 좀더 흥미롭게 생각

하는, 보다 가치가 높은 일을 하게 해줍니다.

테스트와 데이터베이스 통합과 같이 중요한 프로세스에 대해 자동화된 메커

니즘을 사용함으로써, 개선을 이뤄내는 것에 대한 저항(다른 팀 구성원의)을

극복할 수 있게 됩니다.

Page 65: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

3�

chapter2 지속적인 통합 도입하기

배포할 수 있는 소프트웨어를 생성합니다

지속적인 통합은 어느 때라도 배포 가능한 소프트웨어를 출시할 수 있게 해줍니다.

외부에서 볼 때, 이것이야말로 CI의 가장 분명한 이점이라 하겠습니다. 향상된 소프

트웨어 품질과 줄어든 위험에 대해 끊임없이 말할 수야 있겠지만, 배포 가능한 소프

트웨어야말로 고객이나 사용자 같은 ‘외부인’에게는 가장 손에 잘 잡히는 자산입니

다. 이 점이 얼마나 중요한지는 아무리 강조해도 모자랍니다. CI를 적용하면, 소스

코드를 조금씩 고치고 이렇게 고친 것을 주기적으로 코드 베이스의 나머지 부분과

통합하게 됩니다. 만약 문제가 발생하면, 프로젝트 관련자가 그 사실을 알게 되고

수정한 코드를 소프트웨어에 즉시 적용하게 됩니다. 이러한 실천 방법을 포용하지

않는 프로젝트라면 소프트웨어를 전달하기 바로 직전까지 기다려서야 소프트웨어

를 통합하고 테스트하게 됩니다. 이렇게 되면 출시가 늦어지거나, 특정 결함을 고치

는 게 늦어지거나 아예 고치지 못할 수 있고, 서둘러 완성하려다 새로운 결함을 만

들어낼 수도 있으며, 궁극적으론 프로젝트를 제대로 마무리 못하게 될 수 있습니다.

프로젝트 가시성을 더 높입니다

지속적인 통합은 추세를 인지하고 효율적인 결정을 내릴 수 있게 해주고, 새로운 개

선을 혁신해내기 위한 용기를 주는 데 도움을 줍니다. 결정을 내리는 데 도움이 될

실제적인 데이터가 없거나 최근 데이터가 없다면 프로젝트가 고통받게 되며, 사람

들 모두가 최선을 다해 자신만의 짐작을 하게 됩니다. 보통 프로젝트 구성원들은 이

런 정보를 직접 수집하는데, 고되게 일하고도 시기를 놓치기 마련입니다. 그 결과

정보 자체가 아예 수집되지 않기도 합니다. CI는 다음과 같은 긍정적인 효과가 있습

니다.

효과적인 의사결정 – 지속적인 통합 시스템은 최근 빌드 상태와 품질 메트

릭에 관한 정보를 시의 적절하게 제공할 수 있습니다. 어떤 CI 시스템은 결함

률과 기능 완료 상태를 보여줄 수도 있습니다.

추세 인지 – 지속적인 통합 시스템이 있으면 통합을 자주하기 때문에 빌드

성공 여부나 실패 여부, 전체적인 품질, 그 밖의 관련 정보의 추세를 인지할

수 있는 능력이 생깁니다.

Page 66: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

Continuous Integration

32

제품에 대해 보다 큰 자신감을 갖게 됩니다

전반적으로, CI 실천 방법을 효과적으로 응용하게 되면 소프트웨어 제품을 생산해

내는 일에 보다 큰 자신감을 갖게 됩니다. 팀은 매 빌드마다 소프트웨어에 대해 테

스트를 돌려서 행동을 검증한다는 걸 알 것이고, 프로젝트 코딩 및 설계 표준이 충

족됐다는 것도 알게 되며, 기능적으로 테스트 가능한 제품을 얻게 된다는 것도 알게

됩니다.

통합을 자주 하지 않으면 자신이 변경한 코드가 미치는 영향력을 알 수 없어 갑갑

해 할 팀도 있을 겁니다. 뭔가 잘못됐을 때 CI 시스템이 그 사실을 알려줄 테니 개발

자와 다른 팀 구성원은 보다 자신감 있게 코드를 변경할 수 있게 됩니다. CI는 모든

소프트웨어 자신을 한 출처에 모아둘 것을 권장하기 때문에, 그 정확성에 대해서도

훨씬 자신할 수 있습니다.

지속적인 통합을 왜 도입하지 못할까요?

CI가 이점이 많다면, 소프트웨어를 지속적으로 통합하지 못하는 개발팀은 뭐가 문

제일까요? 여러 문제가 꼬였을 때가 많습니다.

CI 시스템을 유지보수하기 위한 추가적인 과부하 – 이는 보통 잘못된 인

식입니다. CI를 쓰건 쓰지 않건, 통합하고 테스트하고 검사하고 배포해야 할

필요가 있기 때문입니다. 견고한 CI 시스템을 관리하는 편이 사람이 직접 관

리하는 것보다 낫습니다. CI 시스템을 관리하거나, 그게 싫다면 수작업을 반

복하는 수밖에 없습니다. 아이러니하게도, 복잡한 다중플랫폼 프로젝트야말

로 CI가 가장 필요한 프로젝트인데도 불구하고, 이런 프로젝트에서는 “추가

작업이 너무 많아요” 하며 반대하기 일쑤입니다.

변경할 게 많음 – 진행 중인 프로젝트에 지속적인 통합을 도입하려면 변경

해야 할 프로세스가 너무 많다고 느끼는 사람도 있습니다. CI에 대해 점진적

으로 접근하는 것이 가장 효과적입니다. 먼저 빌드와 테스트를 좀더 낮은 빈

도(예를 들자면, 일일 빌드 정도로)로 실행하게 하고 나서, 사람들이 그 결과

에 익숙해지면 주기를 짧게 하는 겁니다.

빌드 실패 횟수가 너무 많음 – 보통 이런 일은 개발자들이 자기 코드를 버

전 관리 저장소에 커밋하기에 앞서 개인 빌드를 수행하지 않아서 벌어집니다.

Page 67: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

33

chapter2 지속적인 통합 도입하기

개발자가 깜박 잊고 파일 하나를 체크인하지 않았거나, 테스트 몇 개가 실패

하는 경우일 수 있습니다. 변경 주기가 짧은 만큼 CI를 사용할 때는 신속한 반

응이 필수입니다.

추가적인 하드웨어 및 소프트웨어 비용 – CI를 효과적으로 사용하려면, 별

도의 통합 컴퓨터가 있어야 하는데, 이는 개발 종료 막판에 문제가 생겨 발생

하는 값비싼 비용에 비하면 그야말로 새 발의 피입니다.

개발자들이 이런 활동을 수행해야 합니다 – CI가 어쨌거나 개발자들이 해

야 할 일을 두 번씩 하게 만드는 것처럼 관리층이 느낄 때도 있습니다. 맞습니

다. 개발자들은 일부 활동을 두 번 수행해야 할 겁니다. 하지만 사람들은 그런

일을 분리된 환경에서 보다 효율적이고 안정적으로 수행해야 합니다. 자동화

된 도구를 활용하면 이런 활동의 효율과 빈도를 개선할 수 있습니다. 이뿐 아

니라, 자동화된 도구를 쓰면 깨끗한 환경에서 이런 활동이 수행되는 게 보장

되어, 가정을 줄이고 보다 나은 의사 결정을 할 수 있게 됩니다.

'지속적인' 통합을 도입하려면 어떻게 해야 할까요?

개발 조직들 대부분의 자동화 수준을 알게 되면 놀라기 마련입니다. 개발자들은 열

심히 고객의 업무를 자동화하려고 하지만, 정작 자신의 개발 작업 프로세스를 자동

화할 방법은 잘 찾지 못합니다. 개발 프로세스 일부만을 자동화해주는 스크립트 몇

개로 충분히 자동화했다고 믿는 팀도 있습니다. 대부분 이런 식으로 전개가 됩니다.

조안 (개발자): 그건 벌써 자동화했습니다. 데이터베이스 테이블을 삭제하고 다

시 만드는 배치 스크립트를 작성해놨죠.

수 (기술 리더): 좋은데요. 배치 스크립트를 CVS 저장소에 적용해놨나요?

조안: 아뇨.

수: 그럼 빌드 스크립트에 포함시켰나요?

조안: 아뇨.

수: 그럼, CI 시스템의 일부가 아니라면 정말 자동화된 거라 할 수는 없죠? 안 그

래요?

Page 68: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

Continuous Integration

3�

지속적인 통합은 스크립트 몇 개를 긁어 모아서 상시 돌리는 단순한 프로세스가 아

닙니다. 앞선 시나리오에서 조안이 자동화 스크립트를 작성한 것은 훌륭했지만, 그

렇게 만든 스크립트가 최종 제품에 진정으로 가치를 더하기 위해선, 그 스크립트를

버전 관리 저장소에 추가하고 빌드 프로세스의 실질적인 일부로 만들어야 합니다.

그림 2-2는 한 프로세스를 지속적으로 만들기 위해 취해야 할 조치를 묘사합니다.

이 같은 조치는 프로젝트에서 여러분이 행하는 모든 활동에 대해 하나씩 적용할

수 있습니다.

식별하기(Identify) – 자동화해야 할 프로세스를 파악하세요. 자동화해야 할

프로세스는 컴파일, 테스트, 검사, 배포, 데이터베이스 통합이나 그 밖의 영역

에도 있을지 모릅니다.

빌드(Build) – 빌드 스크립트를 만들어 반복 가능하고 일관성 있게 자동화합

니다. 빌드 스크립트는 닷넷 플랫폼용 NAnt, 자바 플랫폼용 Ant, 루비용 Rake

나 이와 비슷한 다른 도구로 구성할 수 있습니다.

공유하기(Share) – 서브버전 같은 버전 관리 시스템을 사용하면, 이렇게 만든

스크립트나 프로그램을 다른 사람도 사용할 수 있습니다. 이렇게 하면 그 가

치가 프로젝트 내내 지속적으로 전파되게 될 겁니다.

지속적으로 돌아가게 만들기(Make it continuous) – CI 서버를 이용해서, 변경

사항을 적용할 때마다 자동화된 프로세스가 돌아가게 하세요. 팀이 잘 훈련되

어 있다면, 버전 관리 시스템에 변경이 적용될 때마다 직접 빌드를 돌리는 방

법을 선택할 수도 있습니다.

기억이나 의사소통이 용이하도록, 파악하기(Identify), 빌드하기(Build), 공유하기(Share),

지속적으로 하기(Continuous)의 첫 글자를 따서 다음과 같은 문장을 만들어보았습니다.

“I Build So Consistently”

그림 2-2 ㅣ CI 구축하기 - IBSC, I Build So Consistently

Page 69: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

3�

chapter2 지속적인 통합 도입하기

CI 시스템을 조금씩 성장시켜나가는 걸 목표로 삼으세요. 이렇게 해야 구축하기 간

단하고, 새로운 항목이 추가되면 팀이 좀더 동기 부여를 받게 되며, 여태까지 뭐가

효과적이었는지에 따라 다음에 무엇을 추가할지 제대로 계획을 세울 수 있습니다.

당장 모든 걸 CI 시스템에 쑤셔 넣으려고 하면 일이 꼬일 수 있습니다. 소프트웨어

를 작성할 때 많은 양의 코드를 한 번에 리팩토링하는 게 최선의 접근 방법이 아닌

것처럼요. 우선 돌아가게 만들고, 개발자들이 CI를 사용하게 만든 다음에 프로젝트

의 위험 요소를 근거로 하여 다른 자동화된 프로세스를 추가하세요.

언제, 어떻게 프로젝트에 지속적인 통합을 도입해야 할까요?

프로젝트 초기에 CI를 구축하는 게 최선입니다. 가능하긴 해도, 프로젝트가 한참 진

행 중일 때 CI를 구축하하려면 더 힘듭니다. 사람들이 압박을 받고 있을테고, 변화

에 저항하기 십상입니다. 프로젝트 후반에 CI를 구축한다면, 무엇보다도 작은 것부

터 시작해서 시간이 있을 때 좀더 추가하는 게 중요합니다.

★ 지속적인 컴파일인가요? 아니면 지속적인 통합인가요?

지속적인 통합을 구축하려는 여러 조직에서 일해봤는데, “네, 우리는 지속적인 통합을

합니다.”라는 대답을 들은 적이 여러 차례 있었습니다. 물론 저는 “훌륭한 걸!”하고 생각

하고 질문을 던졌습니다. 테스트 코드로 얼마나 많은 코드 적용범위를 달성하나요? 빌드

를 돌리는 데 얼마나 걸리나요? 평균적인 코드 복잡도는 얼마나 되나요? 코드 중복은 얼

마나 있나요? 버전 관리 저장소에 있는 빌드에 꼬리표(Label)를 붙이고 있나요? 배포된

소프트웨어는 어디에 저장하나요?

사람들이 여태까지 해온 게 ‘지속적인 컴파일’에 가깝다는 걸 알게 됐는데, CruiseControl

같은 도구를 설치해서 변경 사항이 있는지 버전 관리 저장소(CVS 같은)를 폴링하는 정

도였습니다. 변경 사항을 탐지하면, CruiseControl 같은 도구가 CVS에서 소스 코드

를 가져와서 코드를 컴파일하고, 문제가 발생했을 때는 이메일을 보냅니다. 별도의 컴퓨

터에서 소프트웨어 시스템을 자동으로 컴파일하는 편이 아무 것도 안 하는 것보단 낫습니

다. 하지만 그렇게 해서는 완전히 기능을 갖춘 CI 시스템이 주는 모든 혜택을 받을 수는

없습니다.

Page 70: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

Continuous Integration

3�

CI 시스템을 구축하는 접근 방법은 많습니다. 목표는 시스템에 변경사항이 있을

때마다 빌드를 돌리는 것이더라도, 일단은 일일 빌드를 돌리는 것부터 시작함으로

써 조직 내에 실천 방법이 스며들게 하는 편이 낫습니다. 잊지 마세요. CI는 단순한

기술적 성취를 뜻하는 것이 아닙니다. CI는 조직과 문화의 성취입니다. 사람들은 변

화에 저항하기 쉽습니다. 그러므로 조직적 관점에서 볼 때 최고의 접근 방법은 조금

조금씩 자동화된 메커니즘을 추가해 나가는 것이라 생각합니다.

처음에는 빌드가 단순히 소스 코드를 컴파일하고 그렇게 만든 바이너리를 패키징

하는 수준에 불과하고 자동화된 회귀 테스트는 실행하지 않을 겁니다. 개발자들이

자동화된 테스트 도구에 친숙하지 않다면, 시작은 이 정도로도 효과적일 수 있습니

다. 일단 이런 작업이 제자리를 찾고 개발자들이 테스트 도구를 익히고 나면, CI의

이점을 좀더 활용해볼 수 있습니다. 변경할 때마다 테스트와 검사를 돌리는 것이죠.

통합의 진화

CI를 가장 새롭고, 최신의, 최첨단의 소프트웨어를 개발하는 방식이라 할 수 있을까

요? 그렇지는 않습니다. CI는 단지 소프트웨어를 통합하는 방법이 한 단계 진화한 것

이라 하겠습니다. 소프트웨어가 단지 작은 몇 개의 파일로 이뤄져 있을 때라면, 파

일들을 통합하여 시스템으로 만드는 것은 별로 대단한 일이 아니었습니다. 때문에,

매일 밤마다 빌드하는 것이 최고의 실천 방법이라고 몇 년간 알려졌습니다. 이런 실

천 방법들은 여러 책과 글에서 다뤄졌습니다. Michael A. Cusumano와 Richard W.

Selby는 Microsoft Secrets라는 책에서 마이크로소프트 사의 일일 빌드에 대해 논의

했습니다. 스티브 맥코넬의 ‘소프트웨어 생존 법칙’에서도 ‘일일 빌드와 스모크 테스

트’라는 실천 방법이 소프트웨어 개발 프로젝트의 일부분으로 다루고 있습니다.

그래디 부치Grady Booch는 “In Object Solutions: Managing the Object-Oriented

Project”란 책에서 이렇게 썼습니다. “객체 지향 개발의 과정 대부분은 ‘지속적인 통

합’의 일부이다…. ‘지속적인 통합’ 프로세스는 주기적으로 실행 가능한 릴리즈를 산

출해내는데, 릴리즈를 할 때마다 그 기능성은 커진다…. 이러한 이정표를 통해 관리

층은 진행 상황과 품질을 측정하고, 그렇게 함으로써 진행 상황에 따라 위험 요소를

예측하고 파악하고, 적극적으로 공략할 수 있다.” XP나 다른 애자일 방법론들이 등

장하고, CI라는 권장할 만한 실천 방법까지 나타나자, 사람들은 단순한 일일 빌드가

아닌 ‘지속적인’ 빌드라는 개념을 깨닫기 시작했던 겁니다.

Page 71: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

3�

chapter2 지속적인 통합 도입하기

CI 실천 방법은 지금도 발전해나가고 있습니다. 거의 모든 XP 관련 책이 이에 대

해 다룹니다. CI란 실천 방법에 대해 논할 때, 사람들은 마틴 파울러가 쓴 독보적인

글 “Continuous Integration”1)을 보통 언급합니다.

하드웨어 및 소프트웨어 자원이 좋아지면서, 보다 많은 프로세스가 CI의 일부로

포함될 것입니다.

지속적인 통합은 다른 개발 실천 방법을 어떻게 보완할까요?

CI 실천 방법은 개발자 테스트 및 코딩 표준 준수, 리팩토링, 작은 릴리즈 등의 소

프트웨어 개발 실천 방법을 보완해주는 역할을 합니다. 여러분이 RUP, XP, RUP와

XP, SCRUM, Crystal 또는 다른 개발방법론을 사용하더라도 상관 없습니다. 다음 목

록은 CI 실천 방법을 다른 실천 방법과 함께 어떻게 운용하는지, 그리고 다른 실천

방법을 어떻게 개선하는지를 보여줍니다.

개발자 테스트 – 테스트를 작성하는 개발자는 대체로 JUnit이나 Nunit 같은

xUnit 기반의 프레임워크를 사용합니다. 이런 테스트는 빌드 스크립트를 써

서 자동으로 실행할 수 있습니다. CI 실천 방법은 소프트웨어가 변경될 때마

다 빌드를 실행해야 하며, 이때 빌드에는 자동화된 테스트가 포함되어야 한다

고 주장하기 때문에, 지속적인 통합은 소프트웨어에 변경 사항이 적용될 때마

다 전체 코드 베이스에 대해서 자동화된 회귀 테스트를 돌릴 수 있게 해줍니다.

코딩 표준 준수 – 코딩 표준은 프로젝트에 참가한 개발자가 지켜야 할 지침

을 모아놓은 것입니다. 코딩 표준을 잘 지키고 있는지는 대체로 코드 검토라

는 수작업을 통해 확인합니다. CI는 변경 내역이 적용될 때마다 빌드 스크립

트를 돌려서 소스 코드가 정해놓은 표준을 지켰는지 검사하는 자동화된 정적

분석 도구를 실행시켜서 코딩 표준 준수 여부를 보고할 수 있습니다.

리팩토링 – 마틴 파울러가 진술했듯이, 리팩토링은 “코드의 외부 행동은 바

꾸지 않으면서 내부 구조를 개선하여 소프트웨어 시스템을 바꾸는 과정”2)입

니다. 리팩토링은 장점이 많지만, 그 중에서도 으뜸은 코드를 유지보수하기

1) www.martinfowler.com/articles/continuousIntegration.html 을 참고하세요. 역자주. 황상철씨의 번역글 http://

moai.tistory.com/224

2) “Refactoring 리팩토링 : 나쁜 디자인의 코드를 좋은 디자인으로 바꾸는 방법” 마틴 파울러 저/윤성준, 조재박 공역 | 대청 |

2002년 03월

Page 72: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

Continuous Integration

3�

훨씬 쉽게 해준다는 겁니다. CI는 빌드할 때마다 검사 도구를 돌려서 잠재적

인 문제 영역을 파악함으로써 리팩토링 작업을 보조할 수 있습니다.

작은 릴리즈 – 작은 릴리즈라는 실천 방법은 테스터와 사용자가 필요할 때

마다 동작하는 소프트웨어를 받아서 사용하고 검토할 수 있게 해줍니다. CI는

작은 릴리즈 실천 방법과 잘 어울립니다. 왜냐하면 소프트웨어 통합이 하루에

도 여러 번 이뤄지고, 거의 언제라도 릴리즈를 사용할 수 있기 때문입니다. CI

시스템이 갖춰지고 나면, 최소한의 노력만으로도 릴리즈를 생성해낼 수 있습

니다.

공동 소유권 – 개발자라면 누구라도 소프트웨어 시스템의 어느 부분이라도

손볼 수 있습니다. 이렇게 하여 시스템의 특정 영역에 대한 지식을 한 사람만

아는 ‘지식 저장고Knowledge silos’ 현상을 방지합니다. CI 실천 방법은 주기적으로

코딩 표준 준수 여부를 확인하고 회귀 테스트를 돌리기 때문에 공동 소유권에

도움이 됩니다.

지속적인 통합을 수립하려면 얼마나 걸릴까요?

빌드 스크립트만으로 새 프로젝트에 지속적인 통합 시스템을 구현하려고 하면 상당

한 시간이 걸릴 수 있습니다(만들어 놓은 스크립트가 없다면 더 걸리겠죠). 지속적

인 통합 시스템에 대해 지식을 쌓아갈수록, 검사 도구를 추가하거나 배포가 더 복잡

해지거나 테스트를 더 하거나 기타 프로세스를 추가하게 되면, 통합하는 데 걸리는

시간이 길어지게 됩니다. 이렇게 기능을 추가하면 그때마다 조금씩 시간이 늘어나

는 경향이 있습니다.

이미 진행 중인 프로젝트라면, 지속적인 통합 시스템을 수립하는 데 며칠, 몇 주,

심지어 몇 달이 걸릴 수 있습니다. 이때 걸리는 시간은 사람들이 프로젝트에 얼마나

헌신하느냐에 달렸습니다. 일반적으로 지속적인 통합 서버를 쓴다든가 지속적이고

자동화된 무인 시스템으로 옮겨갈 때는 할 일이 많습니다. 어떤 경우에는 배치 또는

셸 스크립트에서 Ant 같은 빌드 도구로 옮기거나, 프로젝트의 바이너리 의존성 모

두를 관리해야 할 수도 있습니다. 이전엔 ‘통합’하고 배포하는 일에 IDE를 써왔을 수

도 있습니다. 어느 경우든, 지속적인 통합을 완전히 도입하려면 갈 길이 멉니다.

Page 73: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

3�

chapter2 지속적인 통합 도입하기

지속적인 통합과 나

지속적인 통합을 프로젝트에서 효과적으로 적용하려면, 개발자들 스스로가 일상적

인 개발 습관을 바꿀 필요가 있습니다. 코드를 좀더 자주 커밋하고, 빌드가 깨질 경

우, 이를 고치는 일을 최우선으로 처리하고자 해야 하며, 단위 테스트가 포함된 자

동화된 빌드가 100% 통과되도록 만들어야 합니다. 버전 관리 저장소에 깨진 코드를

커밋하거나 내려받으면 안 됩니다.

이 실천 방법들을 익히려면 약간의 훈련이 필요하지만, 일단 익숙해지고 나면 이

장에서 말한 여러 장점들을 누릴수 있게 될 것입니다. 이상적인 방법은 프로젝트 내

구성원들이 CI 실천 방법에 충분한 주의와 시간을 쏟으며, 그 갑절로 보답을 받으리

라는 인식을 함께 하는 겁니다.

프로젝트에 지속적인 통합을 돌릴 때 개인과 팀에 효과를 제대로 발휘하는 일곱

가지 실천 방법이 있습니다.

코드를 자주 커밋하세요

깨진 코드를 커밋해선 안 됩니다

빌드가 깨지면 즉시 고치세요

자동화된 개발자 테스트를 작성하세요

테스트와 검사는 모두 통과해야 합니다

개인 빌드를 돌리세요

깨진 코드는 가져오지 마세요

이어지는 절에선 각각의 실천 방법을 훨씬 자세히 다룹니다.

코드를 자주 커밋하세요

지속적인 통합의 핵심은 빨리 그리고 자주 통합하는 겁니다. 코드를 더 자주 커밋

하면 그만큼 더 큰 혜택을 볼 수 있습니다. 커밋하는 기간이 하루 이상이 되면, 통합

작업 자체가 시간 소모적인 활동이 되며, 다른 개발자들이 최신 변경 사항을 이용할

수도 없게 됩니다. 다음 기법 중 한두 개를 시도해보고 코드를 더 자주 커밋할 수 있

게 해보세요.

Page 74: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

Continuous Integration

�0

조금씩 바꾸세요 – 한 번에 여러 개의 컴포넌트를 바꾸려 하지 마세요. 대

신, 작은 일거리를 선택하고, 테스트와 소스 코드를 작성하고, 테스트를 돌리

고 나서 코드를 버전 관리 저장소에 커밋하세요.

각 작업이 끝날 때마다 커밋하세요 – 작업/업무 항목을 쪼개서 몇 시간 안

에 끝낼 수 있다고 가정했을 때, 어떤 개발 회사는 개발자들이 각 작업을 끝냈

으면 바로 코드를 커밋하도록 합니다.

모든 사람이 매일 같이 같은 시간에 커밋을 하지 않도록 하세요. 변경 사항들 간에

충돌이 일어나기 때문에 보통 빌드 오류가 훨씬 많아지고 관리하기 어려워진다는

걸 알게 될 겁니다. 하루 일과가 끝날 무렵에, 사람들이 퇴근할 준비를 하고 있을 땐

특히 고생하게 됩니다. 다른 것과 통합해보는 일을 미루면 미룰수록, 통합하기가 더

더욱 어려워진다는 게 입증될 겁니다.

★ 도저히 커밋할 수가 없네요

한 친구는 25명의 개발자가 참여하는 프로젝트를 운용하고 있고, 여러 가지 CI 실천 방

법을 도입하고 싶어합니다. 하지만 개발자들이 코드를 자주 커밋하도록 만드는 데 애를

먹고 있습니다. 저는 변경 사항을 자주 커밋하지 않는 주된 이유가 프로젝트의 문화 때문

이란 걸 알았습니다. 때로는 개발자들은 코드가 ‘완벽’해질 때까지 커밋하기를 꺼려합니

다. 이는 자신이 변경한 코드가 여러 컴포넌트에 영향을 미칠 때 벌어지기 쉽습니다. 버

전 관리 시스템에 코드를 자주 커밋하는 것만이 지속적인 통합을 구현하는 유일한 효과적

인 방법입니다. 그리고 이는 개발자 모두가 더 작은 단위의 코드를 맡고, 자신의 작업을

더 작은 업무 항목으로 나눔으로써 이 같은 개발 실천 방법을 포용해야 한다는 뜻입니다.

Page 75: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

��

chapter2 지속적인 통합 도입하기

깨진 코드를 커밋해선 안 됩니다

프로젝트를 할 때 버전 관리 저장소에 동작하지 않는 코드를 커밋해선 안 된다는 걸

모두가 알 거라고 가정하면 위험합니다. 이러한 위험을 궁극적으로 완화하려면, 되

풀이해서 코드를 컴파일하고 테스트하는 잘 계산된 빌드 스크립트가 있어야 합니다.

버전 관리 저장소에 코드를 커밋하기 전에 개인 빌드(통합 빌드 프로세스와 아주 유

사한)를 항상 돌리는 개발 실천 방법을 팀이 받아들여야 합니다. 코드를 커밋하기

전에 어떤 일을 하면 좋을지 더 알고 싶다면, 나중에 나오는 ‘개인 빌드를 돌리세요’

절을 참고하세요.

빌드가 깨지면 즉시 고치세요

깨진 빌드라 함은 빌드가 성공했다고 보고하지 못하는 경우를 말합니다. 이는 컴파

일 오류일 수도 있고, 테스트 또는 검사가 실패한 것일 수도 있고, 데이터베이스에

문제가 발생했거나 배포가 실패한 것일 수도 있습니다. 지속적인 통합 환경을 운영

할 때는 이러한 문제들을 즉시 고쳐야 합니다. 다행스럽게도 지속적인 통합 환경에

서는, 각각의 오류가 점진적으로 발견되고, 그렇기 때문에 매우 작은 문제일 가능성

이 높습니다. 어떤 프로젝트에서는 빌드를 깨먹으면 벌칙이 있는데, 저금통에 소정

의 돈을 던져 넣는다든가, 빌드를 깨먹은 마지막 개발자의 사진을 회사의 커다란 모

니터에 붙여놓는다든가 하는 식입니다(농담입니다. 이런 일을 하는 사람이 없었으

면 좋겠네요). 프로젝트의 문화는 깨진 빌드를 고치는 걸 최우선 순위로 다뤄야 합

니다. 그렇게 하면, 팀 구성원 모두가 자신이 하던 일로 돌아갈 수 있습니다. 단 몇

명만 돌아가는 게 아니구요.

자동화된 개발자 테스트를 작성하세요

빌드를 완전히 자동화해야 합니다. 지속적인 통합 시스템에서 테스트를 돌리려면,

테스트를 자동화해야 합니다. NUnit나 JUnit 같은 xUnit 프레임워크를 이용해 테스

트를 작성하면 자동화된 방식으로 이 같은 테스트를 돌릴 수 있을 겁니다. 6장에서

는 자동화된 테스트를 작성하는 방법에 대해 자세히 알아보겠습니다.

Page 76: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

Continuous Integration

�2

테스트와 검사는 모두 통과해야 합니다

지속적인 통합 환경에서는 빌드가 통과되려면, 프로젝트의 자동화된 테스트가

100% 통과되어야 합니다(이것은 기술적인 기준이고 모든 사람이, 또는 모든 업무가

완벽해야 한다고 기대하는 건 아닙니다). 자동화된 테스트는 컴파일 만큼이나 중요

합니다. 컴파일되지 않는 코드는 작동하지 않을 거란 사실은 누구나 받아들입니다.

그러므로 테스트 오류가 있는 코드도 역시 작동하지 않을 겁니다. 테스트를 통과하

지 못하는 코드를 받아들이면 품질이 낮은 소프트웨어가 되어버릴 수 있습니다.

개념 없는 개발자라면 실패하는 테스트를 대충 주석 처리하고 말 수도 있습니다.

물론 이러면 테스트 하는 목적이 사라지게 됩니다. 적용범위 도구는 이런 코드들을

잡아내는 데 무척 유용합니다. 코드 적용범위 도구를 통합 빌드 때 돌려도 됩니다.

자동화된 소프트웨어 검사 도구를 돌려도 같은 효과를 볼 수 있습니다. 모든 코드

가 코딩 및 설계 표준 규칙을 통과하도록 하세요. 고급 기능을 사용하면, 빌드는 되

지만 문제가 있는 부분을 잡아낼 수 있습니다.

개인 빌드를 돌리세요

빌드를 깨먹지 않으려면, 개발자들이 단위 테스트를 끝내고 나서 자신의 로컬 워크

스테이션에서 통합 빌드를 모방해봐야 합니다. 이렇게 빌드를 하면, 버전 관리 저장

소에서 변경 사항을 가져와서 최신 코드를 가지고 로컬에서 빌드를 성공적으로 끝

내는 식으로3) 자신이 만든 새 소프트웨어를 다른 개발자들이 만든 소프트웨어와 통

합할 수가 있습니다. 이렇게 하여 개발자 각자가 커밋한 코드는 제품에 훨씬 더 공

헌하게 됩니다. 통합 빌드 서버에서 실패할 확률이 더 적은 코드일 테니 말이죠.

3) ClearCase 같은 일부 형상 관리 도구는 자동으로 버전 관리 저장소의 변경 사항을 로컬 환경에 업데이트해주는 옵션이 있습니다

(ClearCase에선 “동적 뷰”-dynamic views-라 합니다).

Page 77: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

�3

chapter2 지속적인 통합 도입하기

깨진 코드는 가져오지 마세요

빌드가 깨졌을 때는 버전 관리 저장소에서 최신 코드를 체크아웃하지 마세요. 그렇

지 않으면 빌드를 실패하게 만드는 오류를 회피할 방법을 개발하느라 시간을 보내

고 나서야 코드를 컴파일하고 테스트할 수 있게 됩니다. 궁극적으로는 이것은 팀의

책임입니다. 하지만 빌드를 깨먹은 책임이 있는 개발자가 자신의 코드를 고쳐서 버

전 관리 저장소에 다시 커밋해 넣는 일에 먼저 착수했어야 합니다. 때로는 개발자가

빌드가 깨졌다는 이메일을 보지 못했을 수도 있습니다. 이럴 땐 불빛이나 소리 같은

수동적인 피드백 메커니즘이 한 곳에서 일하는 개발자들에게 유용할 수 있습니다.

우리는 개발자 모두가 버전 관리 저장소에 들어 있는 코드의 상태를 알아야 한다고

생각합니다. 지속적인 피드백 메커니즘에 대해 더 많이 알고 싶다면 9장을 참고하

세요. 체크아웃을 피하는 다른 방법은(하지만 그리 바람직하진 않은), 버전 관리 시

스템을 이용해 가장 최근의 커밋 이래로 변경된 것들을 모두 되돌려버리는 겁니다.

★ 빌드를 깨지지 않게 하세요

지속적인 통합을 효과적으로 사용하는지 알아보는 두 가지 측정 방법이 있다는 걸 알게

됐습니다. 커밋한 횟수와 빌드 상태입니다. 개발자 각자(또는 짝)는 적어도 하루에 한 번

은 저장소에 커밋을 해야 합니다. 그러면 보통 체크인 횟수가 얼마나 많이 변경했는지 보

여줍니다(커밋을 많이 했다면 변경 규모는 작았다는 걸 보통 뜻합니다). 빌드 상태는 하

루 중 대부분에 ‘녹색’(성공) 상태여야 합니다. 하루 중 얼마나 녹색 상태로 있어야 하는

지를 팀의 목표로 수립하세요. 누구나 때로는 ‘빨간색’ 빌드 상태를 겪습니다. 하지만 중

요한 것은 최대한 빨리 ‘녹색’으로 돌아가야 한다는 겁니다. 이런 저런 프로젝트 작업이

끝날 때까지 빨간 상태로 기다리는 일에 익숙해지지 않게 해야 합니다. 다른 조건 때문에

빨간 불 상태를 기꺼이 방치해두고자 하면 지속적인 통합의 힘을 상당 부분 까먹게 됩니다.

Page 78: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

Continuous Integration

��

요약

이제 여러분은 다른 사람에게 지속적인 통합에 대해 말할 준비가 됐습니다.

이 장에서는 지속적인 통합의 기초를 약간 다뤘고, 지속적인 프로세스를 수

립하는 방법을 논의했으며, 뒤이은 장에서 자세히 탐구해볼 다른 영역도 모

두 지적했습니다. 표 2-1은 지속적인 통합을 사용할 때 따라야 할 일곱 가지

실천 방법을 요약해놨습니다. 다음 장에서는 지속적인 통합이 어떤 소프트

웨어 위험 요소를 완화시키고품질을 개선하는 데 도움이 되는지 깊이 탐구

해보겠습니다.

표 2-1 이 장에서 논의한 지속적인 통합 실천 방법

실천 방법 설명

코드를 자주 커밋하세요 적어도 하루에 한 번은 버전 관리 저장소에 코

드를 커밋하세요

깨진 코드를 커밋해선 안 됩니다 다른 코드와 함께 컴파일되지 않거나 테스트

를 깨먹는 코드를 커밋하지 마세요

빌드가 깨지면 즉시 고치세요 팀의 책임일지라도, 최근에 코드를 커밋한 개

발자가 깨진 빌드를 고치는 일에 관여해야 합

니다.

자동화된 개발자 테스트를 작성하세요 소프트웨어가 작동하는지 자동화된 개발자

테스트를 사용해 검증하세요. 자동화된 빌드

와 함께 개발자 테스트를 돌리고, 지속적인

통합을 이용해 개발자 테스트를 돌리세요.

테스트와 검사는 모두 통과해야 합니다 버전 관리 저장소에 코드를 커밋하기에 앞서

90%나 95%가 아닌 모든 테스트가 통과해야

합니다.

개인 빌드를 돌리세요 통합 빌드가 실패하지 않도록, 저장소에서 가

장 최근의 변경 사항을 가져오고, 로컬에서 개

인 시스템 빌드라 알려진 완전한 통합 빌드를

돌리세요.

깨진 코드는 가져오지 마세요 빌드가 실패했는데, 저장소에서 코드를 가져

오면 시간을 낭비하게 될 겁니다. 코드가 바뀌

길 기다리거나, 개발자가 빌드 실패를 고치는

일을 돕고 나서 최신 코드를 가져오세요.

��

Page 79: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

��

chapter2 지속적인 통합 도입하기

질문

지속적인 통합을 실천하는 건 단순히 도구 몇 개를 설치하고 설정하는 일을

넘어섭니다. 다음 사항 중 얼마나 많은 것을 프로젝트에서 일관되게 수행하고

있습니까? 그 밖의 CI 실천 방법 중 몇 개나 여러분의 개발 능력을 개선시키는

데 도움이 됩니까?

평균적으로 팀의 모든 사람이 적어도 하루에 한 번은 코드를 커밋합니까? 코드를 자주

커밋하기 쉽게 해줄 기법을 쓰고 있습니까?

하루에 하는 통합 빌드 중 몇 퍼센트가 성공합니까?(가장 최근에 돌린 빌드는 통과했습

니까?)

팀의 모든 사람이 저장소에 커밋하기 전에 개인 빌드를 돌려서 통합 오류를 줄이고 있

습니까?

테스트나 검사 중 하나라도 실패하면 빌드가 실패하도록 스크립트화했습니까?

깨진 통합 빌드를 고치는 일을 우선적으로 하고 있습니까?

빌드가 깨졌을 때 버전 관리 저장소에서 최신 코드를 가져오지 않습니까?

자동화된 프로세스를 빌드와 지속적인 통합 시스템에 추가할 생각을 얼마나 자주 합니

까? 지속적으로 하나요? 아니면 주기적으로라도 하나요?

��

Page 80: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

46

P {[ }

] |\

“‘ Integrate

?/

Shift

��

Page 81: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

47

프로젝트를 하다 보면 일이 꼬이기 마련입니다. 지속적인 통합을 효과적으로 실천

하면 무엇이 문제인지 바로바로 알 수 있게 됩니다-개발 막바지에 아는 게 아니구요,

지속적인 통합은 위험 요소가 발생했을 때 이를 알아보고 완화시킬 수 있게 도와주

어 명확한 증거에 따라 프로젝트의 건강 상태를 평가하고 보고하기 쉬워집니다. 소

프트웨어를 얼마나 구현했는가? 정답: 가장 최근의 빌드를 확인해보라. 테스트 적

용범위가 얼마나 되나? 정답: 가장 최근의 빌드를 확인해보라. 누가 마지막으로 코

드를 체크인했는가? 정답: 가장 최근의 빌드를 확인해보라.

이 장에서 우리는 지속적인 통합을 실천함으로 여러 위험 요소들, 이를테면 결함을

막바지에나 발견하는 문제, 프로젝트 가시성의 부재, 품질이 낮은 소프트웨어, 배포

할 수 있는 소프트웨어를 만들지 못하는 무능력 등을 완화할 수 있다는 걸 알게 될 것

입니다.

대부분의 팀은 좋은 의도로 시작하지만 그 중 몇몇은 프로젝트상의 문제에 압도

되고 맙니다. 이런 문제는 위험 요소를 관리하지 않았기 때문에 벌어집니다. 이의

앞부분에서 언급했듯이, “우리가 생각하기엔 테스트라든가 코드 검토(짝으로 검토

를 하든 다른 방식으로 하든)는 좋은 실천 방법이 아닌 것 같아.”라고 말하는 개발

그룹은 거의 없습니다. 하지만 일정 때문에 압박을 받게 되면 팀은 지속적인 통합부

터 빼먹기 마련입니다. 이 장에선 지속적인 통합의 여러 측면을 활용하여 어떤 소프

트웨어 위험 요소를 줄일 수 있는지에 대해 초점을 맞춥니다. 지속적인 통합을 사용

하면 ‘품질 안전 망’을 구축하고 소프트웨어를 보다 빨리 전달할 수 있습니다. 코드

가 변경될 때마다 ‘통합 버튼’을 누름으로써 여러분은 그림 3-1에 제시된 것과 같이

위험 요소를 조기에 그리고 자주 줄여나갈 기반을 구축하게 됩니다.

chapter3 지속적인 통합을 이용해 위험 줄이기

품질이란 누가 보지 않을 때에도 제대로 돌아가는 걸 뜻한다

- 헨리 포드

P {[ }

] |\

“‘ Integrate

?/

Shift

Page 82: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

Continuous Integration

��

그림 3-1 ㅣ 지속적인 통합은 소프트웨어 품질을 향상시키고 위험 요소를 줄이는 데 도움이 됩니다

특정 소프트웨어 위험 요소를 줄일 수 있다면 소프트웨어 품질을 향상시킬 수 있습니

다. 이 장에서 위험 요소들을 설명함에 있어 우리는 다음과 같은 양식을 따를 겁니다.

소프트웨어 위험 요소에 대한 소개와 설명

우리의 경험에 따른 시나리오

CI의 일면을 활용하여 위험 요소를 완화시킬 해결책

어느 프로젝트에서든지 관리해야 할 위험 요소는 많습니다. 우리는 지속적인 통합

을 활용해서 줄일 수 있는 핵심 위험 요소에 초점을 맞춥니다. 물론 CI가 고객에게

서 요구 사항을 끌어내고, 고객의 산업을 이해하고, 자금이나 자원을 관리하는 일과

같은 사업적 도전거리를 직접 보조하지는 못합니다. 하지만 지속적인 통합을 사용

하면 소프트웨어의 문제를 보다 빨리, 소프트웨어를 개발하는 도중에 발견할 수 있

습니다.

지속적인 통합은 변경될 때마다 소프트웨어를 빌드함으로써, 시간을 여러분의 편으

로 만들어줍니다. 지속적인 통합을 적용하면 보다 중요하고 보다 흥미로운 프로젝트

Page 83: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

��

chapter3 지속적인 통합을 이용해 위험 줄이기

이슈에 집중할 수 있습니다. 지속적인 통합은 집합적인 실천 방법이기 때문에 이 장에

서 다루는 위험 요소들은 여러 소프트웨어 개발 실천 방법을 아우릅니다.

배포 가능한 소프트웨어의 부재

뒤늦은 결함 발견

프로젝트 가시성의 부재

저품질의 소프트웨어

“아, 일전에 이 같은 위험 요소에 대해 들은 적이 있어요. 별로 새로울 건 없네요”라

고 말할지도 모르겠습니다. 하지만, 위험 요소를 안다고 해서 그것을 완화시킬 방법

까지 안다고 할 수는 없습니다. 위험 요소를 파악하고 해결하여 그것들이 더 이상

프로젝트상의 쟁점이 되지 않게 하는, 보다 효율적이고 생산적인 방법이 있습니다.

다른 실천 방법들이 그렇듯, 결국엔 어떻게 효과적으로 실현하느냐가 문제입니다.

뒤이은 장에서는 통합 버튼이란 모델을 이용하여 이런 위험 요소들을 인지하고 줄

이는 효과적인 방법들을 보여주겠습니다.

위험 요소: 배포 가능한 소프트웨어의 부재

한두 달에 한 번씩 별도의 컴퓨터에서 소프트웨어를 빌드했던 프로젝트가 있었습

니다. 마지막으로 소프트웨어를 빌드했을 때는 납품 마감일이 코 앞이라, 팀 구성원

대부분이 저녁 늦은 시간까지 남아서 기적을 다시 이끌어내려 했습니다. 이 ‘통합

지옥’ 와중에 우리는 제대로 동작하지 않는 인터페이스들이 있다는 것과, 설정 파일

을 빼먹었다는 것, 비슷한 기능을 제공하는 컴포넌트가 여러 개 있다는 것, 지난 번

빌드의 일부인 다수의 변경 사항을 병합하기가 힘들다는 것을 알게 됐습니다. 이런

문제 때문에 프로젝트상의 중요한 이정표를 빼먹게 됐던 적도 있습니다.

또 다른 프로젝트에서는 IDE를 사용하여 사람이 직접 소프트웨어 통합 빌드를 했

습니다. 평균적으로 일 주일에 한 번씩 소프트웨어를 직접 통합했습니다. 형상 관리

(CM) 분석가가 특정 스크립트를 사용해서 버전 관리 저장소 밖에서 소프트웨어를

빌드할 때도 있었습니다. 자동화의 부재는 빌드 수행의 부하를 증가시켰습니다. 별

도의 컴퓨터가 제공하는 깨끗한 환경에서 빌드를 하지 않았기 때문에 우리는 소프

트웨어를 제대로 빌드하고 있는지 자신이 없었습니다. 이 모든 것은 세 가지 효과를

일으켰습니다.

Page 84: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

Continuous Integration

�0

소프트웨어를 빌드할 수 있을지에 대해서조차 자신감이 부족하거나 없었습니다.

소프트웨어를 내부(예: 테스트 팀)나 외부(예: 고객)에 전달하기 전까지의 통

합 기간이 길었고, 그 사이에 아무것도 할 수 없었습니다.

테스트 가능한 빌드 결과물을 생산하고 재생산할 능력이 없었습니다.

시나리오: “내 컴퓨터에선 되는데요”

프로젝트 팀이 작동하고 배포 가능한 소프트웨어를 만들어내지 못하는 이유는 여러

가지입니다. 테스트가 실패하는 일부터 버전 관리 저장소에 엉뚱한 파일을 올려놓

는 일까지 어떤 것이라도 빌드 실패에 한몫 할 수 있습니다. 그런 시나리오를 하나

살펴보죠.

존 (기술 리더): 지난 번 빌드가 테스트 서버에서 문제를 일으켰어요.

아담 (개발자): 이상하네요. 제 컴퓨터에서 빌드했을 땐 잘 됐는데요. 한번 볼께

요…. 음, 잘 되는데요.

존: 아, 뭐가 문제인지 알겠어요. 새로 추가한 파일을 서브버전 저장소에 안 올렸네요.

해결책

IDE와 빌드 프로세스가 서로 강하게 얽혀있으면 안 된다는 것은 아무리 강조해도

지나치치 않습니다. 소프트웨어 통합 전용 컴퓨터를 따로 사용하세요. 소프트웨어

를 빌드할 때 필요한 모든 게 버전 관리 저장소에 있어야 합니다. 마지막으로 CI 시

스템을 만드세요. CruiseControl 같은 CI 서버와 Ant, NAnt, 또는 Rake 같은 도구를

사용해서 빌드를 자동화하세요. CruiseControl은 버전 관리 저장소에 변경 사항이

들어왔는지 지켜보다가, 저장소에 변경 사항이 들어오면 프로젝트용 빌드 스크립트

를 돌립니다. 빌드할 때 테스트를 돌리고, 검사를 수행하며 개발 및 테스트 환경에

소프트웨어를 배포하도록 CI 시스템의 기능을 강화할 수도 있습니다. 이렇게 하여

작동하는 소프트웨어를 언제라도 갖게 됩니다.

시나리오: 데이터베이스와 동기화하기

개발 도중에 데이터베이스를 신속하게 다시 만들어낼 수 없다면, 소프트웨어를 변

Page 85: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

��

chapter3 지속적인 통합을 이용해 위험 줄이기

경하기가 힘들 겁니다. 데이터베이스 팀과 개발 팀이 분리되어 있어서 이런 문제가

발생하곤 합니다. 서로 협력하는 데 힘쓰기보단 저마다 자기 팀이 맡은 일에 초점을

맞추기 때문이죠. 팀들이 하나가 되지 못하는 판에 제품을 통합할 방법이 있겠습니

까? 이런 시나리오에선, 이를테면 데이터베이스 관리자가 데이터베이스 스크립트

상당수를 버전 관리 저장소에 커밋하지 않을 수도 있습니다. 이렇게 되면 다음과 같

은 유형의 위험 요소가 발생할 수 있습니다.

데이터베이스나 소스 코드를 변경하거나 리팩토링하기가 무섭다.

여러 가지 데이터 집합을 사용해 데이터베이스를 생성하기가 힘들다.

개발 및 테스트 환경(예: 개발, 통합, 품질 보증, 테스트)을 유지보수하기가

힘들다.

이런 위험 요소는 데이터베이스가 개발 팀을 못 따라잡거나 그 반대의 현상이 일어

나게 해 개발에 악영향을 미칩니다. 소프트웨어와 데이터베이스 개발자들이 각기

다른 버전의 데이터베이스를 쓰고 있을지 모릅니다. 프로젝트 구성원들이 한 곳(버

전 관리 저장소)에서 최신 데이터베이스를 구하지 못할 수도 있습니다. 다음 대화가

이 문제를 잘 묘사하고 있습니다.

로렌 (개발자): 빌드 1345를 써서 버전 1.2.1.b1 데이터베이스를 테스트하려고

하니까 문제가 많네요.

폴린 (데이터베이스 설계자): 아 이런, 빌드 1345를 쓸 땐 버전 1.2.1.b2짜리를

써야 해요. 그 전에 손봐야 할 게 몇 개 있구요.

로렌: 네 시간이나 날렸다구요.

폴린: 저한테 먼저 확인 받았어야죠.

해결책

일부 프로젝트에 이 해결책을 적용하려면 근본적인 변화를 일으켜야 합니다. 데이터베

이스가 개발과 동떨어진 개체가 되지 않게 하는 접근 방법을 대략 설명해보겠습니다.

모든 데이터베이스 산출물을 버전 관리 저장소에 넣으세요. 이 산출물이란 데

이터베이스 스키마와 데이터를 다시 만드는 데 필요한 모든 걸 뜻합니다. 데

이터베이스 생성 스크립트, 데이터 조작 스크립트, 저장 프로시저, 트리거와

그 밖의 데이터베이스 자산을 말하는 겁니다.

Page 86: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

Continuous Integration

�2

빌드 스크립트로 데이터베이스와 테이블을 삭제하고 다시 만들어서 데이터

베이스와 데이터를 다시 빌드하세요. 그런 후에 저장 프로시저와 트리거를 다

시 만들고, 마지막엔 테스트 데이터를 삽입하세요.

데이터베이스를 테스트하세요(그리고 검사하세요). 컴포넌트 테스트를 사용

해 데이터베이스와 데이터를 테스트하는 게 보통입니다. 경우에 따라선 데이

터베이스 별로 테스트를 작성해야 할 겁니다.

5장에서 이 주제를 더 심도 깊게 다루고 시나리오와 해결책을 논의하겠습니다.

시나리오: 버튼을 안 눌렀어요

소프트웨어를 사람이 배포하면 시간과 노력을 낭비하는 겁니다. 애플리케이션 서버

의 웹 관리 유틸리티를 써서 필요할 때마다 소프트웨어를 직접 배포했던 프로젝트

가 있었습니다. 이 일은 하루에 한 번씩 하기로 되어 있었습니다. 하지만 팀이 다른

이슈를 다루느라 정신 없을 때가 많아서, 정작 우리가 최신 통합 빌드가 필요할 땐

병목을 일으켰습니다. 이 반복적이고 지루한 과정에 매일 10분 내지 15분을 썼습니

다. 그것도 일이 잘 풀렸을 때죠. 문제는 자동화했어야 했던 일에 시간을 낭비하고

있다는 것이었습니다. 테스트 컴퓨터에 배포하는 일 말이죠. 그런데다가 관리 도구

의 오른쪽 버튼을 누르지 않으면 문제가 일어나기 십상이었습니다.

사람이 배포하는 접근 방식을 취할 때 발생하는 전형적인 문제를 예로 들어보겠

습니다.

레이첼 (개발자): 개발 서버에 최신 빌드가 업데이트됐나요? 존은 어디 있죠?

켈리 (개발자): 아, 존은 점심 먹으러 갔어요. 존이 업데이트를 서버에 올리기로

되어 있었는데요.

레이첼: 그래요? 존이 돌아올 때까지 기다려야겠네요.

나중에 존이 들어오고…

레이첼: 존, 최신 빌드는 어떻게 된 거예요? JSP 파일을 ‘미리 컴파일하기(Precompile)’

안 한 것 같은데요. 런타임 오류가 나고 있다구요.

존 (기술 리더): 이런, 미안해요. 어제 웹 도구로 배포할 때 미리 컴파일하기 옵션

을 깜박하고 잊은 것 같네요.

Page 87: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

�3

chapter3 지속적인 통합을 이용해 위험 줄이기

해결책

우리가 참여했던 프로젝트에서는 Ant 빌드 스크립트가 애플리케이션 서버의 명령

줄 옵션을 사용하게 만들어 개발 과정을 자동화했습니다. 이렇게 하여 다른 사람이

소프트웨어를 배포해줄 때까지 기다리는 병목을 줄이고 실수할 여지를 없앴습니다.

언제라도 최신 소프트웨어를 사용해 테스트할 수 있습니다. 우리는 CruiseControl

CI 서버를 사용해 버전 관리 저장소에 변경 사항이 들어올 때마다 Ant 빌드 스크립

트를 돌렸습니다. 더 자세히 알고 싶다면 8장을 참고하세요

위험 요소: 뒤늦은 결함 발견

몇몇 프로젝트에서 우리는 테스트를 직접 수행했습니다. 최근에 소프트웨어를 변경

한 코드가 다른 문제를 일으키진 않는지 알 도리가 없었습니다. 이를테면 결함을 하나

고치면 다른 연관된 결함이 드러나는 악순환 때문이죠. 하나를 변경하면 그것이 물밑

에서 어떤 효과를 일으킬지 알지 못해서 변경할 자신이 없었습니다. 테스트들을 사람

이 직접 수행했었기 때문에 개발자들이 테스트를 돌릴 거라는 보장이 없었습니다.

시나리오: 회귀 테스트

회귀 테스트 시나리오를 살펴보도록 하죠.

샐리 (기술 리더): 테스트 환경에 배포된 최신 버전에서 두 달 전 발견한 바로 그

버그를 발견했어요. 왜 그런 거죠?

카일 (개발자): 잘 모르겠네요. 최신 코드를 모두 테스트했는데요.

샐리: 시스템의 다른 부분을 테스트하는 코드까지 모두 돌려봤나요?

카일: 아뇨. 그 많은 테스트를 직접 돌려볼 시간이 없었어요. 그래서 제가 버그를

찾지 못했었나 보네요.

해결책

이후 프로젝트에서 우리는 JUnit으로 비즈니스, 데이터, 그리고 공통 계층에 대해

단위 테스트와 컴포넌트 테스트를 작성했습니다. 기존 프로젝트의 경우에는 변경

한 코드에 대해서만 결함이 있으면 단위 테스트를 작성했습니다. 우리는 Ant 빌드

Page 88: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

Continuous Integration

��

스크립트가 모든 단위 테스트를 돌리고 빌드할 때마다 보고서를 만들도록 설정했

습니다.

다음에 제시된 단계들은 CI 시스템을 이용해 회귀 테스트를 자동화하는 방법을

보여줍니다.

모든 소스 코드에 대해 테스트를 작성하세요(xUnit 프레임워크로 시작하면

좋습니다).

빌드 스크립트로 테스트를 돌리세요(Ant나 NAnt를 많이 사용합니다).

지속적인 통합 시스템의 일부로써 테스트를 지속적으로 돌리세요. 그래야 버

전 관리 저장소에 체크인할 때마다 테스트가 실행됩니다(CruiseControl이나

이와 유사한 CI 서버를 사용하세요).

이토록 쉽게 회귀 테스트를 자동화할 수 있답니다! 6장에서는 테스트를 모든 측면

에서, 빌드 과정에 없어서는 안 될 요소로 만드는 일에 관해 좀더 논의하겠습니다.

시나리오: 테스트 적용범위(Test Coverage, 테스트 커버리지)

테스트를 작성하고 돌리면 그 결과를 보는 것뿐만 아니라 코드 중 얼마나 많은 부분

이 실제로 테스트되는지도 알고 싶을 겁니다. 지속적인 통합 시스템을 도입하기 전

에는 프로젝트상의 단위 테스트 대부분을 직접 돌렸기 때문에, 테스트가 실행됐는

지 독립적으로 검증할 방법이 없었습니다. 얼마나 많이 테스트를 했는지 관리자가

알 방법이 없을까요? 다음 대화를 고려해보세요

에블린 (관리자): 변경한 코드를 저장소에 커밋하기 전에 단위 테스트를 실행해

봤어요?

노아 (개발자): 네.

에블린: 좋아요.

에블린이 뭘 빼먹고 안 물어봤죠? 다시 한 번 해볼까요?

에블린: 새로 추가한 코드를 검사할 새 테스트를 짜거나 기존 테스트를 갱신했나요?

노아: 네

에블린: 테스트를 다 통과하던가요?

1.

2.

3.

Page 89: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

��

chapter3 지속적인 통합을 이용해 위험 줄이기

노아: 네

에블린: 충분한 양의 코드를 적절히 테스트했는지는 어떻게 판단했죠?

이번 질문을 던진 것은 좀 나았습니다. 하지만 여전히 정량적인 분석으로 보다 명확

하게 설명할 수 있는 것을 불필요하게 정성적으로 분석하고 있습니다. 이제 해결책

을 살펴보도록 하죠.

해결책

일단 개발자나 팀이 소스 코드에 대응하는 테스트를 짰다고 생각한다면, 여러분은

코드 적용범위 도구를 돌려서 테스트 코드가 실지로 얼마만한 양의 소스 코드를 실

행하는지 평가해볼 수 있습니다. 패키지나 클래스 별로 적용범위를 백분율로 보여

주는 도구가 여럿 있습니다.

지속적인 통합은 이 같은 테스트 적용범위를 항상 최신 상태로 유지해줍니다. 이

를테면, 테스트 적용범위 도구를 지속적인 통합 시스템의 빌드 스크립트에 넣어 버

전 관리 저장소에 변경 사항이 들어오면 실행되게 할 수 있습니다. 7장에서 코드 적

용범위에 대해 논의하겠습니다.

위험 요소: 프로젝트 가시성의 부재

사람이 직접 의사소통 메커니즘을 수행할 때는, 프로젝트의 정보를 적절한 시기에

올바른 사람에게 전달하려면 조정을 많이 해야 합니다. 옆 자리에 앉은 개발자에게

다가가 최신 소스 코드를 공유 드라이브에 올려놨다고 말하면 좀더 효율적이긴 하

겠지만, 그래도 여전히 그리 썩 좋지는 않습니다. 이 정보를 알아야 할 개발자가 더

있는데, 그 사람들이 휴식을 취하고 있거나 어딘가 가버린 상황이라면 어떨까요? 서

버가 다운됐다면 그 사실을 어떻게 알리나요? 어떤 사람은 사람이 직접 이메일을 보

내서 이러한 위험 요소를 경감시킬 수 있다고 생각합니다. 하지만 이런 방식으로는

정보가 올바른 사람에게 제때 전달되리라 믿기 힘듭니다. 이메일을 보내야 할 여러

분이 이해당사자들에게 이메일을 보내는 걸 잊어먹을 수도 있고, 바로 그 시점에 이

메일을 확인할 수 없는 상황에 처한 사람이 있을 수도 있습니다.

Page 90: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

Continuous Integration

��

시나리오: “제가 남긴 메모 보셨나요?”

이 같은 위험 요소는 다양한 시나리오가 있습니다. 한 사례만 살펴보죠.

에블린(관리자): 노아, 무슨 일을 하고 있어요?

노아(테스터): 테스트를 하려는데 최신 빌드가 QA 팀으로 배포되길 기다리고 있

습니다.

에블린: 최신 빌드가 이틀 전에 테스트 서버에 배포됐는데요. 못 들었어요?

노아: 네. 며칠 동안 회사에 없었거든요.

해결책

이런 위험 요소를 완화하기 위해 우리는 CruiseControl CI 서버를 설치하고 설정하

여 빌드가 실패하면 관련자들에게 이메일을 보내는 자동화 메커니즘을 도입했습니

다. 그와 더불어 SMS 통지 기능을 추가하여 이메일을 볼 수 없는 경우엔 휴대폰으

로 문자 메시지를 받을 수 있게 했습니다. 서버의 가용 여부를 주기적으로 확인하는

자동화된 에이전트도 설치했습니다. 예제를 보고 싶거나 더 많은 정보를 얻고 싶다

면 9장을 참고하세요.

시나리오: 소프트웨어를 시각화할 역량의 부재

새 기능을 만들고 기존 소프트웨어를 수정하는 프로젝트가 있었습니다. 하지만 우

리에겐 큰 그림을 보여줄 역공학 도구가 없었습니다. 클래스들과 그 관계 모델을 볼

수가 없었죠. 만약 참조할 만한 최신 클래스 다이어그램이 있었더라면, 우리는 중복

되는 행동이나 잘못된 구조를 더 쉽게 파악했을 테고, 그럼으로써 효과적이지 않은

결정을 덜 했을 것입니다.

마일리(개발자): 안녕하세요. 프로젝트에 참가하게 됐는데 설계를 검토해보고 싶

습니다. 제가 볼 만한 UML 같은 다이어그램이 있을까요?

앨리(개발자): 으. 여기선 UML을 그리지 않아요. 마일리가 할 일은 코드를 읽는

것뿐이에요. 코드를 읽지 못하면 여기 있을 수 없을 거에요.

마일리: 알겠습니다. 그저 코드를 느릿느릿 헤집어보는 것보다 큰 그림을 보고 아

키텍처 전체를 파악했으면 하고 바랐을 뿐입니다. 저는 그림을 더 좋아하거든요.

Page 91: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

��

chapter3 지속적인 통합을 이용해 위험 줄이기

해결책

설계 결함이 발생하는 시점과 그것을 해결하는 시점 사이의 간격을 줄이려고 우리

는 CI 시스템을 사용해 설계 다이어그램을 생성했습니다. Doxygen이라 하는 자동

화된 코드 문서화 도구를 CI 시스템에서 돌렸습니다. Doxygen은 소스 코드를 문서

화하고 소프트웨어를 모델링하는 UML 다이어그램을 만듭니다. Doxygen을 CI 시

스템의 일부로써 돌리기 때문에, 버전 관리 저장소에 가장 근래에 체크인된 소프트

웨어를 기반 삼아 항상 최신으로 유지됩니다.

CI 시스템에 이런 기능을 넣긴 했지만, 우리는 신참 개발자를 위해 핵심 컴포넌트

와 인터페이스를 파악한 다음 한두 쪽짜리 간단한 문서를 만들어 소프트웨어 아키

텍처를 설명하기로 했습니다.

위험 요소: 저품질의 소프트웨어

눈에 보이는 결함이 있는가 하면 잠재적인 결함도 있습니다. 소프트웨어를 잘 설계

하지 못했거나 프로젝트 표준을 따르지 않았거나, 소프트웨어가 복잡해서 유지보수

하기 힘들면 잠재적인 결함이 있는 겁니다. 이를 두고 코드 냄새 또는 설계 냄새라

고 부르곤 합니다. 냄새란 ‘무언가 잘못됐다는 징후’를 뜻합니다.1) 저품질의 소프트

웨어는 그저 지연된(소프트웨어 인도 후에) 프로젝트 비용일 뿐이라 생각하는 사람

이 있습니다. 저품질의 소프트웨어를 지연된 프로젝트 비용으로 치부할 수는 있지

만, 소프트웨어를 사용자에게 전달하기 전에 여러 가지 문제가 일어나게 됩니다. 지

나치게 복잡한 코드, 아키텍처를 따르지 않는 코드, 그리고 중복 코드 모두 소프트

웨어의 결함으로 이어집니다. 이런 코드 냄새와 설계 냄새가 결함이 되기 전에 찾아

내면 엄청난 시간과 돈을 절약할 수 있고, 그에 따라 품질 좋은 소프트웨어가 만들

어집니다. 이 절에서 이와 관련된 시나리오 몇 개를 검토해보겠습니다.

모든 소스 코드를 매일 손수 검토하는 방법 말고는 소프트웨어가 얼마나 유지보

수하기 좋은지 알 방법이 없었던 프로젝트가 있었습니다. 개발 중인 소프트웨어의

품질 동향을 파악할 수 없었습니다. 프로젝트 구성원 다수가 소프트웨어의 내부 품

질을 고칠 시간이 없다고 느꼈고 어디서부터 시작해야 할지 몰랐습니다. 별로 상의

해본 적도 없고 따르지도 않는 코딩 표준 문서를 만들어놓은 프로젝트가 있습니다.

1) http://en.wikipedia.org/wiki/Code_smell. 를 참고하세요.

Page 92: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

Continuous Integration

��

아예 표준이란 게 없는 프로젝트도 있죠. 몇몇 프로젝트에선 소프트웨어의 엔트로

피가 명확합니다. 왜냐하면 소프트웨어를 깨먹을까 무서워 변경하질 못하기 때문입

니다.

시나리오: 코딩 표준 준수

코딩 표준을 준수하는 것과 관련된 전형적인 대화를 보여드리겠습니다.

브라이언(개발자): 린지씨, 당신이 짠 코드는 읽기 어렵더라구요. 지난 주에 일을

시작할 때 30쪽짜리 코딩 표준 문서를 읽었나요?

린지(개발자): 지난 번 직장에서 했던 대로 하고 있습니다. 제가 작성한 코드는

약간 복잡해서 따라잡기 어려울지도 모르겠네요.

브라이언: 다른 사람이 건들지 못할 코드를 짠다고 똑똑해지는 건 아니잖아요. 자

신을 덜 중요한 사람으로 만들 뿐이죠. 코드를 검토하고 업데이트하느라 시간을

더 잡아먹고 있어요. 빠른 시일 내에 코딩 표준 문서를 검토해주면 좋겠네요. 우

선 지침에 따라 일전에 짜놓은 코드부터 다시 고치고 나서 새 코드를 작성해줬으

면 합니다.

해결책

우리는 30쪽짜리 표준 문서를 작성하는 대신, 한쪽 짜리 어노테이션Annotation 달린 클

래스를 만들어 코딩 표준을 모두 담게 했습니다.2) 우리는 CruiseControl이 빌드 스

크립트를 돌릴 때 자동화된 검사 도구가 코딩 표준을 강요하도록 만들었습니다. 주

로 자바 프로젝트를 다뤘기 때문에 Checkstyle3)과 PMD4)를 써서 정해놓은 표준에

부합하지 않는 코드가 하나라도 있으면 보고하게 해놓았습니다. Checkstyle과 PMD

가 이런 정보를 HTML 보고서 형식으로 내보내게 하여, 이것을 다시 CruiseControl

CI 서버와 통합시켰습니다. 이 이후의 프로젝트에선 코딩 표준을 조금이라도 위반

2) William C. Wake가 작성한 한쪽짜리 자바 코딩 규약(Java Coding Conventions on One)이 http://www.xp123.

com/xplor/xp0002f/codingstd.gif에 있으니 살펴보세요.

3) Checkstyle은 정적 분석 도구인데 소스 코드를 평가하고 정해놓은 코딩 표준에서 벗어나는 게 있으면 보고합니다. Checkstyle

은 http://checkstyle.sourceforge.net/ 에 있습니다.

4) PMD는 메트릭 도구인데 소스 코드에 사용하지 않는 변수, 사용하지 않는 import, 또는 지나치게 복잡한 코드와 같이 비정상적인

부분이 있으면 보고합니다. PMD는 http://pmd.sourceforge.net/에 있습니다.

Page 93: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

��

chapter3 지속적인 통합을 이용해 위험 줄이기

하면 빌드를 통과하지 못하게 해놨습니다.

시나리오: 설계 지침 준수

의도한 설계를 따르지 않는 소스 코드는 유지 보수하기 더 어렵습니다. 프로젝트를

시작할 땐 아주 우아한 소프트웨어 아키텍처를 수립해놓았지만, 프로젝트가 끝날

무렵엔 ‘커다란 진흙덩이Big Ball of Mud’5)가 되어 버린 일이 없었습니까? 어쩌면 아키텍

트가 전체 시스템을 UML 모델링 도구로 설계해놓고 “이 참조 아키텍처를 따르시오”

라고 말했을지 모르죠. 극단적으로 말했을 수도 있지만, 언제나 그렇듯 양 극단의

중간쯤인 경우가 많습니다.

의도한 아키텍처와 실제 아키텍처 간의 불일치는 문제의 소지가 있습니다. 예를

들어 “데이터 계층은 절대로 비즈니스 계층과 ‘대화’를 나눠선 안 된다.”라는 설계 지

침이 있다고 해보죠. 아마도 그 아키텍트는 UML 모델링 도구를 써서 이러한 아키텍

처를 소스 코드로 변환시켰을 겁니다. 하지만 시간이 흐르자, 코드가 변했고 아키텍

처는 의도했던 설계와는 어긋나게 됐습니다. 예를 들어, 신참 개발자가 프로젝트에

참가하게 되었고 비즈니스 계층에서 유용한 메소드들을 몇 개 찾아내서 데이터 계

층에서 호출했다고 해보죠. 이는 프로젝트 아키텍처를 위반한 것입니다. 이런 일이

일어나지 않으리란 보장이 어디 있겠습니까?

진(아키텍트): 아키텍처를 따르고들 계신가요? 컨트롤러 중 하나에서 문제를 발

견했는데, 여러분 중 한 사람이 데이터 계층에서 곧바로 컴포넌트를 호출하게 했

더군요.

마크와 찰리(개발자): (당혹스런 표정)

진: 제가 그 모든 UML 다이어그램을 만든 이유는 모든 사람이 정해진 소프트웨어

아키텍처를 따르게 하기 위해서였습니다. 여러분은 몇 달 동안 잘 지켰던 정해진

규약을 따르지 않고 있어요.

찰리: 프로젝트 시작할 땐 UML 다이어그램을 살펴봤습니다. 하지만 그 이후로 아

키텍처가 몇 차례 바뀌었고 따라가기 힘들더라구요.

5) “진짜 아키텍처를 분간할 수 없는…… 시스템을 말한다.” 출처: http://en.wikipedia.org/wiki/Big_ball_of_mud.

Page 94: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

Continuous Integration

�0

해결책

자동화된 검사 도구를 넣어서 프로젝트 아키텍처 표준을 준수하는지 평가하세요.

이를테면 컨트롤러 클래스는 절대 데이터 접근 객체를 직접 호출해선 안 된다, 라는

규칙을 넣을 수 있습니다. JDepend6)나 NDepend 같은 의존성 분석 도구를 사용할

수도 있습니다. 통합 빌드를 할 때마다 이런 도구가 실행되게 할 수 있습니다.

시나리오: 중복 코드

중복 코드는 코드를 유지보수하기 더 어렵게 만들고 비용을 증가시킵니다. 복사해

붙여넣기Copy & Paste한 코드는 우리가 지켜본 사실상 모든 프로젝트에 위험이 되었습

니다. 실제로 아주 유명한 소프트웨어 개발 키트와 도구 중에 25%가 넘는 코드가

중복되는 것이 많이 있습니다. 우리는 한 회사에서 소프트웨어 개발 프로젝트를 모

두 분석했었는데, 평균적으로 중복 코드가 45%나 된다는 걸 발견했습니다. 유지 보

수해야 할 비슷한 코드가 무더기로 있으면 문제가 될 수 있습니다. 예를 들어, 여러

하위시스템에 비슷한 코드가 5개나 있는 시스템이 있었습니다. 이제 현재 로그인한

사용자의 인증을 검사하는 코드가 있다고 해보겠습니다. 개발자가 하나의 메소드를

작성하지 않고 사용자를 인증할 때 필요한 코드를 사방에서 복사해 붙여넣기로 합

니다. 개발자들이 공통 유틸리티를 쓰지 않고 자기만의 논리를 만들기로 할 때도 코

드 중복의 또 다른 형태를 보게 됩니다. 문자 그대로 복사해 붙여넣는 것은 아니지

만 코드 중복과 똑같은 효과를 만들어낸다는 점은 같습니다.

메리(개발자): User 객체 콜렉션을 어떻게 순회하면 되는지 아세요?

아담(개발자): 아, 제가 지난 주에 그런 코드를 짰어요. User 패키지에서 찾아보

면 될 거예요.

메리: 정말요? 거기서 코드를 복사해 사용하면 되겠네요. 고마워요.

이런 식으로 코드 중복은 계속됩니다. 중복이 많아지고 있는지 줄어들고 있는지 그

리고 어디서 중복이 발생하는지 알지 못하면, 여러분이 직면하게 될 문제가 무엇인

지, 어디를 리팩토링해야 할지 파악하기 힘듭니다.

6) JDepend는 소스 코드의 아키텍처와 설계를 확인하는 도구입니다. JDepend는 http://www.clarkware.com/software/

JDepend.html에서 구할 수 있습니다.

Page 95: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

��

chapter3 지속적인 통합을 이용해 위험 줄이기

해결책

코드 중복을 해결하려면 먼저 문제부터 평가해야 합니다. PMD의 CPD7)나 Simian8)

이란 정적 분석 도구와 같은 자동화된 검사 도구를 추가해서 중복된 소스 코드를 보

고하게 할 수 있습니다. 우리는 이런 검사 도구를 빌드 프로세스에 포함시켰는데,

그 덕분에 언제라도 검사를 돌릴 수 있었습니다. 이런 도구를 사용함으로써 대부분

의 중복이 벌어진 코드 영역을 찾아냈고, 그런 코드를 컴포넌트로 만들어 일반화했

습니다. 이런 접근 방법을 채택함으로써 코드 중복을 항시 감시하고 시스템 내의 중

복 코드를 줄일 수 있었습니다.

전형적인 시나리오대로라면, 똑같거나 비슷한 코드를 가진 클래스를 여러 개 발

견하게 됩니다. 중복 코드를 줄이려면 다음과 같은 절차를 따르세요.

Simian이나 PMD의 CPD 같은 코드 중복 분석기로 코드를 분석하세요. 분석

도구를 빌드 스크립트에 넣으세요.

코드를 리팩토링9)하여 하나의 메소드나 하나의 컴포넌트로 만들고, 그 코드

가 있었던 클래스가 리팩토링한 코드를 호출하게끔 만들어 중복 코드를 줄이

세요.

코드 중복 검사기를 CI 시스템에 집어넣어 코드 중복 검사를 지속적으로 돌리

세요. 이렇게 하면 시간이 지나도 코드 중복을 감지해낼 역량이 생깁니다.

7장에서는 어떤 검사를 돌려야 하는지, 얼마나 자주 돌려야 하는지, 그리고 언제

적용해야 하는지에 대해 자세히 알아보겠습니다.

7) CPD는 PMD 메트릭 도구에 포함된 유틸리티인데 소스 코드를 복사해 붙여넣은 곳을 보고합니다. CPD는 http://pmd.

sourceforge.net/에 있습니다.

8) Simian(Similarity Analyser, 유사도 분석기)은 C#, 자바, 루비를 비롯해 다양한 언어를 지원합니다. Simaian은 www.

redhillconsulting.com.au/products/simian/에서 다운로드 받을 수 있습니다.

9) “리팩토링은 코드 내부를 바뀌어 내부 구조를 개선하는 것을 말한다.“ 출처는 Bill Venners가 쓴 “마틴 파울러와 리팩토링하기:

마틴 파울러와의 대화, 첫 번째”(Refactoring with Martin Fowler: A Conversation with Martin Fowler, Part I)이고

www.artima.com/intv/refactor.html에 있습니다.

1.

2.

3.

Page 96: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

Continuous Integration

�2

요약

이 장에서는 데이터베이스 통합, 테스트, 검사, 배포, 피드백, 문서화처럼 CI

가 도움이 될 만한 핵심 위험 요소를 개략적으로 알아봤습니다. 표 3-1은 이

장에서 다룬 소재를 요약해놓았습니다. CI의 실천 방법들을 사용해 이 같은

위험 요소를 완화시키면 소프트웨어의 품질이 향상된다는 걸 알게 될 것입

니다.

표 3-1 위험 요소 및 완화 방법

위험 요소 완화 방법

배포 가능한 소프트웨어의 부재 CI 시스템을 이용해 언제라도 배포 가능한 소프트웨어를 빌

드하세요. 버전 관리 저장소에 소프트웨어 자산을 모두 올

려놓고, 되풀이할 수 있는 빌드 프로세스를 구축하세요.

뒤늦은 결함 발견 소프트웨어가 변경될 때마다 개발자 테스트를 포함해 빌드

하세요. 그러면 소프트웨어 생명 주기상 이른 시기에 결함

을 발견할 수 있답니다.

프로젝트 가시성의 부재 빌드를 주기적으로 돌려서 소프트웨어의 건강 상태를 항상

파악하세요. 지속적인 통합을 효과적으로 적용하면 프로젝

트의 상태를 궁금해하지 않아도 됩니다.

저품질의 소프트웨어 소프트웨어가 변경될 때마다 테스트와 검사를 돌리세요.

소프트웨어의 복잡도, 중복, 설계, 코드 적용범위 등과 같

은 요소를 알게 되어 코드 베이스에 발생할지 모르는 잠재

적 결함을 발견해낼 수 있습니다.

�2

Page 97: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

�3

chapter3 지속적인 통합을 이용해 위험 줄이기

질문

지속적인 통합이 도움이 될 만한 위험 요소가 여러분의 프로젝트에는 몇 개

나 있습니까? 다음의 질문이 프로젝트상의 위험 요소를 판단하는 데 도움이

될 겁니다.

프로젝트를 하면서 결함을 주로 발견하는 시기는 언제입니까? 생명 주기 초기입니까?

아니면 나중입니까?

품질을 어떤 식으로 파악합니까? 품질을 측정할 수 있나요?

어떤 과정을 사람이 직접 하나요? 자동화할 수 있거나 또는 자동화해야 하는 프로세스

는 어느 것인지 파악해본 적이 있습니까?

데이터베이스와 데이터를 다시 빌드할 때 필요한 스크립트를 모두 버전 관리 저장소에

넣어놨나요? 빌드하는 와중에 데이터베이스와 테스트 데이터를 다시 빌드할 수 있습니

까?

소프트웨어가 변경될 때마다 회귀 테스트를 수행할 수 있습니까? 기능, 통합, 부하 및

성능 테스트를 비롯한 다양한 유형의 회귀 테스트를 돌릴 수 있나요?

어떤 소스 코드에 그에 상응하는 테스트가 없는지 파악할 역량이 있습니까? 테스트 적

용범위 도구를 사용합니까?

소프트웨어 중 몇 퍼센트가 중복 코드인지 압니까? 그 양을 줄여보려 노력합니까?

어느 시점에서라도 그 때의 소스 코드가 소프트웨어 아키텍처에 부합하는지 여부를 검

증할 수 있습니까?

빌드 산출물이나 배포 산출물이 테스트할 준비가 됐다는 걸 어떻게 알립니까? 의사소통

메커니즘 중 어느 부분을 사람이 직접 맡고 있는지, 그리고 어느 부분을 자동화해야 하

는지 알고 있습니까?

소프트웨어의 지금 구조를 다이어그램으로 보일 수 있습니까? 프로젝트에 들어온 신참

개발자에게 소프트웨어의 아키텍처를 어떻게 전달합니까?

�3

Page 98: 지속적인 통합 : 소프트웨어 품질을 높이고 위험을 줄이기

64

P {[ }

] |\

“‘ Integrate

?/

Shift

��