2009-10-31 11 views
10

Właśnie zacząłem używać PHPUnit, ale wpadłem trochę w pułapkę.Radzenie sobie z problemami ze ścieżkami z PHPUnit

Mój kod używa $ _SERVER ['DOCUMENT_ROOT'] do obliczania ścieżek dla załączników, który działa, gdy mój serwer apache jest tym, który uruchamia PHP, ale DOCUMENT_ROOT nie jest ustawiony, gdy uruchamiam phpunit z linii poleceń z "phpunit Tests" , więc te elementy nie działają.

Czy brakuje mi czegoś w konfiguracji PHPUnit? Czy powinien być w jakiś sposób zintegrowany z Apache?

Odpowiedz

14

Późna odpowiedź, przepraszam.

Nie, niczego nie brakuje. PHP CLI (PHP dla Command Line) to inna bestia niż PHP jako moduł Apache/CGI.

Co możesz zrobić, ale zmień setUp() swoich plików, aby ustawić $_SERVER['DOCUMENT_ROOT'] na to, czego potrzebujesz (ponieważ $_SERVER jest nadal dostępny jako superglobalny nawet w kontekście CLI), np. :

public function setUp() { 
    $_SERVER['DOCUMENT_ROOT'] = dirname(__FILE__) . "/../application"; 
} 

Wystarczy być ostrożnym, prawdopodobnie chcesz umieścić to w swoim tearDown():

public function tearDown() { 
    unset($_SERVER['DOCUMENT_ROOT']); 
} 

PHPUnit backs up your global state jeśli globalne (również superglobalną) dane używasz w ogóle, co może spowolnić swoje testy w dół dramatycznie, w związku z tym, dlaczego lepiej jest uniknąć jakichkolwiek po zakończeniu testu.

0

Najlepszym sposobem jest odłączenie kodu od korzystania z $_SERVER lub dowolnej innej globalnej tablicy. Na przykład zrobić

class MyClass 
{ 
    protected $_docroot; 

    public function __construct($docroot) 
    { 
     $this->_docroot = $docroot; 
    } 

    public function getDocRoot() 
    { 
     return $this->_docroot; 
    } 
} 

zamiast

class MyClass 
{ 
    public function getDocRoot() 
    { 
     return $_SERVER['DOCUMENT_ROOT']; 
    } 
} 

Pozwala to zrobić

// in your actual code 
$instance = new MyClass($_SERVER['DOCUMENT_ROOT']); 
$docroot = $instance->getDocRoot(); 

// in your test 
$instance = new MyClass($variable_holding_the_correct_path); 
$docroot = $instance->getDocRoot(); 

Należy pamiętać, że jest to tylko prosty przykład oddzielenia. W twoim przypadku może to być o wiele bardziej skomplikowane, ale generalnie jest to warte wysiłku, szczególnie jeśli prowadzisz testy jednostkowe.

+0

Problem polega na tym, jak dołączyć plik zawierający tę klasę? –

+0

Ah OK - widzę problem ... trochę źle zrozumiałem prawdziwe tło twojego pytania. Nie powinieneś polegać na włączaniu plików przy użyciu dowolnej zmiennej środowiskowej (w tym '$ _SERVER ['DOCUMENT_ROOT']'). Czy możliwe jest dołączenie plików przy użyciu ścieżek względnych, np. 'require_once dirname (__ FILE__). "/ MyClass.php''? Z drugiej strony możesz ustawić automatyczne ładowanie ... –

1

$_SERVER['DOCUMENT_ROOT'] można również ustawić w pliku bootstrap i tym samym Bootstrap_test.php jest dołączony do pliku konfiguracyjnego phpunit phpunit.xml z atrybutem name bootstrap=Bootstrap_test.php

udało mi się osiągnąć ten wymóg, aby ustawić $ _SERVER [ „DOCUMENT_ROOT”] do konfiguracji pracy Jenkinsa. W „Bootstrap_test.php” wygląda

<phpunit 

    backupGlobals="false" 

    backupStaticAttributes="false" 

    strict="true" 

    verbose="true" 

    bootstrap="Bootstrap_test.php"> 

    <testsuites> 

    <testsuite name="PHPUnit Test Suite"> 

    <file>PHPUnitTest.php</file> 

    </testsuite> 

    </testsuites> 

    <logging> 

    <log type="coverage-clover" target="logs/clover.xml"/> 

    </logging> 

</phpunit> 

i zawartość w Bootstrap.php jest zadeklarowana za pomocą define() funkcję:

define('BASE_PATH', realpath(dirname(__FILE__)));  
$_SERVER['DOCUMENT_ROOT'] = BASE_PATH; 

Zmienna BASE_PATH zazwyczaj utrzymać pełną ścieżkę do katalogu zadań Jenkins. Powiedzmy, że nazwa pracy Jenkins to Test_Job. Katalog, w którym Jenkins umieści kod źródłowy projektu, to /var/lib/jenkins/jobs/Test_Job/workspace (zakładając katalog roboczy jenkins jako /var/lib/jenkins).

Jeśli Bootstrap_test.php jest umieszczony w katalogu głównym, BASE_PATH będzie posiadać /var/lib/jenkins/jobs/Test_Job/workspace i ostatecznie ustawiony na $_SERVER['DOCUMENT_ROOT'].

0

Po prostu chcę udokumentować dzwoniąc do innych plików php (jak config.php) z testów PHPUnit.
Mam klasy badawczej:

class xyzTest extends TestCase { 

    public static function setUpBeforeClass() { 
     require_once __DIR__ . '/../../app/config/Config.php'; 
    } 

... 

W config.php skonfigurować pewne stałe, takie jak ścieżki do plików. Ścieżki te odnoszą się do $_SERVER['DOCUMENT_ROOT'].
Chcę przetestować moją klasę xyz używając tych stałych ścieżek.
Jednak superglobal $_SERVER jest pusty, wywołując PHPUnit z wiersza poleceń. Próbowałem postępować zgodnie z dobrą radą z answer above i ustawić metody $_SERVER['DOCUMENT_ROOT'] w PHPUnits setUp. To nie naprawiło mojego problemu.

Naprawiłem go dodając oświadczenie if do mojego Config.php, tak:

if ($_SERVER['DOCUMENT_ROOT']) { 
    $DocumentRoot = realpath($_SERVER['DOCUMENT_ROOT']); 
} else { 
    $DocumentRoot = realpath(dirname(__FILE__) . '/../..'); //for PHPUnit 
} 

Nadzieja ta oszczędza komuś ból głowy.

Powiązane problemy