PHPUnitManual:1
- 제 1 장 자동 테스트
자동 테스트
아무리 뛰어난 프로그래머라도 실수를 합니다. 뛰어난 프로그래머와 그렇지 않은 프로그래머의 차이는, 뛰어난 프로그래머는 테스트를 통해 실수를 가능한 빠르게 발견한다는 점입니다. 빠른 단계에서 테스트를 할 수록 실수를 발견하기 쉽고, 또한 수정하기도 쉽습니다. 공개 직전까지 테스트를 미루는 것이 매우 안 좋은 것은 이 때문으로, 모든 에러를 발견할 수 없게 되며, 발견한 에러를 수정하는 것도 매우 어려워집니다. 결국엔 우선순위를 정해 수정할 에러를 선택해야만 하게 됩니다. 이는 모든 에러를 완전히 수정할 수 없기 때문입니다.
PHPUnit 을 사용한 테스트 자체는, 당신이 지금까지 해 온 것과 같은 것입니다. 단지 방법이 다를 뿐입니다. 이 차이는 단순테스트 (testing) 와 종합테스트 (performing a battery of tests)의 차이로, 단순테스트는 프로그램이 예상대로 동작하는가를 확인하는 것이고, 종합테스트는 실행 가능한 일련의 소스코드를 통해 소프트웨어의 각 부분 (unit) 을 자동적으로 테스트하는 것입니다. 실행 가능한 일련의 소스코드를 unit test 라고 부릅니다.
이 장에서는 단순한 print 베이스의 테스트 코드를 완전한 자동 테스트를 만들 것입니다. 우리가 PHP 의 array 를 테스트하도록 부탁받았다고 해 봅시다. 이 오브젝트의 기능 중 하나로, 함수 count() 가 존재합니다. 새롭게 만들어진 배열의 경우, count() 함수의 반환값은 0 이 될 것입니다. 그리고 요소가 하나 추가된 뒤에 count() 는 1 을 반환하게 될 것입니다. 테스트 할 내용은 Example 1.1 배열 조작 테스트 와 같습니다.
Example 1.1 배열 조작 테스트
<?php
$fixture = array();
// $fixture is expected to be empty.
$fixture[] = 'element';
// $fixture is expected to contain one element.
?>
결과가 예상과 같은지 아닌지를 확인하는 가장 단순한 방법은, 요소를 추가하기 전후에 count() 의 결과를 출력하는 것입니다 (예 1.2 print 를 사용한 배열 조작 테스트 를 참조). 각각의 결과가 0 과 1 이 된다면 array 와 count() 가 예상대로 동작하고 있다는 것이 확인됩니다.
Example 1.2 print 를 사용한 배열 조작 테스트
<?php
$fixture = array();
print count($fixture) . "\n";
$fixture[] = 'element';
print count($fixture) . "\n";
?>
0
1
위의 테스트에서는 성공인지 아닌지의 판단을 (출력 결과를 보고) 수동으로 해야 합니다. 이번엔 이 판단을 자동화시켜 봅시다. 예 1.3 예상치와 실제 결과값을 비교하는 배열 조작 테스트 에서는 예상되는 결과와 실행의 결과를 비교하여, 두 개의 값이 동일한 경우 ok 라고 표시합니다. 만약 not ok 라고 표시된다면 어딘가에 문제가 있다는 것을 알 수 있습니다.
Example 1.3 예상치와 실제 결과값을 비교하는 배열 조작 테스트
<?php
$fixture = array();
print count($fixture) == 0 ? “ok\n” : “not ok\n”;
$fixture[] = 'element';
print count($fixture) == 0 ? “ok\n” : “not ok\n”;
?>
ok
ok
이번에는 문제가 있는 경우 예외를 발생시키는 함수를 준비하여, 예상값과 실제 결과값을 비교하는 처리를 넣어 봅시다 (예 1.4 검증(assertion) 함수를 사용한 배열 조작 테스트). 이 방법에는 2 가지 이점이 있습니다. 테스트의 코딩이 간단해지는 것과, 문제가 존재할 때만 결과를 출력시킬 수 있다는 점입니다.
Example 1.4 Assertion 함수를 사용한 배열 조작 테스트
<?php
$fixture = array();
assertTure(count($fixture) == 0);
$fixture[] = 'element';
assertTure(count($fixture) == 1);
function assertTrue($condition)
{
if (!$condition){
throw new Exception('Assertion failed.');
}
}
?>
이제 테스트는 완전하게 자동화되었습니다. 처음 버젼에서는 단순하게 테스트할 뿐이었지만, 마지막 버젼에서는 자동 테스트가 되어 있습니다.
자동 테스트를 하는 목적은 실수를 줄이는 것입니다. 아무리 뛰어난 테스트를 수행한다고 해도 당신의 코드가 완벽해지지는 않지만, 자동 테스트를 시작하는 것은 문제의 발생을 극적으로 줄일 것입니다. 자동 테스트를 통해 당신의 코드는 높은 신뢰성을 획득하고 대담한
설계 변경 (refactoring) 을 하거나 팀메이트와의 작업을 보다 원활하게 하거나 (Cross-Team Test), 출근할 때보다 퇴근할 때의 코드가 개선되었다는 것을 확신할 수 있는 등의 효과가 있습니다.