2014년 1월 26일 일요일

프로젝트 관리 기법 - 타임박싱(Timeboxing) 관리 기법

 이번 포스팅에서는 지난번 포스팅했던 서적소개 - 실전 반복형 개발에서 잠깐 언급하였던 타임박싱에대해서 설명해 보고자 한다.

타임박싱의 원칙

타임박싱(Timeboxing)이란 반복형 개발에서 쓰이는 프로젝트 기획/관리 기법으로,  이터레이션에 할당된 작업을 완수하지 못하였을 경우 다음 이테레이션으로 넘긴다는 지극히 단순하고 간단한 일종의 규칙(discipline)이다. 타임박싱의 내용을 구체적으로 명시하자면 다음과 같다.

  1. 반복형(Iteration) 개발 방식으로 프로젝트를 진행한다.
  2. 작업내용을 잘게 나누고 각각의 작업에 소요될 시간을 추정한다. 작업소요시간 추정의 대표적인 기법으로는 플래닝 포커가 있다.
  3. 이렇게 추정된 작업들은 팀원들의 타임라인에 중요도와 상호 의존관계를 고려하여 적절하게 배치한다. 
  4. 상자를 쪼갤 수 없듯이 개별적인 작업들은 각각의 이터레이션 안에 완전히 들어갈 수 있도록 배치하여야 한다. 조금이라도 넘어간다면 다음 이터레이션으로 넘겨야 하는데 왜 그런지는 뒤에서 자세히 설명하겠다.

시간과 비용, 그리고 품질을 위해 작업범위를 희생하라

 프로젝트 매니지먼트 협회에서 발간하는 PMBOK(A Guide to the Management Body of Knowledge)에 따르면 프로젝트는 작업범위(Scope), 시간(Time), 비용(Cost) 그리고 품질(Quality)의 네가지 요소를 지닌다.  이 네가지 요소들은 상호 연관성을 지니며 프로젝트의 내용에 따라 우선순위가 달라진다.

 타임박싱은 이 네가지 요소중에 우선순위가 낮은 작업범위에 대해 유동성을 줌으로서 나머지 세가지 요소를 지켜내는것을 선택한다. 타임박싱을 사용하지 않는 프로젝트 매니지먼트의 경우에는 작업이 완료되지 않으면 이터레이션이 종료되지 않으므로 나머지 세가지 요소인 시간, 비용, 품질에 변경이 오게 되는데 일반적으로 이 세가지 요소는 동시에 나빠지는 경향이 있다. 

 즉, 납기를 맞추자면 동일한 시간에 더 많은 일을 해야 하고 이는 개발인원의 증가로 이어져 예산증가로 이어진다. 만약 예산을 맞추자면 이번에는 개발자 부족으로 인한 품질이 문제가 되게 되어 납기가 연장되는 악순환이 반복되게 되는데, 이러한 악순환은 원인에 대한 인식이 잘못된 경우가 많기 때문에 끊어내기가 대단히 어려울 뿐더러 한가지를 막아낸다 해도 나머지 두 요소에 치명적인 손실을 가져오는 경우가 많다.

작업범위의 우선순위가 낮은이유

 바로위의 문단에서 작업범위의 우선순위가 낮다고 하였는데 이에대해 조금더 설명해 보겠다.
 작업범위에 포함되는 내용은 크게 납품물로 지칭되는 프로젝트 작업범위(Project Scope)와 기능으로 지칭되는 제품 작업범위(Product Scope)를 들 수 있겠다. 이들은 각각 많은 세부 항목들을 지니게 되는데 이들에 대하여 우선순위를 정하고 고객의 승인을 받는 작업을 통해 작업범위의 축소/이관이 가능해진다.

 이러한 작업범위 내의 작업들에 대한 우선순위는 프로젝트 진행상황에 따라서 수시로 바뀌는 경향이 있으므로 프로젝트 매니저는 이러한 우선순위 변동에 대하여 지속적으로 체크해 나가고 이를 이터레이션 계획에 반영시켜 나가는 노력 만으로도 나머지 세가지 요소인 시간,비용,품질을 지켜 낼 수 있게 된다.


