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
बस इसे कवर करना चाहता था अगर कुछ अन्य लोग भी इसमें रुचि रखते हैं। PHPunit (जो PHP CLI का उपयोग करता है) चलाते समय हेडर्स_लिस्ट () काम नहीं करता है, लेकिन इसके बजाय xdebug_get_headers () काम करता है।
१26:

जवाबों:


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
इसमें कुछ त्रुटियों को परिभाषित किया गया है, क्योंकि PHPUnit_Framework_Exception: कथन: नोटिस: लगातार xyz पहले से परिभाषित
Minhaz

1
@mebjas जो असंबंधित लगता है।
सामहेनसी

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

2
मुझे सेट हेडर्स की सरणी प्राप्त करने के लिए xdebug_get_headers () का उपयोग करना पड़ा। हेडर्स_लिस्ट () वैश्विक फ़ंक्शन ने मेरे मामले में काम नहीं किया।
शालोम सैम

107

यद्यपि परीक्षण को एक अलग प्रक्रिया में चलाना समस्या को ठीक करता है, लेकिन परीक्षण का एक बड़ा सूट चलाते समय ध्यान देने योग्य ओवरहेड है।

मेरा तय यह था कि फ़पुनिट के उत्पादन को स्टेटरर तक निर्देशित किया जाए, जैसे:

phpunit --stderr <options>

यह समस्या को ठीक करना चाहिए, और इसका मतलब यह भी है कि आपको एक आवरण फ़ंक्शन बनाने और अपने कोड में सभी घटनाओं को प्रतिस्थापित करने की आवश्यकता नहीं है।


3
प्रतिभाशाली! मेरे कोड में कोई बदलाव नहीं, कोई अलग प्रक्रिया नहीं, और यह काम करता है।
अलेक्सांद्रेज़ेज़

लेकिन क्या मैं अभी भी उन त्रुटियों को देखूंगा जो मैंने किए हैं और error_reporting (E_ALL) का आउटपुट प्राप्त करता है ??
spankmaster79

1
@ spankmaster79 हाँ, यह सिर्फ आपके टर्मिनल की मानक त्रुटि पर जाएगा। डिफ़ॉल्ट रूप से, अधिकांश टर्मिनल मानक आउट और मानक त्रुटि को एक साथ प्रिंट करेंगे, लेकिन वे वास्तव में अलग-अलग धाराएं हैं।
जॉन केयर्न्स

मैं बनता जा रहा था !!! इस चाल के लिए tnx, यह समझ में आता है, त्रुटियों को stderror को सूचित किया जाना चाहिए !!! Tnx
th3n3rd

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
संभवतः इसे केवल उस परीक्षण के लिए परिभाषित करना बेहतर है जिसे इसकी आवश्यकता है। सभी परीक्षणों के लिए इसे सेट करने से परीक्षण धीमा हो जाएगा।
शी

3

मेरे पास $_SESSIONमेरे परीक्षण / शामिल फ़ाइलों के अंदर उपयोग करने के लिए एक अधिक कट्टरपंथी समाधान था । मैं से एक संपादित PHPUnit पर फ़ाइलों ../PHPUnit/Utils/Printer.php एक है करने के लिए "session_start();"इससे पहले कि आदेश "$ बफर प्रिंट"

इसने मेरे लिए एक आकर्षण की तरह काम किया। लेकिन मुझे लगता है कि "जून्टी" उपयोगकर्ता का समाधान अब तक का सबसे अच्छा है।


क्या आपने भंडार में पुल-अनुरोध प्रस्तुत किया था? मुझे लगता है कि यह एक आम समस्या हो सकती है।
t1gor

संकेत के लिए धन्यवाद, मैंने अपने phpunit bootstrap.php में session_start () कहा और यह मेरे लिए काम करता है
bumperbox

0

जब PHPUnit चल रहा हो - @runInSeparateProcess का एक वैकल्पिक समाधान --process- आइसोलेशन विकल्प को निर्दिष्ट करना है।

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

यह phpunit.xml में processIsolation = "true" विकल्प सेट करने के लिए समान है।

इस समाधान में --stderr विकल्प को निर्दिष्ट करने के समान फायदे / नुकसान हैं, जो हालांकि मेरे मामले में काम नहीं करते थे। मूल रूप से कोई भी कोड परिवर्तन आवश्यक नहीं हैं, भले ही एक अलग PHP प्रक्रिया में प्रत्येक परीक्षण को चलाने के कारण एक प्रदर्शन हिट हो सकता है।


यह कारण को ट्रैक करने और कुछ परीक्षण करने में पहला कदम हो सकता है, लेकिन बनाए रखने योग्य परीक्षण बनाने के लिए, बस एनोटेशन को सीधे परीक्षण फ़ाइल में एम्बेड करें। कमांड लाइन से कम 'विशेष' विकल्प की आवश्यकता होती है, सीआई सिस्टम कॉन्फ़िगरेशन का रखरखाव आसान है।
शी '

जिन्होंने कभी # फेल किया। यह उत्तर एक अन्य विकल्प के रूप में सही है।
fb

0

अपने परीक्षणों के बाद PHPUnit से हेडर प्राप्त करने के लिए --stderr पैरामीटर का उपयोग करें।

phpunit --stderr
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.