'agile'에 해당되는 글 2건

  1. 2007/10/29 PHPUnit에서 Trac까지 (1)
  2. 2007/02/20 웹 어플리케이션의 개발 (3)
이글을 쓰는 시점에서 PHPUnit과 Trac은 완벽하게 붙지는 않는다. 그래도 시늉까지 해 보는 방법을 설명한다. 이후 좀더 깔끔하게 된다면 업데이트 하겠다.

유닛테스팅은 최근의 개발방법론에서 중요한 요소이다. 유닛테스트를 깨지지 않게 하는 것은 코드의 안정성을 유지하는 좋은 방법중 하나이다. 혹은 TDD(Test Driven Development)를 적용하는데도 기본적인 방법이다. CruiseControl을 사용해서 SubVersion Repository를 감시하며 지속적으로 실행하는 방법도 있겠지만 Trac에 바로 통합하는 방법을 설명코자 한다.

목표는 아래와 같다.
커밋이 일어나면 자동으로 유닛 테스트가 수행되고 그 결과가 Trac 페이지에 떡하니 뜨길 바란다.

우선 Trac과 SubVersion은 설치되어 있고 서로 잘 연결되어 있는 것으로 가정하겠다. (물론 이것도 아직 쉬운편은 아니다. python이 국내에선 그리 인기있는 플랫폼도 아니고...)

bitten의 설치는 http://bitten.edgewall.org/wiki/Documentation/install.html을 보면서 삽질을 좀 하면 된다. 우선 ez_setup이 필요하다.
wget http://peak.telecommunity.com/dist/ez_setup.py
sudo python ./ez_setup.py
sudo로 명기한 것은 슈퍼유저 권한이 필요한 것이니 참고.
아직 bitten은 적당한 패키지를 제공하지 않는다. 소스를 받아야 한다.
svn co http://svn.edgewall.org/repos/bitten/trunk bitten
sudo python setup.py install
trac의 config(conf/trac.ini)에서 플러그인을 활성화 시켜주자. 아래는 추가할 내용이다.
[components]
bitten.* = enabled
퍼미션을 주자.
sudo trac-admin TestProject upgrade

sudo trac-admin TestProject permission add anonymous BUILD_EXEC
sudo trac-admin TestProject permission add anonymous BUILD_VIEW
sudo trac-admin TestProject permission add <관리자 계정> BUILD_ADMIN
웹어드민도 필요한데 아래의 과정을 수행한다.
wget "http://trac.edgewall.org/attachment/wiki/WebAdmin/TracWebAdmin-0.1.2dev_r4240-py2.4.egg.zip?format=raw"
받은 파일의 zip 확장자를 없애 준다. (rename) 그리고는

sudo easy_install TracWebAdmin-0.1.2dev_r4240-py2.4.egg

trac config에 아래 내용을 추가한다.
[components]
webadmin.* = enabled

마지막으로 아파치 한번 리스타트를 해 준다.


이제 Trac으로 들어가보면 Build라는 탭이 보인다. Admin에 가서 Builds/Configuration으로 가보자.
새로운 빌드를 만들때 중요한 점은 타겟을 적어도 하나 만들어야 한다. 그리고 레시피가 중요하다.
<build xmlns:svn="http://bitten.cmlenz.net/tools/svn" xmlns:php="http://bitten.cmlenz.net/tools/php" xmlns:sh="http://bitten.cmlenz.net/tools/sh" > <step id="Update" description="Update source from repository" svn:update revision="${revision}" /> </step> <step id="test" description="Run unit tests"> <sh:exec executable="/usr/bin/phpunit" <args="--log-xml testsuit/results.xml --tap testsuitSuiteForLib testsuit/testsuitSuiteForLib.php" /> <php:phpunitsuite file="testsuit/results.xml" /> </step> </build>
레시피 만드는 방법은 http://bitten.edgewall.org/wiki/Documentation/commands.html 를 참고하시고,
phpunit 실행부의 args는 phpunit의 설명을 보고 잘 맞춰보기 바라다. xml로 결과를 출력하며(필수) testsuit/testsuitSuiteForLib.php에서 testsuitSuiteForLib클래스를 수행한다.

위에서 보면 php:phpunit을 사용하지 않고 php:phpunitsuite라는 것을 사용한다. 단순히 testcase를 사용하는 경우 phpunit을 사용하면 되지만 suite를 사용하는 경우 파싱 에러가 난다. 이는 현재 http://bitten.edgewall.org/ticket/199 상황이다. 여차하면 수정을 제안하겠는데 python은 젬병이라 땜빵을 했다.

