문제

이 질문은 PHPUnit 사용에만 해당됩니다.

PHPUnit은 PHP 오류를 예외로 자동 변환합니다. PHP 오류를 트리거하는 메소드의 반환 값을 테스트하는 방법이 있습니까 (내장 오류 또는 사용자 생성 오류를 통해 사용자 생성 오류가 발생합니다. trigger_error)?

테스트 할 코드의 예 :

function load_file ($file)
{
    if (! file_exists($file)) {
        trigger_error("file {$file} does not exist", E_USER_WARNING);
        return false;
    }
    return file_get_contents($file);
}

이것은 내가 쓰고 싶은 테스트 유형입니다.

public function testLoadFile ()
{
    $this->assertFalse(load_file('/some/non-existent/file'));
}

내가 겪고있는 문제는 트리거 된 오류로 인해 장치 테스트가 실패한다는 것입니다. 그러나 오류가 발생한 후 실행되지 않은 코드를 잡으려고 시도하거나 예상 예외를 설정하면 메소드의 반환 값을 테스트 할 방법이 없습니다.

이 예제는 작동하지 않습니다.

public function testLoadFile ()
{
    $this->setExpectedException('Exception');
    $result = load_file('/some/non-existent/file');

    // code after this point never gets executed

    $this->assertFalse($result);
}

내가 이것을 어떻게 달성 할 수 있는지 아이디어가 있습니까?

도움이 되었습니까?

해결책

하나의 단위 테스트 내 에서이 작업을 수행 할 방법이 없습니다. 반환 값을 테스트하고 통지를 두 가지 다른 테스트로 분해하면 가능합니다.

PHPUnit의 오류 핸들러는 PHP 오류를 포착하고 통지를 예외로 전환하여 예외로 변환합니다. 이는 정의에 따라 프로그램 실행을 중지합니다. 테스트중인 기능은 전혀 반환되지 않습니다. 그러나 런타임에서도 오류 전환을 예외로 일시적으로 비활성화 할 수 있습니다.

이것은 예를 들면 더 쉬울 것입니다. 따라서 두 테스트가 어떻게 보일지 여기에 있습니다.

public function testLoadFileTriggersErrorWhenFileNotFound()
{
    $this->setExpectedException('PHPUnit_Framework_Error_Warning'); // Or whichever exception it is
    $result = load_file('/some/non-existent/file');

}

public function testLoadFileRetunsFalseWhenFileNotFound()
{
    PHPUnit_Framework_Error_Warning::$enabled = FALSE;
    $result = load_file('/some/non-existent/file');

    $this->assertFalse($result);
}

이것은 또한 테스트를 더 명확하고 깨끗하고 자체 문서화 할 수있는 추가 보너스가 있습니다.

Re : 댓글 :그것은 좋은 질문이며, 나는 몇 가지 테스트를 실행할 때까지 전혀 몰랐습니다. 마치 마치 마치 마치 보입니다 ~ 아니다 적어도 PHPUNIT 3.3.17 (현재 안정적인 릴리스)의 기본/원본 값을 복원하십시오.

그래서 나는 실제로 위의 내용을 그렇게 수정할 것입니다.

public function testLoadFileRetunsFalseWhenFileNotFound()
{
    $warningEnabledOrig = PHPUnit_Framework_Error_Warning::$enabled;
    PHPUnit_Framework_Error_Warning::$enabled = false;

    $result = load_file('/some/non-existent/file');

    $this->assertFalse($result);

    PHPUnit_Framework_Error_Warning::$enabled = $warningEnabledOrig;
}

Re : 두 번째 주석 :

그것은 완전히 사실이 아닙니다. PhPunit의 오류 처리기를보고 있는데 다음과 같이 작동합니다.

  • 그것이 있다면 E_WARNING, 사용 PHPUnit_Framework_Error_Warning 예외 클래스로.
  • 그것이 있다면 E_NOTICE 또는 E_STRICT 오류, 사용 PHPUnit_Framework_Error_Notice
  • 그렇지 않으면 사용하십시오 PHPUnit_Framework_Error 예외 클래스로.