절대로 박스를 자르거나 찌그러트리지 말라!

타임박싱의 긍정적인 효과중 큰 부분은 반복형 개발의 리듬을 지킬 수 있게 해 준다는 점 이다. 반복형 개발은 몰입과 휴식의 반복이 가장 핵심적인 개념이다. 이터레이션 종료후의 휴식시간은 그냥 토일 쉬게 해주는 것 과는 다른다. 하나의 작업이 완료되고 정신적으로 몰입했던 일에서 완전히 빠져나와 개인적인 시간을 가질 수 있게 해 준다는 의미이다. 맨탈은 공짜가 아니다. 몰입은 심하게 맨탈 에너지를 소모하는 작업인만큼 휴식시간의 양과 질이 보장되지 않으면 다음 이터레이션에 사용될 맨탈의 양 당연히 줄어들게 된다.

보통 계획단계에서는 대부분 팀원의 타임라인이 이쁘게 채워질 것이다. 만약 기획단계에서 채위지지 않는 자투리 칸이 발생한다면 그것은 그것대로 놔 두는것이 중요하다.
작업이 진행됨에 따라 숨겨져 있던 요소들이 들어나고 각각의 작업들이 늘어나게 되는것은 개발 현장에서 흔히 볼 수 있는 풍경이다. 이때, 이터레이션에 들어가지 못하게된 작업은 다음 이터레이션으로 넘겨야 한다. 무리하게 이터레이션 안에서 소화하려고 하다 보면 결국 품질이 희생되게 될 학률이 높다. 끝나지 않은 상태로 두개의 이터레이션에 걸쳐 넘기는것도 좋지 않다. 작업의 품질과 이터레이션 이후 휴식에 문제가 되기 때문이다. 과감하게 다음 이터레이션으로 덤기도록 하자.

남은 시간에 들어가지지 않는 작업은 다음 이터레이션으로 넘겨야 한다. 


빈 공간은 창의성과 기술적 부채의 해결을 위한 시간이다

이렇게 생긴 자투리공간들은 테스트코드작성, 리팩토링, 문서화와 같이 개발자가 그동안 미뤄 왔던 기술적 부채의 상환에 사용할 수 있도록 한다. 생산성 향상을 위한 새로운 툴의 도입을 검토해 보는것도 좋을것이다. Jira나 Redmine과 같은 티켓 기반 관리툴을 사용할경우 작업자가 스스로 티켓을 끊고 자신의 타임라인에 붙여 넣기만 하면 된다.

작업범위 변경에 대한 힌트

 작업범위는 고객과의 약속이므로 변경 불가능하다는 고정관념을 가지고 있는 PM들이 많지만 이는 사실과 다르다. 고객이 원하는것은 제대로 작동하는 소프트웨어이지 부차적인 절차나 산출물이 아니기 때문이다. 프로젝트 제안서에 적힌 프로젝트 목표에 비추어 나열된 기능들과 산출물들이 어떠한 의미를 지니는지 되새겨 보자.

고객의 요구는 의외로 단순한 경우가 많다. 갑과 을의 관계에만 얽메여서 생각하지 말고 고객의 입장에서 프로젝트를 바라보고 우선순위를 다시 살펴봄으로서 윈윈할 수 있는 타협점을 찾아야 한다.



 작업범위 변경에 대해서 고려해야 하는경우(우선순위 재 배치) 다음과 같은 항목들이 우선적인 고려의 대상이 될 수 있을것이다.

 쓸데없는 납품물: 작동하는 소프트웨어와 별개의 부분들. 특히 문서화 작업에 대해 다시한번 생각해 보자. 이미 작업과 상관없게 되어 버린 상세 설계서를 유지해 나가는것은 고객에게 있어서 아무런 도움이 되질 않는다. 무거운 문서화를 피하는 방법에 대해서는 문서화에 대한 이전 포스팅이 도움이 될 것이다.

 혹시나 기능: 미래에 이러이러한 일이 있을지도 몰라 추가로 만들어 놓는 기능들이 있다. 이러한 기능들은 프로젝트 중간에 고객과의 재 검토를 갖는것 만으로도 필요 없는것으로 판명되는경우가 많다.

 기술적 부채: 기술적 부채도 이관이 가능한 작업범위중 하나이다. 기술적 부채에 대한 자세한 사항은  기술적 부채에 대처하는 자세를 참고해 보기 바란다.



