2010/12/14 08:30
요구사항
목적
비디오 가게에서 고객이 대여하는 비디오의 대여정보를 조회할 수 있는 프로그램을 작성한다.

요구사항
  1. 고객은 이름을 갖는다.
  2. 고객은 한번에 여러 개의 비디오를 대여할 수 있으나 각각의 대여기간은 다를 수 있다.
  3. 비디오는 영화, 스포츠, 다큐먼터리의 세 종류가 있다.
  4. 각 비디오는 독립적인 일일 대여요금을 갖는다.
  5. 영화는 대여기간이 2일 이상되면 3일째부터는 대여요금이 1/2로 할인된다.
  6. 다큐먼터리는 3일 이상 대여하면 4일째부터 1/3로 할인된다.
  7. 스포츠는 장기대여 할인이 없다.
  8. 비디오 1개 대여할 때마다 보너스 포인트는 1포인트씩 올라간다. 단, 스포츠는 2포인트씩 올라간다.
  9. 과거의 대여기록을 보유하고 있을 필요는 없으나 고객이 얻은 총 보너스 포인트 정보는 알고 있어야 한다.
  10. 고객의 현재 대여정보를 구할 수 있는 기능을 작성하라.
    총 대여비디오 수
    대여정보: 비디오(종류 + 제목 + 가격), 대여기간 리스트
    총 대여가격
    현재 대여하고 있는 비디오로 인해 추가된 포인트

요구사항 정련
  • 고객은 한 번에 여러 개의 비디오를 대여할 수 있으나 각 대여기간은 다를 수 있다.
    * 업무 규칙 *
    - 고객은 한 번에 여러 개의 비디로를 대여 할수 있다.
    - 대여기간은 비디오 마다 각각 다를 수 있다.
  • 비디오는 영화, 스포츠, 다큐먼터리의 세 종류가 있다.
    * 업무 규칙 *
    - 비디오에는 종류가 있다.
    - 현재 비디오의 종류는 영화, 스포츠, 다큐먼터리의 세 종류다.
  • 영화는 대여기간이 2일 이상 되면 3일째부터는 대여요금이 1/2로 할인된다.
    * 업무 규칙 *
    - 영화는 대여기간이 n일 이상되면 m일째부터 대여요금이 p로 할인된다.

요구사항 정련 결과
* 업무규칙 *
  1. 고객은 이름을 갖는다.
  2. 고객은 한 번에 여러 개의 비디오를 대여할 수 있다.
  3. 대여기간은 비디오마다 각각 다를 수 있따.
  4. 비디오에는 종류가 있다.
  5. 현재 비디오의 종류는 영화, 스포츠, 다큐먼터리의 세 종류다.
  6. 각 비디오는 독립적인 일일  대여요금을 갖는다.
  7. 영화는 대여기간이 2일 이상 되면 3일째부터는 대여요금이 1/2로 할인된다.
    예: 영화는 대여기간이 n일 이상이 되면 m일째부터 대여요금이 p로 할이된다.
  8. 다큐먼터리는 3일 이상 대여하면 4일째부터는 1/3로 할인된다.
    예: 어떤 비디오의 타입은 n일 이상 대여하면 m일째부터 p로 할인된다.
  9. 스포츠는 장기대여 할인이 없다.
    예: 어떤 비디오 타임은 장기대여 할인이 없다.
  10. 비디오 1개 대여할 때마다 보너스 포인트 1포인트씩 누적된다. (단, 스포츠는 2포인트씩)>
    예: 고객의 보너스 포인트 누적점수는 비디오를 n개 대여할 때마다 보너스 포인트 m포인트씩 누적된다.(단, 특정 타입은 p포인트씩).
  11. 시스템은 고객의 과거의 대여기록을 보유하고 있을 필요 없다.

* 고객과 협의해 확정해야 하는 업무규칙 *

  • 대여는 일 단위다.
  • 포인트는 정수다.
  • 할인은 분수 비율이다.

