달력

122019  이전 다음

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  •  
  •  
  •  
  •  
최근 TSS에 재밌는 기사가 하나 떴습니다. 테스트케이스가 공식적으로 개발과정에 포함되는지 아니면 비공식적으로 만들어지는지에 관한 조사였습니다. 2006년에 이어서 2년 후인 2008년 설문을 진행했습니다. 데이터는 다음과 같습니다.

Answers 2008 (2006)
Unit testing is not performed: 17% (13%)
Unit testing is informal: 40% (46%)
Unit tests cases are documented: 9% (11%)
Unit tests cases and their executions are documented: 14% (16%)
We use a Test Driven Development approach: 20% (14%)

Participants: 384 (2006: 460)
Ending date: October 2008 (February 2006)
Source: Methods & Tools (http://www.methodsandtools.com/)

TDD 접근법을 사용하는 것은 20%로 증가한 것에 비해 단위테스트에 대한 노력은 오히려 감소했습니다. 그리고 의외인 것은 외국에서도 아직 단위테스트가 보편적이지 않다는 것이었습니다.

오픈소스 프로젝트 하나를 앞서 살펴봤습니다. 여기에는 test라는 테스트케이스를 모아놓은 폴더가 있었습니다. 소스의 양은 얼마나 될까요. httpunit 이라는 단위테스트용 프로젝트이기 때문에 좀 더 많이 있을 거라 예상했습니다.
예상대로 제가 회사에서 만든 테스트코드들과는 비교할 수 없이 많더군요.

요기까지가 패키지 하나에 들어있는 소스 코드들입니다. 이 코드들을 테스트하는 테스트케이스는 다음과 같습니다.
그리 많은 것은 아니지만 대략 1/5 정도 테스트케이스의 클래스들이 있지않나 생각됩니다. 각 테스트케이스 내의 테스트 메소드들이 애플리케이션에 대한 코드 커버리지를 책임지겠지요.

테스트케이스를 모아놓은 것이 테스트스위트입니다. *Suite.java 로 찾아보면 다음과 같은 스위트들이 보입니다.

빌드 스크립트에서도 테스트 관련 배치작업을 찾을 수 있습니다.



test 타겟을 실행해보니 다음과 같은 결과가 나오는군요.
test:
     [java] .........................................
     [java] .........................................
     [java] .........................................
     [java] .........................................
     [java] .........................................
     [java] .........................................
     [java] .........................................
     [java] .........................................
     [java] .........................................
     [java] .....................................F....
     [java] .........................................
     [java] .........................................
     [java] .........................................
     [java] .........................................
     [java] .........................................
     [java] .........................................
     [java] .........................................
     [java] .........................................
     [java] .....................................
     [java] Time: 22.656
     [java] There was 1 failure:
     [java] 1) testCookieAge(com.meterware.httpunit.cookies.CookieTest)junit.framework.AssertionFailedError: cookie2 expiration expected:<1223798608260> but was:<1112124642000>
     [java]  at com.meterware.httpunit.cookies.CookieTest.testCookieAge(CookieTest.java:202)
     ...
     [java]  at com.meterware.httpunit.HttpUnitSuite.main(HttpUnitSuite.java:49)
     [java] FAILURES!!!
     [java] Tests run: 775,  Failures: 1,  Errors: 0
BUILD SUCCESSFUL
Total time: 36 seconds

디버깅을 할 것은 아니지만, 이렇게 테스트케이스를 775가지 이상 갖고 있는 애플리케이션을 관리하는 것은 좀 더 수월하지 않을까 생각됩니다. 작업환경의 차이에서 발생하는 버그도 찾을 수 있고, 코드 변경으로 인한 틀어짐도 놓치지 않기 때문입니다.

읽어주셔서 감사합니다. 알찬 11월 되시길...
Posted by 케누 kenu허광남

댓글을 달아 주세요

  1. coolengineer  댓글주소 수정/삭제 댓글쓰기 2008.11.01 13:01

    http://blog.davebouwman.net/2008/06/04/DeveloperSurveyUnitTestingAmpOtherTools.aspx

    연관글을 따라가다 보니 재밌는 서베이가 있군요..

  2. 정의의소  댓글주소 수정/삭제 댓글쓰기 2008.11.01 13:11

    Test Case가 많은 Coverage를 가질 수록 코드 변경에 대한 자신감이 생기죠.. 최소한 이 Coverage에는 문제가 없다는... 그러나 Unit Test 를 단지 품질적인 측면만 보면 도입이 꺼려지지만 향후 생산성.. 파생되는 과제들(저희 회사의 경우)을 생각하면 나중에 다 많은 위력을 발휘하는 것 같습니다. - Unit Test 예찬론자... ^^:


앞서 오픈소스인 httpunit을 통해서 프로젝트 소스 구성을 살펴봤습니다. 빌드스크립트인 build.xml를 통해서 프로젝트 소스를 가공하는 방법을 알 수 있습니다. 프로젝트의 작업 지시서와 같은 역할을 하는 것이죠.

이클립스의 아웃라인뷰에 나오는 타겟 목록입니다.
소스를 보면 <project ... default="jar"> 내용을 확인 할 수 있습니다. 기본 프로젝트 타겟은 jar 입니다.

그 외에도 수많은 작업그룹이 보입니다. 각각의 내용을 확인해 봐야 정확한 작업 내용을 알 수 있겠지만 여기서는 jar 를 중심으로 살펴보겠습니다.