요구사항을 동결시키는 효과

물위를 걷는 것은 쉽다. 만약 물이 얼어 있다고 한다면 말이다.

 위의 문구는 인터넷에 떠도는 사양 변경에 대한 어려움을 물위를 걷는것에 비유한 글 이다.
 많은 개발자들이 고객의 요구사항 대응이 어렵다고 말을 한다.
하지만 열심히 해서 그러한 대응에 모두 대응 할 수 있는가? 현실적으로 불가능한 경우가 대부분일 것이다. 납기를 지키면 품질에 문제가 생기고 품질을 지키면 납기를 지연 시킬 수 밖에 없다. 이것은 명백한 사실이다.

 이것저것 변경을 요구해 오는 고객에 대해서 "예. 알겠습니다. 어떻게든 열심히 해서 일정을 맞춰 보겠습니다" 라고 말 해 놓고 정작 프로젝트 말미에 가서 "열심히 했지만 납기를 지킬 수 없습니다. 정말 죄송합니다."라고 말 하면 좋아할 고객이 있을까?

 "이번 프로젝트(또는 이터레이션)에서는 현재 가능한 최선의 일정으로 일 하고 있습니다. 만약 이러한 변경을 이번에 반영하고 싶다면 동등한 비용이 발생하는 다른 기능을 다음 개발로 넘기셔야 합니다" 라고 알리고 현실적인 대응 반안을 제시하는 것이 훨씬 나은 방법일 것이다.

 물론 이러한 대화가 이루어지려면 현실적인 스케줄에 대한 추정이 있어야 하며 작업 범위에 대한 정확한 산출과 프로젝트 현황에 대한 파악이 있어야 할 것이고 이것은 어디까지나 고객과의 신뢰관계가 쌓여 있을 경우에만 가능하다는 사실이다. 수치를 제시하지 못하는 설명은 설득력을 지니지 못한다는 사실을 명심하라.

타임박싱을 이용하지 않을 이유가 하나도 없다!

반복형 개발을 기반으로 하는 스크럼이나 간반과 같은 애자일 개발은 물론이고 전통적인 폭포수형 개발에 있어서도 타임박싱은 매우 유용하다.  폭포수형 프로젝트에서도 그 나름의 시간 구획이 존재하기 때문이다.

타임박싱은 성공한 많은 프로젝트 들에서 채택되어 그 효용성을 입증 받았으며 DSDM(Dynamic systems development method), RAD(Rapid application development software development), Scrum, Extreme programming과 같은 프로젝트 관리 방법론에서 기본적으로 채택되고 있다. 사실상 SI에 에자일방법론을 적용 시킬 때 필수적인 기법이라 할 수 있겠다.

Trac이나 Redmine과 같은 이슈추적 시스템을 사용해 프로젝트 관리를 하고 있다면 티켓(테스크)의 타겟버전을 변경하는 것 만으로도 손쉽게 작업을 다음 이터레이션으로 이관하는것이 가능해진다.


2014년 1월 21일 화요일

티켓 주도 개발(ticket-driven development; TiDD)

이번 포스팅은 위키피디아 일본어판의  티켓 주도 개발 설명에 기초하여 작성되었음을 밝혀둔다.

티켓 주도 개발이란?