그렇습니다 E_USER_* phpUnit의 *_warning 또는 *_notice 클래스로 바뀌지 않으면 여전히 일반적인 것으로 변형됩니다. PHPUnit_Framework_Error 예외.

더 많은 생각

기능이 어떻게 사용되는지 정확히 의존하지만, 아마도 오류를 트리거하는 대신 실제 예외를 던지기로 전환 할 것입니다. 예, 이것은 메소드의 논리 흐름과 메소드를 사용하는 코드가 변경 될 것입니다 ... 지금 당장 파일을 읽을 수 없을 때 실행이 중지되지 않습니다. 하지만 기존이 아닌 요청 된 파일이 진정으로 특별한 행동. 오류/경고/통지보다 예외를 사용하는 경향이 있습니다. 응용 프로그램 흐름을 처리, 테스트 및 작업하기가 더 쉽기 때문입니다. 나는 보통 감가 상각 방법 통화 등과 같은 것들에 대한 통지를 예약합니다.

다른 팁

a phpunit.xml 구성 파일 및 예외 변환에 대한 통지/경고/오류를 비활성화합니다. 더 매뉴얼의 세부 사항. 기본적으로 다음과 같습니다.

<phpunit convertErrorsToExceptions="false"
         convertNoticesToExceptions="false"
         convertWarningsToExceptions="false">
</phpunit>

일반적인 것을 기대하는 대신 "Exception", 예상되는 것은 어떻습니까"PHPUnit_Framework_Error" ?

이와 같은 일이 할 수 있습니다.

/**
 * @expectedException PHPUnit_Framework_Error
 */
public function testFailingInclude()
{
    include 'not_existing_file.php';
}

나는 또한 다음과 같이 쓰여질 수 있다고 생각합니다.

public function testLoadFile ()
{
    $this->setExpectedException('PHPUnit_Framework_Error');
    $result = load_file('/some/non-existent/file');

    // code after this point never gets executed

    $this->assertFalse($result);
}

더 많은 정보는 참조하십시오 PHP 오류 테스트
특히 (인용) : 다음과 같이 말합니다.

PHPUnit_Framework_Error_Notice 그리고 PHPUnit_Framework_Error_Warning PHP 통지 및 경고를 각각 나타냅니다.


내 시스템에있는 /usr/share/php/phpunit/textui/testrunner.php 파일을보고, 나는 이것을 본다. (라인 198 및 다음) :

if (!$arguments['convertNoticesToExceptions']) {
    PHPUnit_Framework_Error_Notice::$enabled = FALSE;
}

if (!$arguments['convertWarningsToExceptions']) {
    PHPUnit_Framework_Error_Warning::$enabled = FALSE;
}

그렇다면 해당 동작을 활성화하기 위해 일종의 매개 변수를 전달해야할까요? 그러나 기본적으로 활성화 된 것 같습니다 ...

실제로 반환 값과 예외를 모두 테스트하는 방법이 있습니다 (이 경우 PHPUnit에 의해 변환 된 오류).

다음을 수행하면됩니다.

public function testLoadFileTriggersErrorWhenFileNotFound()
{
    $this->assertFalse(@load_file('/some/non-existent/file'));

    $this->setExpectedException('PHPUnit_Framework_Error_Warning'); // Or whichever exception it is
    load_file('/some/non-existent/file');
}

반환 값을 테스트하려면 함수 호출에 오류 억제 연산자를 사용해야합니다 ( @ 함수 이름 앞에서). 이런 식으로 예외는 발생하지 않으며 실행은 계속 될 것입니다. 그런 다음 오류를 테스트하려면 평소와 같이 예상 예외를 설정해야합니다.

할 수없는 것은 단위 테스트 내에서 여러 예외를 테스트하는 것입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top