Estou tentando usar o PHPunit para testar uma classe que gera alguns cabeçalhos personalizados.
O problema é que na minha máquina isso:
<?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);
}
}
ou mesmo este:
<?php
class HeadersTest extends PHPUnit_Framework_TestCase {
public function testHeaders()
{
ob_start();
header('Location: foo');
header_remove();
ob_clean();
}
}
retorna este erro:
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.
Parece que há outra saída no terminal antes da execução do teste, embora não haja nenhum outro arquivo incluído e nenhum outro caractere antes do início da tag PHP. Será que algo dentro do PHPunit está causando isso?
Qual poderia ser o problema?
Respostas:
O problema é que o PHPUnit imprimirá um cabeçalho na tela e nesse ponto você não poderá adicionar mais cabeçalhos.
A solução alternativa é executar o teste em um processo isolado. Aqui está um exemplo
Isso resultará em:
A chave é a anotação @runInSeparateProcess.
Se você estiver usando PHPUnit ~ 4.1 ou algo assim e obtiver o erro:
Tente adicionar isso ao seu arquivo de inicialização para corrigi-lo:
fonte
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
Embora a execução do teste em um processo separado corrija o problema, há uma sobrecarga perceptível ao executar um grande conjunto de testes.
Minha correção foi direcionar a saída do phpunit para stderr, assim:
Isso deve resolver o problema e também significa que você não precisa criar uma função de wrapper e substituir todas as ocorrências em seu código.
fonte
stderr="true"
em seu phpunit.xml para salvar alguns pressionamentos de tecla.Como um aparte: Para mim,
headers_list()
continuei retornando 0 elementos. Notei o comentário de @titel sobre a questão e achei que merece menção especial aqui:HTH
fonte
Como já mencionado em um comentário, acho que é uma solução melhor para definir o isolamento do processo no arquivo de configuração XML, como
Assim, você não precisa passar a opção --stderr, o que pode irritar seus colegas de trabalho.
fonte
Tive uma solução mais radical, para usar
$_SESSION
dentro dos meus arquivos testados / incluídos . Eu editei um dos arquivos PHPUnit em ../PHPUnit/Utils/Printer.php para ter um"session_start();"
antes do comando "print $ buffer" .Funcionou para mim como um encanto. Mas acho que a solução do usuário "joonty" é a melhor de todas até agora.
fonte
Uma solução alternativa para @runInSeparateProcess é especificar a opção --process-isolation ao executar o PHPUnit:
Isso é análogo a definir a opção processIsolation = "true" em phpunit.xml.
Essa solução tem vantagens / desvantagens semelhantes à especificação da opção --stderr, que, entretanto, não funcionou no meu caso. Basicamente, nenhuma mudança de código é necessária, embora possa haver um impacto no desempenho devido à execução de cada teste em um processo PHP separado.
fonte
Use o parâmetro --stderr para obter cabeçalhos do PHPUnit após seus testes.
fonte