티켓 주도 개발(ticket-driven development; TiDD)이란 일본발 소프트웨어 개발 방식중 하나로 개발 과정 발생하는 테스크를 분할한 후에 이를 Track, Redmine과 같은 이슈 트래킹 시스템에 등록하여 관리해 나가는 개발 스타일을 지칭한다.  WBS(Working Breakdown Structure)를 기반으로 하는 기존의 폭포수 개발방식은 물론이고 XP나Scrum, Kanban과 같은 애자일 개발과도 궁합이 좋다.  같은 이니셜을 지니게 되는 테스트 주도 개발(TDD)과 구분하여 TiDD라는 약칭을 사용한다.

프로젝트 룰

기본적으로 티켓 주도 개발에 있어서 룰은 단 한가지다.

No Ticket, No Commit! (티켓 없이는 커밋도 없다!)

Subversion이나 Git를 이용하는 형상관리상, 커밋이란 개인이 관리하는 소스가 공동관리하에 들어간다는 것을 의미한다.  룰은 단순하지만 이슈트래커에 모든 테스크가 관리됨에 따라 개개인의 작업에 대한 파악이 간편해지고 성과물의 갱신이 반드시 티켓과 연관지어지게 됨에 따라 변경이유가 명확해지는것이 이 티켓 주도 개발의 매리트이다.

개발 사이클

티켓 주도 개발은 일반적으로 다음과 같은 PDCA(Plan/Do/Check/Action)사이클의 반복이다.


  • 큰규모의 릴리즈 계획을 작성한다
  • 작업을 작은 단위의 테스크로 분할하여 이슈 트래커에 등록한다.(티켓 등록)
  • 이터레이션 단위로 테스크를 모아 이터레이셔계획을 작성한다.
  • 테스크를 선택하여 실시한다.
  • 결과물을 커밋하고 종료한다.(티켓 클로즈)
  • 이터레이션에 포함된 모든 테스크가 종료되면 릴리즈를 실시한다.
  • 릴리즈후에 작업에 대한 회고를 진행한다. 
  • 다음 이터레이션계획에 고객의 요구사항과 회고의 내용을 반영한다.


이점

티켓 주도 개발의 이점은 다음과 같다.


  • 언제나 누구든지 티켓을 참조하는것이 가능해져, 커뮤니케이션이 쉬워진다.
  • 돌발적인 테스크 변경에도 티켓 속성의변경이 간단하므로 변화대응이 쉽다.
  • 이터레이션 작업량을 일정하게 하는것으로 작업의 리듬을 만들어 나갈 수 있다.
  • 티켓을 이터레이션 단위로 관리해 나가기 때문에,  빈번한 릴리즈를 가능하게 한다.
  • 티켓이 소스코드,요건,테스트케이스와 연관지어지므로 상호 추적이 가능해진다.
  • 이러한 티켓중심의 워크플로는 버그관리뿐만 아니라 요건관리를 포함해 소프트웨어 개발 전 과정에서 응용 가능하다.  
  • 진척관리면에서 모든 작업 진행상황이 투명해 지므로 프로젝트 현황의 파악이 대단히 용이해진다.

성공을 위한 팁