<!--  ===================================================================  -->
<!--  Creates the jar archive                                              -->
<!--  ===================================================================  -->
<target name="jar" depends="compile" description="create the jar file">
    <mkdir dir="${lib.dir}" />
    <echo file="${build.dir}/info.txt">Manifest-Version: 1.0
Sealed: false
HttpUnit-Version: ${version}
Build-Date: ${TODAY}
Build-Time: ${TSTAMP}
</echo>
    <jar jarfile="${lib.dir}/${name}.jar" manifest="${build.dir}/info.txt">
        <fileset dir="${build.classes}" includes="com/**"/>
        <fileset dir="META-INF" includes="*.dtd"/>
    </jar>
</target>

주석의 모양도 참고 대상입니다.  타겟의 depends속성을 보면 compile 타겟이 먼저 수행되는 것을 알 수 있습니다. <jar> 태스크를 보면 JAR 파일명이 지정되어 있습니다. 컴파일된 클래스 디렉토리를 기준으로 com 패키지 아래 있는 것이 포함되고, META-INF 디렉토리에 있는 *.dtd 파일들도 jar 파일에 들어갑니다.

compile 타겟을 확인하면 소스의 위치는 확실히 알 수 있겠죠.

<!--  ===================================================================  -->
<!--  Compiles the source code                                             -->
<!--  ===================================================================  -->
<target name="compile-for-java2" depends="prepare,check_for_optional_packages" if="dom3.absent">
    <mkdir dir="${build.classes}" />
    <javac srcdir="src-1.4" destdir="${build.classes}"/>
</target>
<target name="compile" depends="prepare,check_for_optional_packages,compile-for-java2">
    <mkdir dir="${build.classes}" />
    <javac srcdir="${src.dir}" destdir="${build.classes}"
           debug="${debug}" deprecation="${deprecation}" optimize="${optimize}">
        <classpath refid="base.classpath" />
        <exclude name="**/JTidyHTMLParser.java" unless="jtidy.present" />
        <exclude name="**/ScriptFilter.java" unless="nekoHTML.present" />
        <exclude name="**/NekoHTMLParser.java" unless="nekoHTML.present" />
        <exclude name="**/NekoDOMParser.java" unless="nekoHTML.present" />
        <exclude name="**/servletunit/*" unless="jsdk.present" />
        <exclude name="**/JUnitServlet.java" unless="junit.present" />
        <exclude name="**/javascript/*" unless="rhino.present" />
    </javac>
</target>
 
클래스의 빌드 디렉토리를 만든 후에 파일들을 컴파일 합니다. 컴파일 시 관련 jar의 유무에 따라 컴파일에서 제외시키기도 합니다. 여러가지 jar파일들을 사용하는 것을 알 수 있습니다. jtidy, nekoHTML, jsdk, junit, rhino. 대부분 자바스크립트 파서나 실행에 관련된 것들이죠.

httpunit 한 프로젝트에서도 건질 것들이 굉장히 많은 듯 합니다.

Posted by 케누 kenu허광남

댓글을 달아 주세요

[kenu@82s ~]$ ls /web/kenu/okjsp.80port.net/
DSC022.JPG    count.jsp  f.jsp        javaone2004/  lecture/  rss/
WEB-INF/      css/       family/      javaone2006/  letter/   slf/
agent.html    cvs/       favicon.ico  ...
[kenu@82s ~]$ cd okjsp2007/
[kenu@82s okjsp2007]$ pwd
/home/kenu/okjsp2007
[kenu@82s okjsp2007]$ ls
CHANGE.txt  README.txt        build.properties.default  docs/  test/
CVS/        build.properties  build.xml                 src/   web/
[kenu@82s okjsp2007]$ cvs update; ant

cvs 서버에서 서비스되는 서버 폴더에 소스를 보내기 전에 cvs와 sync하는 장소가 필요합니다. 이곳을 sandbox 라고 합니다. 여기에서는 /home/kenu/okjsp2007 경로가 sandbox입니다. cvs update 명령을 통해서 새로운 소스들 가져옵니다. ant 명령으로 build.xml 내용을 실행합니다. 이렇게 하면 sandbox의 내용이 서비스되는 경로( /web/kenu/okjsp.80port.net/ )로 보내지게(publish) 됩니다.

어제 세미나에서 미처 보여드리지 못한 내용이라 추가합니다.
Posted by 케누 kenu허광남

댓글을 달아 주세요

  1. 마르스  댓글주소 수정/삭제 댓글쓰기 2007.09.12 21:28

    토요일날 잘 들었습니다.

    회사 프로젝트가 많아 지다보니 공동작업에 대한 개발환경과 개발표준이 필요해서..
    요즘 이쪽으로 많은 문서랑... 경험을 듣고 있습니다.
    어떤 분은 불편하다고 하는 분들도 있었고...
    하여튼.. 정확한 내용을 듣지 못했죠...

    세미나를 통해서 거의 정확한 감을 잡아서 다행입니다.

    한가지 모르는건... 서비스 서버가 여러대 일때 어떻게 해야하는지
    그때 물어보지 못했네요... ^^..

    한번 삽질해서 구축해봐야겠습니다... 나중에... 도저히 안되면.. help!! 하겠습니다... ^^;;

    p.s. 왜 sandbox 라 부르나요??