PHPUnitManual:4.1

From 흡혈양파의 번역工房
Revision as of 10:05, 6 June 2013 by Onionmixer (talk | contribs) (PHPUnit 4.1 테스트의 의존성 페이지 추가)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
4.1 테스트의 의존성

테스트의 의존성

Unit Tests are primarily written as a good practice to help developers identify and fix bugs, to refactor code and to serve as documentation for a unit of software under test. To achieve these benefits, unit tests ideally should cover all the possible paths in a program. One unit test usually covers one specific path in one function or method. However a test method is not necessary an encapsulated, independent entity. Often there are implicit dependencies between test methods, hidden in the implementation scenario of a test.

단위 테스트 (unit test) 를 작성하는 근본적인 목적은, 버그의 발견과 수정, 코드 리팩토링의 용이성, 테스트 대상에 관한 문서 역할이다. 이 목적을 달성하기 위해서는, 단위 테스트가 프로그램 안의 모든 경우의 흐름 (route) 를 커버하는 것이 이상적이다. 하나의 단위 테스트가 커버하는 범위는, 일반적으로 하나의 함수나 메소드 안의 특정 한 흐름이다. 하지만 테스트 메소드는 캡슐화를 통해 독립시켜야만 할 필요는 없다. 복수의 테스트 메소드 간에 암묵적인 의존성이 있어서 드러나지 않은 실동작 시나리오가 테스트 안에 존재하는 것은 흔하다. - Adrian Kuhn et. al.


PHPUnit 에서는 테스트 메소드 간의 의존성을 명시적으로 선언할 수 있습니다. 여기서 말하는 의존성이란, 테스트 메소드가 실행되는 순서를 정의하는 것은 아닙니다. 생산자 (producer) 가 테스트 fixture 를 만들어 fixture 의 인스턴스를 반환 (return) 하고, 이에 의존하는 소비자 (consumer) 가 인스턴스를 받아 이용하는 것입니다.

  • 생산자란, 테스트 대상의 유닛을 생성하여 반환하는 테스트 메소드이다
  • 소비자란, 생산자가 반환값에 의존하는 테스트 메소드입니다.


예제 4.2 @depends 선언을 이용한 의존성의 표현

<?php
class StackTest extends PHPUnit_Framework_TestCase
{
	public function testEmpty()
	{
		$stack = array();
		$this->assertEmpty($stack);
		return $stack;
	}
	/**
	 * @depends testEmpty
	 */
	public function testPush(array $stack)
	{
		array_push($stack, 'foo');
		$this->assertEquals('foo', $stack[count($stack)-1]);
		$this->assertNotEmpty($stack);
		return $stack;
	}
	/**
	 * @depends testPush
	 */
	public function testPop(array $stack)
	{
		$this->assertEquals('foo', array_pop($stack));
		$this->assertEmpty($stack);
	}
}
?>


위 예에서는, 첫번째 테스트인 testEmpty() 에서 새 배열을 만들고, 배열이 비어 있음을 확인합니다. 이 테스트는 fixture 를 반환합니다. 두번째 테스트인 testPush() 는 testEmpty() 에 의존하고 있기에 의존하는 테스트의 결과를 인수로 받습니다. 마지막 testPop() 는 testPush() 에 의존하고 있습니다.


문제 범위를 빠르게 찾기 위해서는, 실패한 테스트를 쉽게 발견하게 하여야 합니다. 이 때문에 PHPUnit 에서는, 하나의 테스트가 실패한 경우, 그 테스트에 의존하는 다른 테스트의 실행을 스킵합니다. 예제 4.3 "테스트의 의존성의 활용" 은 테스트 간의 의존성을 활용하여 문제점을 쉽게 발견하게 되는 예입니다.


예제 4.3 테스트의 의존성의 활용

<?php
class DependencyFailureTest extends PHPUnit_Framework_TestCase
{
	public function testOne()
	{
		$this->assertTrue(FALSE);
	}
	/**
	 * @depends testOne
	 */
	public function testTwo()
	{
	}
}
?>
PHPUnit 3.7.0 by Sebastian Bergmann.
FS
Time: 0 seconds, Memory: 5.00Mb
There was 1 failure:
1) DependencyFailureTest::testOne
Failed asserting that false is true.
/home/sb/DependencyFailureTest.php:6
There was 1 skipped test:
1) DependencyFailureTest::testTwo
This test depends on "DependencyFailureTest::testOne" to pass.
FAILURES!
Tests: 1, Assertions: 1, Failures: 1, Skipped: 1.phpunit --verbose DependencyFailureTest
PHPUnit 3.7.0 by Sebastian Bergmann.
FS
Time: 0 seconds, Memory: 5.00Mb
There was 1 failure:
1) DependencyFailureTest::testOne
Failed asserting that false is true.
/home/sb/DependencyFailureTest.php:6
There was 1 skipped test:
1) DependencyFailureTest::testTwo
This test depends on "DependencyFailureTest::testOne" to pass.
FAILURES!
Tests: 1, Assertions: 1, Failures: 1, Skipped: 1.


하나의 테스트에 복수의 @depends 주석을 달 수도 있습니다. PHPUnit 은 테스트가 실행되는 순서를 변경하지 않기 때문에, 테스트가 실행될 때 확실하게 의존성을 만족시키도록 할 필요가 있습니다.