끝으로 필자가 티켓 주도 개발에 참여하며 느낀점을 간단히 정리해 보았다.

  • 무엇보다 팀원 개개인이 프로젝트의 주체로서 능동적으로 행동해 나간다는 의식이 TiDD 성공의 열쇠이다. 역으로 티켓 주도 개발의 큰 장점중 하나는 이러한 의식을 뿌리 내리게 하는데 도움을 준다는 점이다. 처음 도입시에는 여러가지 어려움이 많으므로 적절한 외부 코칭이나 기존에 시행하고 있는 팀과의 노하우 공유가 큰 도움이 된다.
  • 티켓의 할당은 개개인이 선택하는것이 바람직하며 데일리 미팅등을 통해 팀원들과 진척사항을 공유해 나가야 한다. 
  • 형상관리 시스템에 커밋시 특정 형식에 맞추어 번호를 기입하는 것 만으로도 이슈트래커가 티켓과 소스의 링크를 자동 생성해 주는 기능을 이용한다.
          Trac Links
          Redmine의 Subversion연동설정

  • 최초 티켓 등록은 PM이나 팀 리더에 의해 이루어지 지지만 테스크 진행 결과 서브 테스크 분할이나 후속작업등이 필요하게 되는 경우에는 추가로 티켓을 발행한다.
  • 티켓 분할은 일단위 작업이 될때까지 진행하는것을 권장한다.
  • 타임 박싱 관리기법에 의해 릴리스 시기에 맞추지 못하게 된 우선순위가 낮은 티켓은 다음 릴리스로 이관한다.
  • 이슈 트래커 툴의 선택에 있어서는 Trac과 Redmine을 추천하며 특히 Redmine의 경우 티켓간의 관계설정(전/후,부모/자식)이나 상태전이를 커스터마이징등의 기능들이 기본제공된다.
  • 작업자들은 리팩터링이나 테스트케이스의 추가를 능동적으로 판단하여 티켓에 등록할 수 있어야 하고 PM과 우선순위와 일정등을 협의한다. (기술적 채무 관리에 크게 도움이 된다.)
  • 프로젝트 관계자간에 적절한 정보공유와 커뮤니케이션이 이루어 질 수 있도록 위키와 게시판등을 병행하여 사용한다. 일반적으로 메일을 사용하는 경향이 있는데, 메일의 경우 보관이나 업데이트의 면에서 유지모델을 다루기엔 부적합하다. 
  • Redmine의 경우 커뮤니케이션과 관련하여 풍부한 기능을 제공하고 있는데 모두 사용할 필요는 없다. 프로젝트의 규모와 성격, 팀 구성에 따라 적절하게 선택하여 사용한다.
  • 태생이 일본이다 보니 TiDD와 관련된 노하우는 일본어로 된 정보가 풍부하다. 구글 번역기등을 이용하면 여러가지 실천적 노하우를 쉽게 찾아 볼 수 있다.
TiDD는 일본에서 다양한 소프트웨어 개발 프로젝트의 관리기법으로 선호되고 있으며 특히 빠른 릴리즈를 선호하는 모바일 어플리케이션 개발의 경우 보편적으로 사용되고 있다.


2014년 1월 16일 목요일

주석(comment)을 달지 말아야 하는 이유


일전에 애자일 개발에서의 문서화 작업에 대한 블로깅에서도 밝힌바와 같이 도큐멘테이션은 프로젝트의 목적(납품물)이 아닌 커뮤니케이션을 위한 수단이 되어야 한다. 올바른 문서화을 위한 원칙을 다시한번 간략히 살펴보자.



정보의 중복 금지: 같은 내용을 여러군데 적지 말라. 쓸데없는 노력이 들어갈 뿐만 아니라 결국에는 서로 다른 내용을 지닌 문서/코드를 보게될 것이다. 

코드에 포함 가능한 정보는 코드에 포함하라: 동일한 내용이 여러 장소에 적힐 수 있다면 코드가 우선시 되어야 한다. 코드에 표현하기 어려운 정보라면 그 다음 순위는 유지모델이 될 것이다.

라이프 사이클을 구분하여 사용하라: 프로젝트 내내 지속적으로 유지해야만 하는 유지모델과 특정 단계에서만 구성원들의 의식 통일을 위해 사용하는 임시모델을 구분하여 사용한다. 아키텍처 정의나 ER다이어그램과 같은 문서는 프로젝트가 끝난 후라 할 지라도 유지보수를 위해 여전히 유용한 반면, 특정 기능 구현을 위한 시퀀스 다이어그램이나 클래스 다이어그램과 같은 임시 모델은 회의를 진행하면서 화이트보드에 적은 내용을 디지털사진으로 남기는 것 만으로도 충분한 경우가 많다. 

