PHPUnit으로 PHP 헤더 테스트


97

PHPunit을 사용하여 일부 사용자 지정 헤더를 출력하는 클래스를 테스트하려고합니다.

문제는 내 컴퓨터에서 다음과 같습니다.

<?php

class HeadersTest extends PHPUnit_Framework_TestCase {

    public function testHeaders()
    {
        ob_start();

        header('Location: foo');
        $headers_list = headers_list();
        header_remove();

        ob_clean();

        $this->assertContains('Location: foo', $headers_list);
    }
}

또는 이것도 :

<?php

class HeadersTest extends PHPUnit_Framework_TestCase {

    public function testHeaders()
    {
        ob_start();

        header('Location: foo');
        header_remove();

        ob_clean();
    }
}

이 오류를 반환합니다.

name@host [~/test]# phpunit --verbose HeadersTest.php 
PHPUnit 3.6.10 by Sebastian Bergmann.

E

Time: 0 seconds, Memory: 2.25Mb

There was 1 error:

1) HeadersTest::testHeaders
Cannot modify header information - headers already sent by (output started at /usr/local/lib/php/PHPUnit/Util/Printer.php:173)

/test/HeadersTest.php:9

FAILURES!
Tests: 1, Assertions: 0, Errors: 1.

이것은 다른 파일이 포함되어 있지 않고 PHP 태그 시작 전에 다른 문자가 없더라도 테스트가 실행되기 전에 터미널에 출력되는 다른 내용이있는 것처럼 보입니다. 이것을 일으키는 PHPunit 내부의 무언가 일 수 있습니까?

문제가 무엇일까요?


14
다른 사람들도 이것에 관심이 있다면 이것을 다루고 싶었습니다. headers_list ()는 PHPunit (PHP CLI 사용)을 실행하는 동안 작동하지 않지만 xdebug_get_headers ()는 대신 작동합니다.
제목 :

답변:


123

문제는 PHPUnit이 화면에 헤더를 인쇄하고 그 시점에서 더 많은 헤더를 추가 할 수 없다는 것입니다.

해결 방법은 격리 된 프로세스에서 테스트를 실행하는 것입니다. 다음은 예입니다.

<?php

class FooTest extends PHPUnit_Framework_TestCase
{
    /**
     * @runInSeparateProcess
     */
    public function testBar()
    {
        header('Location : http://foo.com');
    }
}

결과는 다음과 같습니다.

$ phpunit FooTest.php
PHPUnit 3.6.10 by Sebastian Bergmann.

.

Time: 1 second, Memory: 9.00Mb

OK (1 test, 0 assertions)

키는 @runInSeparateProcess 주석입니다.

PHPUnit ~ 4.1 또는 무언가를 사용 중이고 오류가 발생하는 경우 :

PHP Fatal error:  Uncaught Error: Class 'PHPUnit_Util_Configuration' not found in -:378
Stack trace:
#0 {main}
  thrown in - on line 378

Fatal error: Uncaught Error: Class 'PHPUnit_Util_Configuration' not found in - on line 378

Error: Class 'PHPUnit_Util_Configuration' not found in - on line 378

Call Stack:
    0.0013     582512   1. {main}() -:0

이를 수정하려면 부트 스트랩 파일에 다음을 추가하십시오.

<?php
if (!defined('PHPUNIT_COMPOSER_INSTALL')) {
    define('PHPUNIT_COMPOSER_INSTALL', __DIR__ . '/path/to/composer/vendors/dir/autoload.php');
}

7
이로 인해 몇 가지 define () 문에 오류가 발생합니다. PHPUnit_Framework_Exception :주의 : 상수 xyz가 이미 정의되어 있습니다.
Minhaz

1
@mebjas 관련이없는 것 같습니다.
SamHennessy

4
나는 적용했을 때 이것을 얻었다 :PHP Fatal error: Uncaught exception 'Exception' with message 'Serialization of 'SplFileInfo' is not allowed' in phar:///usr/local/bin/phpunit/phpunit/Util/GlobalState.php:211
t1gor

2
이것은 확실히 문제를 해결하는 최선의 선택입니다. 그것은 매력처럼 작동했습니다!
xarlymg89 2015-06-12

2
나는 세트 헤더의 배열을 얻기 위해 xdebug_get_headers ()를 사용해야했다. 제 경우에는 headers_list () 전역 함수가 작동하지 않았습니다.
Shalom Sam

108