* 기능 요구사항 *

  1. 고객은 비디오를 여야할 수 있다.
  2. 시스템은 고객의 현재 대여정보를 제공할 수 있다.
    대여정보
    - 총 비디오 대여수
    - 비디오(종류 + 제목 + 가격), 대여기간 리스트
    - 총 대여가격
    - 현재 대여하고 있는 비디오로 인해 추가된 포인트
  3. 시스템은 현 대여로 인해 발생하는 포인트 총합을 계산할 수 있다.
  4. 시스템은 대여된 비디오들의 총 대여가격을 계산할 수 있다.
  5. 시스템은 총 대여비디오 수를 계산할 수 있다.

* 기타 요구사항 확인 작업 *
  • 과거의 대여기록을 보유하고 있을 필요는 없으나 고객이 얻은 총 보너스 포인트 정보는 알고 있어야 한다. ▶ 포인트 정보의 기록을 의미하는 건지, 개별 포인트만의 관리가 아닌 대여 반납의 포인트 합산인지를 확인한다.



행위 기반 클래스 도출
대여한다 (고객이 비디오를)
할인된다 (비디오 일일 대여각격이)
누적된다 (보너스 포인트가)
계산한다 (시스템이 포인트 총합을)
계산한다 (시스템이 총 대여가격을)
계산한다 (시스템이 총 대여비디오 수를)
제공한다 (시스템이 대여 정보를)

OOP에서 객체에 수동 액션을 담는 일은 좀처럼 없다. (버스가 운전을 당한다? 설마~). 그런데 요구사항으로부터 액션(행동)을 도출하고 보면 본의 아니게 수동이 쓰이는 경우가 있다. 만ㅇ리 수동이 쓰인 상태로 구현을 하게 되면 타 모듈에 대한 의존성이 높아져서 설계가 전체적으로 복잡해 진다. 다음 예를 보자
할인된다 (비디오 일일 대여가격이)
누적된다 (보너스 포인트가)

위 두 가지 액션을 하는 행위를 능동형으로 바꿔보자. 바꾸다 보면, 행위의 주체가 시스템이라는 걸 자연스럽게 알 수 있다.
할인한다 (시스템이 비디오 일일 대여가격을)
누적한다 (시스템이 포인트를)


소유기반 클래스 도출
이름을 갖는다 (각 고객은)
종류를 갖는다 (각 비디오는)
대여요금을 갖는다 (각 비디오는)
포인트를 갖는다 ( 각 비디오)
대여일수를 갖는다 (비디오가? 고객이?)

고객에서 비디오 타입까지
 - 행위 기반 클래스
대여한다 (고객이 비디오를)
할인한다 (시스템이 비디오 일일 대여가격을)
누적한다 (시스템이 포인트를)
계산한다 (시스템이 포인트 총합을)
계산한다 (시스템이 총 대여가격을)
계산한다 (시스템이 총 대여비디오 수를)|
제공한다 (시스템이 대여정보를)

비디오샵과 고객의 관계
- 소유기반 클래스(엔티티 클래스)
이름을 갖는다 (각 고객은)
종류를 갖는다 (각 비디오는)
대여요금을 갖는다 (각 비디오는)
포인트를 갖는다 (각 비디오 타입은)
대여일수를 갖는다 (각 대여는)

'IT > TDD' 카테고리의 다른 글

OOP 객체 액션  (0) 2010/12/14
TDD 우분투에서 phpunit 설치  (0) 2010/12/08
TDD jUnit4 비교표현확장: Hamcrest  (0) 2010/12/07
TDD jUnit4 특징  (0) 2010/12/06
TDD 실습 - 은행계좌(Account) 클래스 만들기  (0) 2010/12/03
TDD 개발 진행방식  (0) 2010/12/02
Posted by 푸른_바람
TAG OOP, 객체, 액션
참고