주석을 달지 말아야 하는 이유

코드에 주석을 달지 말아야 하는 이유는 정보의 중복을 피하기 위해서입니다. 주석을 열심히 달기 보다는 읽기쉬운 코드를 만든는데 집중하세요. 메소드 내의 처리를 단일 기능 단위로 분할 하고 하고 각종 네이밍에 주의를 기울이십시오. 프로그램 사양에 대한 기술은 코드의 주석보다는 테스트 케이스의 Javadoc에 기대하는 동작을 기술하세요. 이렇게 작성된 Javadoc은 그 자체로서 훌륭한 상세설계서가 됩니다. - 나가사토(나가사토씨는 필자와 같은 Mamezou소속의 애자일 컨설턴트 이며 Disciplined Agile의 일본어판 번역을 비롯해 다수의 기술서적을 번역하였다.)

필자는 사실 테스트케이스의 Javadoc조차도 최소한의 내용만을 적는것이 좋다고 생각한다. 테스트 코드도 실행코드와 마찬가지로 코드 자체의 가독성을 최대화 하는것에 집중하는것이 좋다고 생각하기 때문이다.

잘 작성된 주석은 프로그램의 가독성을 매우 향상시킬 수 있는 반면, 잘못 작성된 주석은 프로그램의 가독성을 해칠 수 있다. 
코드 컴플리트(스티브 맥코넬, 2005)

주석을 달지 않는 코딩 유형은 자바의 코어 라이브러리 소스 코드를 비롯해 대부분의 오픈소스 코드에서 쉽게 확인 할 수 있다.

예제1) 스프링 소스코드
     @Override  
     public void initialize(  
             Servlet servlet, ServletRequest request, ServletResponse response,  
             String errorPageURL, boolean needsSession, int bufferSize, boolean autoFlush) {  
         throw new UnsupportedOperationException("Use appropriate constructor");  
     }  
     @Override  
     public void release() {  
     }  
     @Override  
     public void setAttribute(String name, Object value) {  
         Assert.notNull(name, "Attribute name must not be null");  
         if (value != null) {  
             this.attributes.put(name, value);  
         }  
         else {  
             this.attributes.remove(name);  
         }  
     }  
     @Override  
     public void setAttribute(String name, Object value, int scope) {  
         Assert.notNull(name, "Attribute name must not be null");  
         switch (scope) {  
             case PAGE_SCOPE:  
                 setAttribute(name, value);  
                 break;  
             case REQUEST_SCOPE:  
                 this.request.setAttribute(name, value);  
                 break;  
             case SESSION_SCOPE:  
                 this.request.getSession().setAttribute(name, value);  
                 break;  
             case APPLICATION_SCOPE:  
                 this.servletContext.setAttribute(name, value);  
                 break;  
             default:  
                 throw new IllegalArgumentException("Invalid scope: " + scope);  
         }  
     }  

예제로 제시한 코드는 주석이 필요 없을정도로 간결하다. 이번엔 테스트코드를 살펴보자.

예제2) 테스트코드
 /**  
  * Unit tests for the {@code MockPageContext} class.  
  *  
  * @author Rick Evans  
  */  
 public final class MockPageContextTests extends TestCase {  
     public void testSetAttributeWithNoScopeUsesPageScope() throws Exception {  
         String key = "foo";  
         String value = "bar";  
         MockPageContext ctx = new MockPageContext();  
         ctx.setAttribute(key, value);  
         assertEquals(value, ctx.getAttribute(key, PageContext.PAGE_SCOPE));  
         assertNull(ctx.getAttribute(key, PageContext.APPLICATION_SCOPE));  
         assertNull(ctx.getAttribute(key, PageContext.REQUEST_SCOPE));  
         assertNull(ctx.getAttribute(key, PageContext.SESSION_SCOPE));  
     }  
     public void testRemoveAttributeWithNoScopeSpecifiedRemovesValueFromAllScopes() throws Exception {  
         String key = "foo";  
         String value = "bar";  
         MockPageContext ctx = new MockPageContext();  
         ctx.setAttribute(key, value, PageContext.APPLICATION_SCOPE);  
         ctx.removeAttribute(key);  
         assertNull(ctx.getAttribute(key, PageContext.PAGE_SCOPE));  
         assertNull(ctx.getAttribute(key, PageContext.APPLICATION_SCOPE));  
         assertNull(ctx.getAttribute(key, PageContext.REQUEST_SCOPE));  
         assertNull(ctx.getAttribute(key, PageContext.SESSION_SCOPE));  
     }  
 }  

