ZF3 konkrétně balíček zend-test obsahuje velice užitečnou třídu AbstractHttpControllerTestCase na testování kontrolerů v MVC projektu. Chci si vytvořit testy všech action metod kontroleru ? Není problém, vytvořím si adresář /test v modulu, do něho vložím nový php soubor např. ListControllerTest.php, který bude obsahovat v definici rozšiřovat třídu AbstractHttpControllerTestCase.
class ListControllerTest extends AbstractHttpControllerTestCase { }
Zend test: https://github.com/zendframework/zend-test
Dispatch
Samotný test umí vyrenderovat kompletní stránku přes php konzoli metodou dispatch(), která má jako parametr relativní URL stránky ! Není nutné instalovat žádný Selenium server a testovat projekt zvenku web browserem ! Spouštění stránek PHP-CLI má ale svoje limity, např. pokud v projektu používám $_SERVER[‚HTTP_HOST‘] (aktuální url v prohlížeči), nebude proměnná $_SERVER existovat (konzole není prohlížeč). Řešením je použití metody getenv() v tomto případě getenv(‚HTTP_HOST‘). Použití filter_input je potřeba nahradit zendovským fromQuery.
Metoda dispatch má jako druhý parametr HTTP metodu (např. GET = výchozí). Třetí parametr je pole, do kterého se vkládají parametry (query např. [‚id‘ => 123]). Je libo testovat ajax volání (X-Requested-With: XMLHttpRequest) ? Žádný problém pro zend, do čtvrtého parametru stačí dát true.
Asserty (výroky)
Samotné PHPUnit testy tvoří jednotlivé asserty. Každý test jich může obsahovat třeba 10. Asserty se dají popsat jako tvrzení, která musí platit. Např. tvrdím, že stránka vrací status code 200 OK ($this->assertResponseStatusCode(200);).
Potřebuju otestovat routování ? Ok, přidám testy na router např. že stránka musí pocházet z modulu Application ($this->assertModuleName(‚application‘);), konkrétně musí projít přes kontroler ListController $this->assertControllerName(ListController::class);, samotná routa se musí jmenovat list ($this->assertMatchedRouteName(‚list‘);).
Pokud projdu testem až k samotné action kontroleru, tak se dá testovat samotný obsah stránky ! Ještě je dobré testovat header např. u Ajaxu vracejícím JSON ($this->assertResponseHeaderContains(‚Content-Type‘, ‚application/json; charset=utf-8‘);)
Obsah stránky se dá testovat buďto přímo přes body $body = $this->getResponse()->getBody(); nebo u klasické HTML stránky jsou k dispozici 2 typy práce s DOM objekty (query a XPath). např. otestovat meta tag title se dá takto $this->assertQueryContentContains(‚title‘,’Titulek stránky‘);
Příklady XPath
Kontrola obsahu canonical link:
$this->assertXpathQueryContentContains('/html/head/link[@rel="canonical"]/@href','/firmy/blablabla/');
Kontrola breadcrumbs:
$this->assertXpathQueryContentContains('(//div[@id="breadcrumb"]//a)[1]',"Domů");
Test 301 redirectu
Test status code odpovědi.
$this->assertResponseStatusCode(301);
Test cílové url přesměrování.
$this->assertRedirectTo('/firmy/blablabla2/');