PHPUnitManual:13
Revision as of 08:54, 4 July 2013 by Onionmixer (talk | contribs) (PHPUnit 13 Behaviour-Driven Development 페이지 추가)
- 제13장 Behaviour-Driven Development
Astels2006 에서 Dave Astels 은 다음과 같이 주장했습니다.
- Extreme Programming[1] 은 고장날 가능성이 있는 모든 것을 테스트한다는 규칙을 가지고 있다.
- 그렇지만 지금의 Extreme Programming 에서의 테스트 기법은 테스트 주도 개발 (Test-Driven Development)[2] (12장 참조) 로 진화하였다.
- 하지만, 각종 툴은 아직도 명세 (specification) 대신에 검증 (assertion) 과 테스트 라는 용어를 쓰도록 강요하고 있다.
- 그렇다면, 테스트가 아니라면 도대체 무엇인가?
- It's about figuring out what you are trying to do before you run off half-cocked to try to do it. You write a specification that nails down a small aspect of behaviour in a concise, unambiguous, and executable form. It's that simple. Does that mean you write tests? No. It means you write specifications of what your code will have to do. It means you specify the behaviour of your code ahead of time. But not far ahead of time. In fact, just before you write the code is best because that's when you have as much information at hand as you will up to that point. Like well done TDD, you work in tiny increments... specifying one small aspect of behaviour at a time, then implementing it.
- 지금부터 무엇을 하고자 하는가를 사전에 확실히 파악하는 것을 통해, 준비가 부족한 상태로 출발하지 않도록 하는 것입니다. 당신이 작성하는 명세는, 어떤 동작의 한 측면을, 간결하고 명확하면서도 실행 가능한 형식으로 표현한 것입니다. 이는 매우 단순한 것입니다. 그게 테스트 아니냐고요? 예, 테스트가 아닙니다. 당신은 "이 코드가 어떻게 동작해야 하는가" 에 관한 사양 (specification) 을 작성하는 것입니다. 실제 코드를 작성하기 전에, 코드의 동작을 정의하는 것입니다. 그렇긴 하지만, 이는 코드를 작성하기 한참 전에 할 일은 아닙니다. 실제로는 코드를 작성하기 직전에 명세를 쓰는 게 좋을 것입니다. 코드를 작성할 때 이용할 정도와 명세를 작성할 때 이용할 정보는 거의 같기 때문입니다. 한 번에 정의하는 동작의 규모는 작게 유지하고, 이 단위 대로 실제 구현해야 합니다.
- When you realize that it's all about specifying behaviour and not writing tests, your point of view shifts. Suddenly the idea of having a Test class for each of your production classes is ridiculously limiting. And the thought of testing each of your methods with its own test method (in a 1-1 relationship) will be laughable.
- 명세를 정의하는 것과 테스트를 작성하는 것의 차이를 이해한다면, 당신의 시점이 변할 것입니다. 기능 클래스 각각에 대한 테스트 클래스를 작성하는 방식이, 매우 답답하게 보일 것입니다. 각각의 메소드 별로 테스트 메소드를 1대1 대응으로 준비하는 방식은 웃기게 보이기까지 할 것입니다.
- --Dave Astels
Behaviour-Driven Development[3] 가 주목하는 것은, 소프트웨어 개발에 사용되는 언어나 상호 작용 (interactions) 입니다.BDD 에서는, 익숙한 개념인 Domain-Driven Design[4] 의 언어를 사용하여 코드의 목적과 유용성을 기술합니다. 이렇게 함으로서, 개발자는 기술적인 세부 사항보다는 "어째서 이 코드를 작성해야 하는가" 를 생각하게 됩니다. 그리고, 코드를 작성할 때 사용해야 할 언어와 Domain 전문가가 사용하는 Domain 언어의 차이를 최소한으로 줄일 수 있습니다.
PHPUnit_Extensions_Story_TestCase 클래스는 BDD 를 위한 도메인 특화 언어 (Domain-Specific Language) 의 정의를 보조하는 스토리 프레임워크를 제공합니다. 이 확장 기능은 다음 명령으로 인스톨할 수 있습니다.
localhost# pear install phpunit/PHPUnit_Story
scenario 안에서, given(), when(), 그리고 then() 은 step 을 표현합니다. and() 는 직전의 step 과 같은 종류의 것을 표현합니다. 다음 메소드는 PHPUnit_Extensions_Story_TestCase 에서 abstract 로 선언되어 있으므로, 구현이 필요합니다.
- runGiven(&$world, $action, $arguments)
... - runWhen(&$world, $action, $arguments)
... - runThen(&$world, $action, $arguments)
...