[code bash]
sudo apt-get install phpunit
패키지 목록을 읽는 중입니다... 완료 의존성 트리를 만드는 중입니다 상태 정보를 읽는 중입니다... 완료 다음 패키지를 더 설치할 것입니다: php-benchmark 제안하는 패키지: phpunit-doc 다음 새 패키지를 설치할 것입니다: php-benchmark phpunit 0개 업그레이드, 2개 새로 설치, 0개 지우기 및 0개 업그레이드 안 함. 323k바이트 아카이브를 받아야 합니다. 이 작업 후 4,485k바이트의 디스크 공간을 더 사용하게 됩니다. 계속 하시겠습니까 [Y/n]? y 받기:1 http://ftp.daum.net/ubuntu/ lucid/universe php-benchmark 1.2.7-4 [13.5kB] 받기:2 http://ftp.daum.net/ubuntu/ lucid/universe phpunit 3.4.5-1 [310kB] 내려받기 323k바이트, 소요시간 3초 (103k바이트/초) 전에 선택하지 않은 php-benchmark 패키지를 선택합니다. (데이터베이스 읽는중 ...현재 318741개의 파일과 디렉토리가 설치되어 있습니다.) php-benchmark 패키지를 푸는 중입니다 (.../php-benchmark_1.2.7-4_all.deb에서) ... 전에 선택하지 않은 phpunit 패키지를 선택합니다. phpunit 패키지를 푸는 중입니다 (.../phpunit_3.4.5-1_all.deb에서) ... man-db에 대한 트리거를 처리하는 중입니다 ... php-benchmark (1.2.7-4) 설정하는 중입니다 ... phpunit (3.4.5-1) 설정하는 중입니다 ... [/code]

아래 위치에서 2개의 파일을 다운로드 합니다.

받기:1 http://ftp.daum.net/ubuntu/ lucid/universe php-benchmark 1.2.7-4 [13.5kB]
받기:2 http://ftp.daum.net/ubuntu/ lucid/universe phpunit 3.4.5-1 [310kB]

실행파일 설치 위치는 /usr/bin/phpunit
[code php]
if (strpos('@php_bin@', '@php_bin') === 0) { set_include_path(dirname(__FILE__) . PATH_SEPARATOR . get_include_path()); } require_once 'PHPUnit/Util/Filter.php'; PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); require 'PHPUnit/TextUI/Command.php'; define('PHPUnit_MAIN_METHOD', 'PHPUnit_TextUI_Command::main'); PHPUnit_TextUI_Command::main();
[/code]
lib 설치 위치는 /usr/share/php/PHPUnit/

2010.12.01
http://www.phpunit.de/
최신 3.6 매뉴얼

phpunit.de 에서 제공하는 설치 방법
[code bash]
pear install phpunit/PHPUnit [/code]
설치 위치 /usr/lib/php/PHPUnit.

 Download a release archive from http://pear.phpunit.de/get/ and extract it to a directory that is listed in the include_path of your php.ini configuration file.