우선 bitten 소스에서
Index: setup.py
===================================================================
--- setup.py    (revision 515)
+++ setup.py    (working copy)
@@ -68,6 +68,7 @@
             NS + 'java#cobertura = bitten.build.javatools:cobertura',
             NS + 'php#phing = bitten.build.phptools:phing',
             NS + 'php#phpunit = bitten.build.phptools:phpunit',
+            NS + 'php#phpunitsuite = bitten.build.phptools:phpunitsuite',
             NS + 'php#coverage = bitten.build.phptools:coverage',
             NS + 'python#coverage = bitten.build.pythontools:coverage',
             NS + 'python#distutils = bitten.build.pythontools:distutils',

그리고 bitten/build/phptools.py 에서 "def phpunit"이란 곳을 찾아서 해당 함수를 아래에 복사한 후 phpunitsuite라는 함수로 변경한다.
for testsuit in xmlio.parse(fileobj).children('testsuite'):

부분을
for testsuitset in xmlio.parse(fileobj).children('testsuite'):
    for testsuit in testsuitset.children('testsuite'):

로 수정하고는 들여쓰기를 맞춰준다. 그리고는 다시 설치한다. 이걸로 대충 준비는 끝났다.

사용자 삽입 이미지

PHPUnit 테스트파일을 어떻게 만드는지는 다음 시간에. (같이 적으려니 글이 무척 길어진다.)
우선 동기의 글

연휴동안 한 일 - 설계를 문서화 하기... from 써니의 一生牛步行

태생이 시스템 프로그래머(System Programmer : 이후 SPer)요 웹쪽을 한지 이제 만 1년이 된 상황에서 저 글을 본 후 뭔가 부자연스러움을 느꼈다. UI화면에서 어떻게 상세기획서급의 문서가 나오는가에 대해서다. 이말에 동감을 하는 쪽이라면 SPer이요 당연하다고 느낀다면 웹 개발쪽을 많이 한 사람일 가능성이 높다고 본다. 최근에 웹 기획자랑 서로 외계어(!)로 대화를 했고 서로가 서로를 이해 못했었는데 현재의 가정이 맞다면 당연히 서로 100만 광년을 떨어져서 이야기 한 셈이라고 본다. 틀리면 다시 머리 싸메고 분석해야 하는 것이고.


웹 기획자란

구글을 뒤져보니 이런 링크를 찾았다.
웹 기획자가 하는 일 - 김중태문화원 1기 블로그

중간에 기획자가 하는 업무중 4번째

4. 고객이 해당 견적서와 제안서를 수용하면 개발팀과 의논하면서 개발 기획을 작성해 일정을 잡고, 일정이 잡히면 구체적인 스토리보드를 작성한다.
고객과 홈페이지에 들어갈 내용이 확정되면 바로 스토리 보드에 뛰어 드는 것이다. 이것을 기반으로 이후 HTML 코드의 기반이 잡히고 CSS가 적용될테니 나름 상위기획이겠지만 나의 눈에는 이것은 화면디자인이고 아직 요구사항 분석이나 사용자 시나리오 분석도 되지 않았는데 화면 상세 디자인을 붙잡고 있느냐라고 반문하게 된다. 이 반문은 "프로젝트를 콩가루로 만들지 않겠다라는 투철한 의지"에 활활 타올라 말하는 것이겠지만 전통적인 웹 기획자는 "자다가 봉창 두드리는 소리"로 밖에 들릴 수 없는 것이다.

전통적인 웹페이지, 그리고 웹 어플리케이션
내가 최초로 본 웹 페이지라고 한다면 몇시간에 걸쳐 트럼펫 윈속(Trumpet WinSock)과 Mosaic Browser를 끙끙대며 설치하여 접속한 NASA 홈페이지일 것이다. http://www.nasa.gov/
간만에 들어가 보니 플래시에 복잡한 컨텐트를 가지고 있지만 당시엔 그림한장과 장황한 글을 볼 수 있었다. 불과 10년전만 하더라도 대용량의 컨텐츠(그림 등)를 사용하는 것은 거의 죄악에 가까웠지만 지금은 몇백Kbyte쯤은 쉽게 쓰고 있다.
회사의 홈페이지나 기타 정적인(Static or Near-Static) 내용을 보여주는 웹 페이지의 구축에 있어서는 위의 개발 방법론(스토리보드를 통한 상위기획)이 매우 적당할 수 있다. 여기서 Near-라고 표기한 것은 복잡한 비지니스 로직이 있는 것이 아닌 관리자가 차례대로 넣은 데이터를 단순한 조회로 가져와서 보여주는 정도도 포함되기 때문이다. 하지만 이것을 BlahBlah-Market 같은 시스템(홈페이지가 아니다)을 구축하는데 사용했다간 이전에 비행기가 떨어지고 우주선이 행방불명이 되듯 개발 구성원들은 다 암걸리고 회사는 문을 닫아야 할지 모른다. 단순히 동적인(Dynamic) 데이터를 보여주는 페이지가 아니라 웹 브라우저를 Front-End 즉 UI(User Interface)로 사용하는 프로그램으로 봐야 하기 때문일 것이다.

