PHP başlıklarını PHPUnit ile test edin


99

Bazı özel başlıkları veren bir sınıfı test etmek için PHPunit kullanmaya çalışıyorum.

Sorun şu ki benim makinemde bu:

<?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);
    }
}

hatta bu:

<?php

class HeadersTest extends PHPUnit_Framework_TestCase {

    public function testHeaders()
    {
        ob_start();

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

        ob_clean();
    }
}

bu hatayı döndür:

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.

Bu, başka bir dosya bulunmamasına ve PHP etiketinin başlangıcından önce başka bir karakter bulunmamasına rağmen, test çalışmadan önce terminale başka bir çıktı gönderiliyor gibi görünüyor. PHPunit içinde buna neden olan bir şey olabilir mi?

Sorun ne olabilir?


14
Bununla ilgilenen başka insanlar da varsa bunu kapatmak istedim. PHPunit (PHP CLI kullanan) çalıştırılırken headers_list () çalışmaz, ancak bunun yerine xdebug_get_headers () çalışır.
başlık

Yanıtlar:


125

Sorun, PHPUnit'in ekrana bir başlık yazdırması ve bu noktada daha fazla başlık ekleyememenizdir.

Çözüm, testi izole bir süreçte çalıştırmaktır. İşte bir örnek

<?php

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

Bu şunlarla sonuçlanacaktır:

$ phpunit FooTest.php
PHPUnit 3.6.10 by Sebastian Bergmann.

.

Time: 1 second, Memory: 9.00Mb

OK (1 test, 0 assertions)

Anahtar @runInSeparateProcess ek açıklamasıdır.

PHPUnit ~ 4.1 veya başka bir şey kullanıyorsanız ve şu hatayı alıyorsanız:

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

Düzeltmek için bunu bootstrap dosyanıza eklemeyi deneyin:

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

7
bu, bazı define () deyimlerinde hatalara neden olur
PHPUnit_Framework_Exception

1
@mebjas Bu alakasız görünüyor.
SamHennessy

4
Bunu uyguladığımda aldım: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
Sorunu çözmek için kesinlikle en iyi seçenek budur. Tılsım gibi çalıştı!
xarlymg89

2
Set başlıklarının dizisini elde etmek için xdebug_get_headers () kullanmak zorunda kaldım. headers_list () global işlevi benim durumumda çalışmadı.
Shalom Sam

108

Testi ayrı bir işlemde çalıştırmak sorunu çözse de, büyük bir test grubu çalıştırırken gözle görülür bir ek yük vardır.

Düzeltmem phpunit'in çıktısını stderr'e yönlendirmekti, şöyle ki:

phpunit --stderr <options>

Bu, sorunu çözmelidir ve aynı zamanda bir sarmalayıcı işlevi oluşturmanız ve kodunuzdaki tüm örnekleri değiştirmeniz gerekmediği anlamına gelir.


3
Parlak! Kodumda değişiklik yok, ayrı işlemler yok ve çalışıyor.
alexfernandez

ancak yine de yaptığım hataları görüp error_reporting (E_ALL) çıktısını alacak mıyım?
spankmaster79

1
@ spankmaster79 evet, sadece terminalinizin standart hatasına gidecek. Varsayılan olarak çoğu terminal, standart ve standart hatayı birlikte yazdırır, ancak bunlar aslında ayrı akışlardır.
Jon Cairns

yapılıyordum !!! tnx bu hile için mantıklı geliyor, hatalar tam olarak bildirilmeli !!! Tnx
th3n3rd

42
stderr="true"Birkaç tuş vuruşunu kaydetmek için phpunit.xml dosyanızı ekleyebilirsiniz .
tszming

10

Bir kenara: Benim için headers_list()0 elementi döndürmeye devam etti. @Titel'in soruyla ilgili yorumunu fark ettim ve burada özel olarak bahsedilmeyi hak ettiğini düşündüm:

Bununla ilgilenen başka insanlar da varsa bunu kapatmak istedim. headers_list()PHPunit (PHP CLI kullanan) çalıştırılırken çalışmaz ama xdebug_get_headers()onun yerine çalışır.

HTH


4

Bir yorumda daha önce belirtildiği gibi, XML yapılandırma dosyasında processIsolation'ı tanımlamanın daha iyi bir çözüm olduğunu düşünüyorum.

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

Bunun gibi, --stderr seçeneğini geçmek zorunda değilsiniz, bu da iş arkadaşlarınızı rahatsız edebilir.


4
Muhtemelen sadece onu gerektiren test için tanımlamak daha iyidir. Tüm testler için ayarlamak, testleri yavaşlatacaktır.
Shi

3

Test edilen / dahil edilen dosyalarımın $_SESSIONiçinde kullanmak için daha radikal bir çözüm buldum . ../PHPUnit/Utils/Printer.php adresindeki PHPUnit dosyalarından birini "print $ buffer" komutundan önce bir tane olacak şekilde düzenledim ."session_start();"

Benim için bir cazibe gibi çalıştı. Ama bence "joonty" kullanıcının çözümü şimdiye kadar en iyisi.


Bilgi havuzundaki çekme talebini gönderdiniz mi? Sanırım bu yaygın bir sorun olabilir.
t1gor

İpucu için teşekkürler, phpunit bootstrap.php dosyamda session_start () 'ı çağırdım ve benim için çalışıyor
bumperbox

0

@RunInSeparateProcess için alternatif bir çözüm, PHPUnit'i çalıştırırken --process-isolation seçeneğini belirlemektir:

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

Phpunit.xml'de processIsolation = "true" seçeneğini ayarlamak benzerdir.

Bu çözümün --stderr seçeneğini belirtmeye benzer avantajları / dezavantajları vardır, ancak benim durumumda işe yaramadı. Her testin ayrı bir PHP sürecinde çalıştırılması nedeniyle bir performans düşüşü olsa bile, temelde hiçbir kod değişikliği gerekmez.


Bu, nedeni takip etmek ve bazı testler yapmak için ilk adım olabilir, ancak bakımı yapılabilir testler oluşturmak için ek açıklamayı doğrudan test dosyasına gömün. Komut satırından ne kadar az 'özel' seçenek gerekli olursa, CI sistem konfigürasyonunun bakımı o kadar kolay olur.
Shi

kim düşürdü # başarısız. bu cevap başka bir seçenek olarak doğrudur.
fb

0

Testlerinizden sonra PHPUnit'ten üstbilgi almak için --stderr parametresini kullanın.

phpunit --stderr
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.