테스트 코드 역시 매우 간결한 모습을 띄고 있다.
코드의 가독석을 높이는 가장 좋은 방법은 코드를 심플하게 유지 하면서 네이밍, 특히 변수의 네이밍에 신경을 써 주는것이 효과적이다.

변수명과 네이밍에 대한 내용은 코드 컴플리트에서 더할나위 없이 훌륭하게 다루어지고 있으므로 아직 읽어보지 않은 분이라면 꼭 읽어들 것을 추천한다.

2014년 1월 13일 월요일

젠킨스(Jenkins)를 이용한 지속적 통합(CI:Continuous Integration) (2) - 젠킨스씨가 있는 개발풍경

젠킨스(Jenkins)를 이용한 지속적 통합(CI:Continuous Integration)
(2) 젠킨스씨가 있는 개발풍경


젠킨스에 대한 두번째 포스팅으로 오늘은 젠킨스가 실제 프로젝트에서 어떤 형태로 사용될 수 있는지 살펴 보고자 한다.

젠킨스씨가 있는 개발풍경


하루 24시간이 모자르신 젠킨스씨

형상관리 툴과의 연동

젠킨스와 같은 CI툴이 등장하기 전에는 일정시간마다 빌드를 실행하는 방식이 일반적 이었다. 특히 개발자들이 당일 작성한 소스들의 커밋이 모두 끝난 심야 시간대에 이러한 빌드가 타이머에 의해 집중적으로 진행되었는데 이를 nightly-build라 한다. Fire Fox와 같은 많은 오픈소스 프로젝트들은 정식 배포 버전과 별도로 nightly-build에서 생성된 바이너리를  함께 배포함으로서 오픈 베타테스트 또한 지속적으로 수행 할 수 있게  되었다.

젠킨스는 정기적인 빌드에서 한반 나아가 서브버전, Git와 같은 버전관리 툴과 연동하여 소스의 커밋을 감지하면 자동적으로  자동화 테스트가 포함된 빌드가 작동되도록 설정 할 수 있다.



물론 개발도중의 프로젝트에서 커밋은 매우 빈번히 일어나기 때문에 커밋 횟수만큼 빌드를 실행하는 것이 아니라  큐잉되어 자신이 실행될 차례를 기다리게 된다.

코드의 변경과 함께 이뤄지는 이같은 자동화된 빌드와 테스트 작업들은 다음과 같은 이점들을 가져다 준다.


  • 프로젝트 표준 컴파일 환경에서의 컴파일 오류 검출
  • 자동화 테스트 수행
  • 정적 코드 분석에 의한 코딩 규약 준수여부 체크
  • 프로파일링 툴을 이용한 소스 변경에 따른 성능변화 감시
  • 결합 테스트 환경에대한 배포작업

이 외에도 젠킨스는 500여가지가 넘는 플러그인을 온라인으로 간단히 인스톨 할 수 있는 기능을 제공하고 있으며 파이선과 같은 스크립트를 이용해 손쉽게 자신에게 필요한 기능을 추가 할 수도 있다.

각종 배치 작업의 간략화 