이런 생각에 대해서 개인적은 확증은 없다. 하지만 심증(?)이 가는 것은 갑자기 SOA(Service Oriented Architecture)나 CBD(Component Based Development)등 SPer인 나에게는 당연한 소리가 대두되고 웹 어플리케이션 개발에 BCD(Business Concept Diagram: CBD에서 사용. 여기(PDF)를 참고)가 멋있지 않느냐라고 하는 것을 보았기 때문이다. 정확히 객체들(요구사항이나 기능, 비지니스 로직, 서비스든 컴포넌트든 페이지든)에 대해 정의를 제대로 내리지 않고 어플리케이션을 작성해 나간다면 태초에 소프트웨어라는 것이 생겨날 때 부터 발생한 문제들을 그대로 떠안게 된다. 부정확한 개발, 일정 연기, 개발자 도망, 유지 보수 불가능 등.

소규모 상점 사이트를 만든다고 하였을 때 전통적인 웹 페이지의 개발대로 만드는 것이 지금까지 큰 문제를 일으키진 않았다. 물건의 속성이 명확하고 그것을 바로 스토리보드(Story Board)에 기입할 수 있기 때문이다. 그러나 많은 사이트들이 문제를 일으키는 페이지가 있다. 바로 결제페이지다. 국내법상 특정 정보들은 반드시 HTTPS(HTTP over SSL)이나 기타 암호화 방식을 사용해야 하고, 물건 리스트와 결제 정보, 배송지나 최종 카드의 승인까지 몇단계로 나누어 지는 과정을 가지고 있다. 이 과정이 독립적이고 단방향이길 바라겠지만 웹의 특성상 앞뒤로는 일반 페이지들이 존재하고 중간에 튀어 나올 수도 있고 재전송/중복전송이나 역방향으로 움직일 때도 있다. 마지막으로 해커들도 존재한다. 전통적인 모델링으로 이를 Transaction으로 정의하고 각 페이지를 State로 본 후 State Transition Diagram 그리면 SPer들은 쉽게 해결할 문제지만 단순한 Story Board에서는 이 관계를 명확히 표시하거나 디자인에 대한 검증(Analysis)이 쉬운 편은 아닐 것이다. 그래서 중복 결제나 처음부터 다시라는 메시지가 나오기도 하고 해커들에게 공략 당해도 보완하기 힘들게 된다.

웹 어플리케이션의 개발 방법론
웹 페이지 소리만 나오면 이제 CBD 같은 것을 사용하라는 의미는 아니다. 케이스에 따라서는 스토리 보드를 통한 상위기획이 효율적일 수도 있고 다른 특성들을 가지는 방법들도 있을 것이다. 역시나 만능의 Silver Bullet(은총알. 흡혈귀를 잡을 수 있는 아이템, 어떤 문제를 확실히 해결 할 수 있는 방법이란 의미, 자세한건 구글에게 물어보세요)은 없다는 현재까지의 정설이다. 그렇다면 역시 마늘 엑기스와 십자가중 하나를 선택해야 할 것이다. 능력이 되면 맞짱 떠서 가슴에 말뚝이라도.

프로젝트의 시작부에서 아이디어가 발의된 후 정리되고 전체적인 무엇인가(아직 프로그램인지 웹사이튼지 모름) 윤곽이 잡힐 즘에 계획(Planning) 단계를 거칠 때 그 앞뒤로 해야 할 작업중 하나는 개발 방법론의 계획일 것이다. 아이디어의 창안자의 머리속에 뭉게뭉게 피어나는 생각이 프로젝트화 될 때는 어느정도의 윤곽이 잡힐 것이고 이것의 특성이 파악되고 더불어 상황에 따라 적당한 방법론을 찾는 것이 그 시점의 Manager가 할 일일 것이다.

그러나....

위에서 계속 큰 이야기만 했지만, 상세 설계서에서 "필드는 디비 테이블 직접 보셈"은 나중에 여러모로 문제가 될 소지가 많은 문구일 것이다. 전체 프로젝트에서 중요한 부분이든 아니든 데이터의 처리(Processing)가 일어난다면 해당 모듈은 프로그램이기 때문이다. 뭐 몇개월 후에 관계가 없을 프로젝트라면 상관 없지만 말이다.