Version 2.0
You are browsing the unmaintained documentation for old Nette 2.0. See documentation for current Nette.

Testování

I dobří programátoři dělají chyby. Rozdíl mezi dobrým a špatným programátorem je v tom, že ten dobrý ji rychle odhalí pomocí automatizovaných testů.

  • „Kdo netestuje, je odsouzen opakovat své chyby.“ (přísloví)
  • „Jakmile se zbavíme jedné chyby, objeví se další.“ (Murphyho zákon)
  • „Testovat, testovat, testovat“ (Martin Iljič Fowler)

Už jste někdy napsali v PHP podobný kód?

$obj = new MyClass;
$result = $obj->process($input);

var_dump($result);

Tedy vypsali jste si výsledek volání funkce proto, abyste okem ověřili, zda vrací to, co má? Určitě to děláte mnohokrát denně. V případě, že všechno funguje správně, smažete tento kód a očekáváte, že se třída v budoucnu nerozbije? Murphyho zákony garantují opak :-)

Kdybyste test nesmazali, mohli byste ho spustit kdykoliv v budoucnu a ověřit, že vše stále funguje jak má. Zároveň by bylo vhodné jej mírně upravit, aby nevyžadoval naši kontrolu, aby se zkrátka zkontroloval sám:

function assertTrue($condition)
{
    echo $condition ? 'OK' : 'ERROR: test neprošel';
}

$obj = new MyClass;
$result = $obj->process($input);
assertTrue( $result === array(1, 2, 3) );

Časem takových testů vytvoříte velké množství, tudíž by se hodilo je spouštět automatizovaně. S tím vám pomůže testovací framework, jako je například Nette\Test používaný k testování samotného Nette Framework nebo velmi populární PHPUnit.

PHPUnit

Nejdřív si PHPUnit nainstalujte. Do příkazové řádky napište:

pear channel-discover pear.phpunit.de
pear install phpunit/PHPUnit

Že se instalace zdařila, poznáme tak, že do příkazové řádky napíšeme phpunit a program se vám ohlásí.

V logice PHPUnit je každý jednotlivý test představován třídou dědící od PHPUnit_Framework_TestCase s příponou Test v názvu (například MyClassTest), která je uložená ve stejnojmenném souboru. Samotné testování se odehrává v jejích metodách s předponou test, například testProcess(). Před každou takovou metodou se spouští setUp(), ve které můžeme uvést testovací prostředí do výchozího stavu.

Pro ověření vráceného výsledku se používají tzv. asserty. PHPUnit jich nabízí celou řadu, nejpoužívanější jsou zřejmě assertTrue($result), assertFalse($result) a assertEquals($ocekavanaHodnota, $result).

Soubor MyClassTest.php by mohl vypadat takto:

require_once 'PHPUnit/Framework.php';

class MyClassTest extends PHPUnit_Framework_TestCase
{
    public function testProcess()
    {
        $obj = new MyClass;
        $result = $obj->process($input);
        $this->assertEquals( array(1, 2, 3), $result );
    }
}

Test spustíme tak, že v adresáři se souborem napíšeme do příkazové řádky:

phpunit .

Testování presenterů

Jak testovat funkci presenterů? Každý presenter má funkci run(), která převede požadavek (objekt Nette\Application\Request) na odpověď (objekt Nette\Application\IResponse).

Aby presenter běžel správně, vyžaduje objekt Nette\DI\Containernakonfigurovanými službami. Nejjednodušší způsob jak vložit nakonfigurovaný DI Container je použitím statické třídy Nette\Environment, který se doporučuje nepoužívat, protože je ve frameworku hlavně kvůli zpětné kompatibilitě. V PHPUnit testech je však použití Nette\Environment oprávněné.

Vytvoříme si tedy požadavek a poté pomocí assertů ověříme vrácenou odpověď:

class HomepagePresenterTest extends PHPUnit_Framework_TestCase
{

    public function testRenderDefault()
    {
        $presenter = new HomepagePresenter(Nette\Environment::getContext());
        $presenter->autoCanonicalize = FALSE;
        $request = new Nette\Application\Request('Homepage', 'GET');
        $response = $presenter->run($request);
        $this->assertInstanceOf(
            'Nette\Application\Responses\TextResponse',
            $response
        );
    }

}