프로젝트 기간중에 개발자들은 순수한 개발 작업 이외에 DB셋업이나 환경설정, 디플로이 작업과 같은 단순 작업에 시간과 노력을 빼았기는 경우가 빈번하다.
데이터베이스의 구축, 어플리케이션 서버에의 디플로이,  라이브러리 릴리즈와 같이 이전에 커맨드 라인 인터페이스로 실행되던 작업들이 젠킨스 덕분에 미려한 웹인터페이스로 손쉽게 가능해 지게 되었다.

젠킨스씨는 거들뿐

이와같이 다양한 작업들을 손쉽게 처리해 주지만 테스트를 만들고 빌드 전략을 세우는 등의 작업은 여전히 개발자의 몫으로 남아 있다. 젠킨스가 진정으로 프로젝트에 도움이 되기 위해서는 다음과 같은 작업이 반드시 함께 이루어 져야 한다.

Build 자동화의 확립: 빌드 툴의 경우 Java는 이미 Maven이 대세로 자리잡았다. 물론 Ant도 훌륭한 기능들을 많이 갖추고 있지만 플러그인의 편리함은 Maven을 따라잡지 못한다. 이미 빌드 관리 툴을 이용해 프로젝트를 진행하고 있다면 Jenkins를 사용하지 않을 이유가 하나도 없다.

자동화 테스트: 자동화 테스트야 말로 젠킨스를 사용해야 하는 이유중 으뜸이며, 사실상 자동화 테스트가 포함되지 않은 빌드는 CI자체가 불가능하다고 봐도 무방하다. 젠킨스는 Subversion이나 Git와 같은 버전관리 시스템관 연동하여 코드변경을 감지하고 자동화 테스트를 수행해 줌 으로서 만약 개인이 미처 실시하지 못한 테스트가 있다 하여도 든든한 안전망이 되어준다.
무엇보다 중요한것은 이러한 안전망이 제공해 주는 안심감이야 말로 개발자들이 악취나는 코드를 리팩토링을 통해 적극적으로 제거 할 수 있게 해 주는 든든한 버팀목이 된다는 점이다.


제대로 테스트를 거치지 않은 코드를 커밋하게 되면 화난 젠킨스씨를 만나게 된다.

테스트 커버리지: 젠킨스는 자동화 테스트 실시와 더불어 테스트 커버리지도 리포팅을 해 준다. 개인적으로 테스트 커버리지가 품질에 대해서 기여하는 부분에 대해서는 회의적인 입장이다. 결국 자동화 테스트의 작성 자체는 프로그램 사양에 대한 개발자 심도있는 고찰을 기반으로 하는데 커버리지 라고 하는 일괄적인 기준으로 제약을 가하게 되면 테스트가 본래의 의미를 잃어버린 커버리지를 달성하기 위한 테스트가 만들어지기 쉽기 때문이다.
젠킨스에서는 다양한 형태로 클러스터링을 지원하는데, 자동화 테스트가 충실하게 작성된 프로젝트라면 테스트에 상당한 컴퓨팅 파워가 투입되어야 하기 때문이다. 

코드 표준 준수여부 검사: 자동화 테스트와 마찬가지로 개인이 미처 실시하지 못한 코드 표준 준수여부의 검사나 정적 분석을 통한 코드 품질  빌드 내부에서 수행하는 것으로서 기술적 부채의 감소에도 크게 기여한다.

빌드 파이프라인 구성: 2개 이상의 모듈로 구성되는 프로젝트의 경우 당연하게도 레이어드 아키텍처가 적용되어 있을터이고 그에 따른 빌드 파이프라인 구성이 필요하다. 예를 들자면 도메인 -> 서비스 -> UI와 같이 각 레이어의 참조관계에 따라 순차적으로 빌드를 진행하지 않으면 안된다. 이러한 파이프라인의 구성은 선형뿐만 아니라 간단한 스크립트를 통해 매우 복잡한 제어 까지도 가능하다.

Build Pipeline Plugin을 이용하면 논리 구조를 가진 파이프라인도 웹 인터페이스를 통해 간단히 만들 수 있다.