(http://pear.phpunit.de/get/ 에서 다운로드 하고, php.ini 설정파에서 include_path 에 있는 디렉토리에 압축을 풉니다.)

Prepare the phpunit script:
(phpunit 스크립트를 준비합니다.)


Rename the phpunit.php script to phpunit.
(phpunit.php 스크립트 phpunit 이름을 수정합니다.)


Replace the @php_bin@ string in it with the path to your PHP command-line interpreter (usually /usr/bin/php).
(@php_bin@ 문자열을 인터프리터의 경로와 파일명으로 교체하세요. (보통 /usr/bin/php))


Copy it to a directory that is in your path and make it executable (chmod +x phpunit).

(당신의 경로에 복사하거나 만들어서 실행하세요. (chmod +x phpunit))

Prepare the PHPUnit/Util/PHP.php script:
(PHPUnit/Util/PHP.php 스크립트를 준비하세요.)


Replace the @php_bin@ string in it with the path to your PHP command-line interpreter (usually /usr/bin/php).
(@php_bin@ 문자열을 인터프리터의 경로와 파일명으로 교체하세요. (보통 /usr/bin/php))


뭔 말인지... ㅡ.ㅡ

 


'IT > TDD' 카테고리의 다른 글

OOP 객체 액션  (0) 2010/12/14
TDD 우분투에서 phpunit 설치  (0) 2010/12/08
TDD jUnit4 비교표현확장: Hamcrest  (0) 2010/12/07
TDD jUnit4 특징  (0) 2010/12/06
TDD 실습 - 은행계좌(Account) 클래스 만들기  (0) 2010/12/03
TDD 개발 진행방식  (0) 2010/12/02
Posted by 푸른_바람
Hamcrest : 비교표현확장
JUnit 4.7, 4.8 기본 탑재되어 있는 Hamcrest 버전은 1.1 core 입니다.

Hamcrest(햄크레스트)는 jMock이라는 Mock 라이브러리 저자들이 참여해 만들고 있는Matcher 라이브러리입니다.
테스트 표현식을 작성할 때 좀 더 문맥적으로 자연스럽고, 우아한 문장을 만들 수 있게 도와줍니다.
개발자만이 읽을 수 있는 프로그램밍 언어라라는 느낌보다 좀 더 문장체에 가까운 느낌으로 넓은 범주의 사람들이 함께 이해할 수 있는 형태로 만들어줍니다.

현재 Hamcrest는 Java 이외에도 C++, Objective-C, Phthon 그리고 PHP 버전으로도 포팅되어 있습니다.
Matcher 라이브러리: 필터나 검색등을 위해 값을 비교할 때 좀 더 편리하게 시용할 수 있게 도와주는 라이브러리입니다.

Hamcrest 라이브러리는 기본적으로 assertEquals 대신에 assertThat이라는 구분사용을 권장한다.
공학적인 느낌을 주는 딱딱한 assertEquals 보다는 assertThat이 좀 더 문맥적인 흐르을 만들어준다고 여기기 때문입니다. ( 영어라서 이해를 못하겠습니다. ㅜ.ㅜ)
[code java]
asertEquals("YoungJim", customer.getName() );
assertThat( customer.getName(), is("YoungJim") );

// 적용 전
assertEquals(100, account.getBalance());
// 적용 후
aseertThat(account.getBalance(), is(equalTo(10000)));


// 적용 전
assertNotNull(resorce.newConnection());
// 적용 후
assertThat(resource.newConection(), is(notNullValue());

// 적용 전
assertTrue(account.getBalance() > 0);
// 적용 후
assertThat(account.getBalance(), isGreaterThan(0));

// 적용 전
assertTrue(user.getloginName().indexOf("Guest") > -1);
// 적용 후
asertThat(user.getLoginName(), containsString("Guest"));
[/code][code java]
import static org.junit.Assert.*; import static org.hamcrest.CoreMatchers.*; import org.junit.Test; public class HamcrestTest{ @Test public void testArray() throws Exception { assertThat("Start Date 비교", "2010/02/03", is("2010/02/04")); } } [/code]

패키지설명
org.hamcrest.core 오브젝트나 값들에 대한 기본적인 Matcher들
org.hamcrest.beans Java 빈(Bean)과 그 값 비교에 사용되는 Matcher들
org.hamcrest.coolection 배열과 컬렉션 Matcher들
org.hamcrest.number 수 비교를 하기 위한 Matcher들
org.hamcrest.object 오브젝트와 클래스들 비교하는 Matcher들
org.hamcrest.test문자열 비교
org.hamcrest.xmlXML 문서 비교

  • 코어(Core)
    메소드설명클래스 명
     anything어떤 오브젝트가 사용되든 일치한다고 판별한다. IsAnything
     describedAs테스트 실패 시에 보여줄 추가적인 메시지를 만들어주는 메시지 테코레이터 DescribedAs
     equalTo두 오브텍트가 동일한지 판별한다.IsEqual
     is내부적으로 equalTo와 동일하다.
    가독성 증진용.
    아래 세문장은 의미가 동일하다.
    [code java]assertThat(entity, equalTo(expectedEntity));
    assertThat(entity, is(equalTo(expectedEntity)));
    assertThat(entity, is(expectedEntity));
    [/code]
    Is

  • 오브젝트(Object)
    메소드설명클래스 명
     hasToStringtoString 메소드 값과 일치 여부를 판별한다. HasToString
     instanceOf
     typeCompatibleWith
    동일 인스턴스인지 타입비교(instance of).
    동일하거나 상위 클래스, 인터페이스인지 판별
    IsInstanceOf
    IsCompatibleType
     notNullValue
     nullValue
    Null인지, 아닌지 판별 IsNull
     sameInstanceObject가 완전히 동일한지 비교.
    equals 비교가 아닌 ==(주소비교)로 비교하는 것과 동일
    isSame

  • 논리(Logical)
    메소드설명클래스 명
     allOf비교하는 두 오브젝트가 각각 여러 개의 다른 오브젝트를 포함하고 있을 경우에, 이를테면 collection 같은 오브젝트일 경우 서로 동일한지 판별한다. Java의 숏서킷(&& 비교)과 마찬가지로 한 부분이라도 다른 부분이 나오면 그 순간 false를 돌려준다. AllOf
     anyOfallOf와 비슷하나 anyOf는 하나라도 일치하는 것이 나오면 true로 판단한다.
    Java의 숏서킷(||)과 마찬가지로 한 번이라도 일치하면 true를 돌려준다.
    AnyOf
     not서로 같지 않아야 한다. IsNot

  • 빈즈(Beans)
    메소드설명클래스 명
     hasPropertyJava 빈즈 프로퍼티 테스트 HasProperty

  • 컬렉션(Collection)
    메소드설명클래스 명
     array두 배열 내의 요소가 모두 일치하는지 판별 IsArray
     hasEntry, hasKey, hasValue맴(Map)요소에 대한 포함 여부 판단 isMapContaining
     hasItem, hasItems특정 요소들을 포함하고 있는지 여부 판단 IsCollectionContaining
     hasItemInArray배열 내에 찾는 대상이 들어 있는지 여부를 판별 IsArrayContaining

  • 숫자(Number)
    메소드설명클래스 명
     closeTo부동소수점(floating point) 값에 대한 근사값 내 일치 여부, 값(value)과 오차(delta)를 인자로 갖는다. IsCloseTo
     greaterThan
     greaterThanOrEqualTo
    값 비교. >, >= OrderingComparison
     lessThan
     lessThanOrEqualTo
    값 비교. <, <= OrderingComparison

  • 텍스트(Text)
    메소드설명클래스 명
     containsString문자열이 포함되어 있는지 여부 StringContains
     startsWith특정 문자열로 시작 StringStartsWith
     endsWith특정 문자열로 종료 StringEndsWith
     equalToIgnoringCase대소문자 구분하지 않고 문자비교 IsEqualIgnoringCase
     equalToIgnoringWithSpace문자열 사이의 공백 여부를 구분하지 않고 비교 IsEqualIgnoringWhiteSpace


'IT > TDD' 카테고리의 다른 글

OOP 객체 액션  (0) 2010/12/14
TDD 우분투에서 phpunit 설치  (0) 2010/12/08
TDD jUnit4 비교표현확장: Hamcrest  (0) 2010/12/07
TDD jUnit4 특징  (0) 2010/12/06
TDD 실습 - 은행계좌(Account) 클래스 만들기  (0) 2010/12/03
TDD 개발 진행방식  (0) 2010/12/02
Posted by 푸른_바람
2010/12/06 08:30

  • @Test
    jUnit3 이전에는 메소드 이름을 test로 시작해야한다는 규칙이 있었지만 jUnit4 이 후에는 @Test 애노테이션만 붙이면 테스트 메소드로 인식됩니다.

  • @BeforeClass @AfterClass
  • @Before @After
  • 예외 테스트
    테스트 메소드내에서 해당 예외가 발생하지 않는다면 테스트 메소드를 실패로 간주합니다.

    [code java]
    // jUnit3
    public void testException(){ String value = "a103"; try{ System.out.println(Integer.parseInt(value)); assertTrue(false); } catch ( NumberFormatException nfe){ assertTrue(true); } }[/code]
    [code java]
    // jUnit4
    @Test (expected=NumberFormatException.class) public void testException(){ String value = "a108"; System.out.println(Integer.parseInt(value)); } [/code]

  • 테스트 시간제한
    밀리초 단위의 시간을 정해준 후 해당 시간 내에 메소드가 소행왈뇨되지 않으면 실패한 테스트로 간주합니다.

    [code java]
    @Test (timeout=500) pulbic void testPingback() throws Exception{ ciServer.sendNotimail(); assertEquals(NOTIFICATED, ciServer.getState()); } [/code]

  • 테스트 무시
    @Ignore가 붙은 메소드는 해동 애노테이션을 지우기 전까지 수행하지 않습니다.

    [code java]
    @Ignore @Test public void testTerminal() throws Exception { assertTrue(term.isLogin()); System.out.println("=== logon test"); } [/code]

  • 배열지원
    배열 원소의 자리 순서 기준으로 equals 비료가 이뤄지기 때문에 배열 안의 집합은 동일하더라도 순서가 다르면 테스트가 실패합니다.

    [code java]
    @Test public void testArrayAssertEquals() throws Exception { String [] names = {"Tom", "JIMMY", "JOHIN"}; String[] anotherNames = {"Tom" "JOHIN", "JIMMY"}; assertArrayEquals(names, anotherNames); } [/code]

  • @RunWith
    테스트 케이스를 이클립스에서 실행하면 내부적으로는 jUnit의 BlockJUnit4ClassRunner라는 테스트 러너 클래스가 실행되고, 이클립스는 그 결과를 해석해서 보여줍니다.
    @RunWith 애노테이션은 JUnit에 내장된 기본 테스트 러너인 BlcokJUnit4ClassRunner 대신에 $RunWith로 지정된 클래스를 이용햐ㅐ 클래스 내의 테스트 메소드들을 수행하도록 지정해주는 애노테이션입니다.
    일종의 JUnit 프레임워크의 확장지점 입니다.

  • @SuiteClasses
    JUnit3에서의 static Test Suite() 메소드와 동일한 일을 수행한다.

    [code java]
    // jUnit3
    public class ABCSuite extends TestCase { public static Test(){ TestSuite suite = new TestSuite(); suite.addTestSuite(ATest.class); suite.addTestSuite(BTest.class); suite.addTestSuite(CTest.class); } } [/code]
    [code java]
    // jUnit4
    @RunWith(Suite.class) @SuiteClasses(ATest.calss, BTest.class, CTest.class) public class ABCSuite { } [/code]


  • 파라미터화된 테스트 (Parameterized Test)
    하나의 메소드에 대해 다양한 테스트 값을 한꺼번에 실행하고자 할 때 사용한다.


  • 룰(Rule)
    JUnit 4.7 버전부터 추가된 기능으로 하나의 테스트 클래스 내에서 가 테스트 메소드의 동작 방식을 재정의 하거나 추가하기 위해 사용하는 기능입니다.

     규칙이름설명
    TemporaryFolder (임시폴더) 테스트 메소드내에서만 사용가능한 임시 폴더나 파일을 만들어준다.
    ExternalResorce (외부자원) 외부 자원을 명시적으로 초기화 한다.
    ErrorCollector (에러수집기) 테스트 실패에도 테스트를 중단하지 않고 진행할 수 있게 도와준다.
    Verifier (검증자) 테스트 케이스와는 별개의 조건을 만들어서 확인할 때 사용한다.
    TestWatchman (테스트 감시자) 테스트 실행 중간에 사용자가 끼어들 수 있게 도와준다.
    TestName ( 테스트 이름) 테스트 메소드 이름을 알려준다.
    Timeout (타임아웃) 일괄적인 타임아웃을 설정한다.
    ExpectedException (예상된 예외) 테스트 케이스 내에서 예외와 예외 메시지를 직접 활인할 때 사용한다.

  • 이론(Theory)
    테스트 데이터와 상관없이 작성 대상 메소드를 항상 유지해야 하는 논리적인 규칙을 표현 할 때 사용합니다. 실험적인 성격의 기능입니다.

    [code java]
    @RunWith public class SquareRootTheoryTest{ @DataPoint public static double FOUR = 4.0; @DataPoint public static double ZERO = 3.0; @Theory public void defineOfSquareRoot(double n){ assertEquals(n, sqrRoot(n)*sqrRoot(n), 0.01); assertTrue( sqrRoot(n) >= 0); } // 정수 n은 √n*√n과 같다는 이론을 정의 } [/code]

'IT > TDD' 카테고리의 다른 글

OOP 객체 액션  (0) 2010/12/14
TDD 우분투에서 phpunit 설치  (0) 2010/12/08
TDD jUnit4 비교표현확장: Hamcrest  (0) 2010/12/07
TDD jUnit4 특징  (0) 2010/12/06
TDD 실습 - 은행계좌(Account) 클래스 만들기  (0) 2010/12/03
TDD 개발 진행방식  (0) 2010/12/02
Posted by 푸른_바람
은행계좌 클래스
* 첫번째 질문
  • 구현해야 할 기능을 파악하고, 목록을 작성한다.
  • 계좌 생성 기능을 구현하기 위한 최초의 테스트 케이스를 만들고 실패하는 모습을 확인한다.

작성하고자 하는 메소드나 기능이 무엇인지 선별하고, 작성 완료 조건을 정해서 실패하는 케이스를 작성하는것.

클래스 설계서와 같은 산출물이 있는 경우라면, 크게 고민할 것 없이 메소드 외양부터 만들기 시작.
이때 리턴 타입은 기본 초기값(null, 0 등) 위주로 설정해놓으면 편한다. 이런 방식을 클래스 스켈레톤(skeleton) 구현이라고 부른다.

업무전문가나 설계자로부터 넘겨받은 산출물이 없다면 개발에 필요한 내용을 개발자가 스스로 머릿속에서 떠올려야 한다.
이 예제에서는 설계문서 없이 곧바로 개발한다. 라고 가정.


* 기능요구사항 & 유의사항
ToDo
  • 클래스 이름 Account
  • 기능은 세가지
    • 잔고조회
    • 임금
    • 출금

    * 금액은 원 단위로 (예 : 천 원 = 1000)

테스트 케이스 작성 접근방식
  1. 구현 대상 클래스의 외형에 해당하는 메소들을 먼저 만들고 테스트 케이스를 일괄적으로 만드는 방식
  2. 테스트 케이스를 하나씩 추가해나가면서 구현 클래스를 점진적으로 만드는 방식

대부분의 TDD 책에서는 2번을 권장한다. 첫 번째 방식을 사용했을 경우에는, 모든 테스트가 정상 통과하는 올 그린(All Green) 상태에 이르기까지 긴 시간이 걸릴 수 있다. 그로 인해 TDD의 몇 가지 장점을 잃을 우려가 있기 때문에 초보자에게는 권하지 않는다.

* 첫 번째 응답: 계좌 생성 메소드 구현
  • 계좌 생성 테스트 케이스를 통과하는 코드를 작성한다.

[code java]
package test; import main.Account; /** * 계좌 테스트 클래스 * @author uncaose * */ public class AccountTest { /** * 계좌생성 테스트 * @throws Exception */ public void testAccount() throws Exception{ Account account = new Account(); if( account == null){ throw new Exception("계좌생성 실패"); } } /** * 테스트 실행 */ public static void main(String[] args){ AccountTest test = new AccountTest(); try { //테스트 케이스 실행 test.testAccount(); } catch (Exception e) { e.printStackTrace(); } System.out.println("성공"); } }[/code]
[code java]
package main; public class Account { }[/code]

최대한 빨리 실패하기
TDD에서는 테스트 자동화를 통해 개발이 시작된 시점부터 완료될 때까지 가능한 한 빠른 시점 내에 그리고 자주 실패를 경험하도록 유도하고 있다. 심지어는 개발이 시작되기도 전에 실패가 발생하는 상황부터 보고 시작하라고 하니 말 다했다. 그런데 이런 방식은 사실 일반적인 문제해결 방식과는 조금 다르다. 보토은 작업의 중관 과정에서조차도 실패를 하지 않기 위해 최대한 노력하는 경우가 더 많다. 하지만 TDD는 실패를 통해 배움을 늘겨가는 법이다. OK 조건을 사전에 정해두고 빠르게 실패를 경험하며, 그 조건을 등대로 삼아 실패 상황을 최대한 빠리 극복하고자 노력한다. 성공한 항목과 실패한 항목이 명확하고, 작업해야 하는 부분이 확실하다. 성공에 필요한 조건을 만들고, 실패하는 조건 항목을 성공시킨다. 그래서 빨리 실패하면 실패할수록 좀 더 성공에 가까워지는 묘한 개발 방식이다.


* 최초의 정재
  • 리팩토링을 적용할 부분이 있는지 찾아본다.
  • ToDo 목록에서 완료된 부분을 지운다.
  • 소스의 가독성이 적절한가?
  • 중복된 코드는 없는가?
  • 이름이 잘못 부여된 메소드나 변수명은 없는가?
  • 구조의 개선이 필요한 부분은 없는가?

테스트 케이스 추가
[code java]
public static void main(String[] args){ AccountTest test = new AccountTest(); try { test.testAccount(); // 계좌 생성 test.testGetBalance(); // 잔고 조회 } catch (Exception e) { e.printStackTrace(); } System.out.println("성공"); }[/code]
ToDo
  • 클래스 이름 Account
  • 기능은 세가지
    • 잔고조회
    • 임금
    • 출금

    * 금액은 원 단위로 (예 : 천 원 = 1000)


올 그린(All Green) : TDD에서는 모든 테스트 케이스가 통과하면 녹색 막대가 표시된다. 테스트 케이스를 기준으로 소스코드가 모든 테스트를 정상통과해, 현재 시스템이 건강하다고 판단하는 상태를 흔히 올 그린 상태라고 표현한다.

'IT > TDD' 카테고리의 다른 글

OOP 객체 액션  (0) 2010/12/14
TDD 우분투에서 phpunit 설치  (0) 2010/12/08
TDD jUnit4 비교표현확장: Hamcrest  (0) 2010/12/07
TDD jUnit4 특징  (0) 2010/12/06
TDD 실습 - 은행계좌(Account) 클래스 만들기  (0) 2010/12/03
TDD 개발 진행방식  (0) 2010/12/02
Posted by 푸른_바람
2010/12/02 08:30
  • 질문(Ask) : 테스트 작성을 통해 시스템에 질문한다. (테스트 수행 결과는 실패)
  • 응답(Respond) : 테스트를 통과하는 코드를 작성해서 질무에 대답한다.(테스트 성공)
  • 정제(Refine) : 아이디어를 통합하고, 불필요한 것을 제거하고, 모호한 것은 명확히 해서 대답을 정제한다. (리펙토링)
  • 반복(Repeat) : 다음 질문을 통해 대화를 계속 진행한다.

TDD를 이용한 개발은 크게 '질문 > 응답 > 정제'라는 세 단계가 반복적으로 이루어진다.


'IT > TDD' 카테고리의 다른 글

OOP 객체 액션  (0) 2010/12/14
TDD 우분투에서 phpunit 설치  (0) 2010/12/08
TDD jUnit4 비교표현확장: Hamcrest  (0) 2010/12/07
TDD jUnit4 특징  (0) 2010/12/06
TDD 실습 - 은행계좌(Account) 클래스 만들기  (0) 2010/12/03
TDD 개발 진행방식  (0) 2010/12/02
Posted by 푸른_바람
이전버튼 1 이전버튼