별도의 프로세스에서 테스트를 실행하면 문제가 해결되지만 대규모 테스트 제품군을 실행할 때 눈에 띄는 오버 헤드가 있습니다.

내 수정 사항은 phpunit의 출력을 stderr로 보내는 것입니다.

phpunit --stderr <options>

그러면 문제가 해결되어야하며 래퍼 함수를 ​​만들고 코드의 모든 항목을 바꿀 필요가 없습니다.


3
훌륭한! 내 코드에 대한 변경 사항, 별도의 프로세스가 없으며 작동합니다.
alexfernandez 2010 년

하지만 여전히 내가 만든 오류가 표시되고 error_reporting (E_ALL) 결과가 표시됩니까?
spankmaster79

1
@ spankmaster79 예, 터미널의 표준 오류로 이동합니다. 기본적으로 대부분의 터미널은 표준 출력과 표준 오류를 함께 인쇄하지만 실제로는 별도의 스트림입니다.
Jon Cairns

나는 만들어지고 있었다 !!! 이 트릭에 대한 tnx, 그것은 의미가 있습니다, 오류는 stderror에보고되어야합니다 !!! Tnx
th3n3rd 2013 년

42
stderr="true"phpunit.xml에 추가 하여 몇 가지 키 입력을 저장할 수 있습니다 .
tszming

9

제쳐두고 : 나를 위해 headers_list()0 요소를 계속 반환했습니다. 질문에 대한 @titel 의 의견을 발견 하고 여기에서 특별히 언급 할 가치가 있다고 생각했습니다.

다른 사람들도 이것에 관심이 있다면 이것을 다루고 싶었습니다. headers_list()PHPunit (PHP CLI 사용)을 실행하는 동안 작동하지 않지만 xdebug_get_headers()대신 작동합니다.

HTH


4

주석에서 이미 언급했듯이 XML 구성 파일에서 processIsolation을 다음과 같이 정의하는 것이 더 나은 솔루션이라고 생각합니다.

     <?xml version="1.0" encoding="UTF-8"?>
     <phpunit
        processIsolation            = "true"
        // ... 
     >
     </phpunit>

이렇게하면 동료를 짜증나게 할 수있는 --stderr 옵션을 전달할 필요가 없습니다.


4
필요한 테스트를 위해 정의하는 것이 좋습니다. 모든 테스트에 대해 설정하면 테스트 실행 속도가 느려집니다.
Shi

3

테스트 / 포함 된 파일 $_SESSION내 에서 사용하기 위해보다 급진적 인 솔루션이있었습니다 . 나는 중 하나 편집 phpunit을의 에서 파일을 ../PHPUnit/Utils/Printer.php 을 가지고 전과 명령 "$ 버퍼를 인쇄" ."session_start();"

그것은 나를 위해 매력처럼 작동했습니다. 하지만 지금까지 "joonty"사용자의 솔루션이 최고라고 생각합니다.


리포지토리에 풀 요청을 제출 했습니까? 나는 이것이 일반적인 문제라고 생각합니다.
t1gor

힌트 주셔서 감사합니다, 나는 나의 phpunit을의 bootstrap.php에서으로 session_start ()를 호출하고 그것은 나를 위해 작동
bumperbox

0

@runInSeparateProcess에 대한 대안은 PHPUnit을 실행할 때 --process-isolation 옵션을 지정하는 것입니다.

name@host [~/test]# phpunit --process-isolation HeadersTest.php

이는 phpunit.xml에서 processIsolation = "true"옵션을 설정하는 것과 유사합니다.

이 솔루션은 --stderr 옵션을 지정하는 것과 유사한 장단점을 가지고 있지만 제 경우에는 작동하지 않았습니다. 기본적으로 별도의 PHP 프로세스에서 각 테스트를 실행하여 성능 저하가 발생할 수 있지만 코드 변경은 필요하지 않습니다.


이것은 원인을 추적하고 몇 가지 테스트를 수행하는 첫 번째 단계 일 수 있지만 유지 관리 가능한 테스트를 생성하려면 주석을 테스트 파일에 직접 포함하기 만하면됩니다. 명령 줄에서 필요한 '특별한'옵션이 적을수록 CI 시스템 구성 유지 관리가 더 쉬워집니다.
Shi

#fail을 다운 그레이드 한 사람. 이 대답은 다른 옵션으로 맞습니다.
fb

0

테스트 후 PHPUnit에서 헤더를 가져 오려면 --stderr 매개 변수를 사용하십시오.

phpunit --stderr
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.