Testování presenterů v Nette\Tester
- radas
- Člen | 224
Ahoj,
našel by se někdo, kdo by sem napsal pokud možno funkční kód, který by
demonstroval testování presenteru pomocí nástroje
Nette\Tester? Nejlépe testování
- metody action…()
- metody render…()
- signálu handle…()
- odeslaného formuláře
Rád bych pokryl aplikaci napsanou v Nette testy a rád bych využil právě Nette\Tester.
Díky moc
- David Grudl
- Nette Core | 8218
Nejprve si vytvoř testovací bootstrap, který bude vytvářet DI kontejner.
Potom si vyrob presenter. Buď ručně vytvoříš instanci, nebo rovnou využiješ služeb PresenterFactory:
$presenterFactory = $container->getByType('Nette\Application\IPresenterFactory');
$presenter = $presenterFactory->createPresenter('Sign');
Asi bude vhodné vypnout kanonikalizaci, aby nevracel přesměrování:
$presenter->autoCanonicalize = FALSE;
a rovnou můžeme začít testovat:
// zobrazení stránky Sign:in metodou GET
$response = $presenter->run(new Request('Sign', 'GET', array('action' => 'in')));
Důležité je, že presenter počítá jen s jedním voláním
run()
, pro další requesty vytvoř nový presenter.
Ověříme, zda odpověď je skutečně šablona:
Assert::true( $response instanceof Nette\Application\Responses\TextResponse );
Assert::true( $response->getSource() instanceof Nette\Templating\ITemplate );
Necháme si vygenerovat výsledné HTML:
$html = (string) $response->getSource();
A třeba zkontrolujeme, zda se na stránce nacházejí formulářová políčka pro jméno a heslo:
$dom = Tester\DomQuery::fromHtml($html);
Assert::true( $dom->has('input[name="username"]') ); // zápis jako selektory v jQuery
Assert::true( $dom->has('input[name="password"]') );
- radas
- Člen | 224
Narazil jsem na problém s testováním presenteru, kde po odeslání formuláře a úspěšném ověření uživatele, má proběhnout přesměrování. Testuju tedy odpověď oproti Nette\Application\Responses\RedirectResponse takto:
public function testLoginFormSucceeded()
{
$params = array(
'action' => 'login',
'do' => 'loginForm-submit'
);
$post = array(
'e_mail' => 'somebody@domain.com',
'password' => '***'
);
$request = new Request('Admin:Auth', Http\Request::POST, $params, $post);
$response = $this->presenter->run($request);
Assert::true($response instanceof Nette\Application\Responses\RedirectResponse);
}
Problém ale je, že do Assertu se vůbec nedojde, namísto toho v konzoli to skončí „Nette\Application\UI\InvalidLinkException: No route for Admin:Default:default()“
Přitom aplikace normálně funguje, po úspěšném přihlášení proběhne přesměrování.
Editoval radas (20. 4. 2013 21:53)
- Filip Procházka
- Moderator | 4668
Presenter při vytváření odkazu zkouší vytvořit instance cílového presenteru a volá nad ním reflexi. Musíš zajistit, aby presenter factory takový presenter mohla v pohodě vytvořit.
Také je třeba aby byl přístupný http request, který bude mít v sobě aktuální url, klidně i fake.
- Filip Procházka
- Moderator | 4668
- Mělo by stačit, aby šlo autoloadovat všechny classy presenterů a byl správně nastavený presenter factory mapping jako máš v configu
- https://github.com/…tFactory.php
- MzK
- Člen | 127
Též mi testy vyhazovaly „Nette\Application\UI\InvalidLinkException: No
route for Default:default()“, ale stačilo v setUp()
nastavit $presenter->invalidLinkMode = $presenter::INVALID_LINK_SILENT;
Do _tests/bootstrap.php jsem zkoušel postupně toto:
<?php
//$container->router[] = new \Nette\Application\Routers\CliRouter('Default:default');
$container->router[] = new \Nette\Application\Routers\Route('<presenter>/<action>[/<id>].html[/p-<page>]', 'Default:default');
//$container->removeService("router");
//$container->addService("router", new Nette\Application\Routers\SimpleRouter());
if ($container->parameters['consoleMode']) {
$container->removeService('httpRequest');
$container->addService('httpRequest', function() {
// Podle potreby muzeme pouzit nastaveni z configu nebo vzit z parametru prikazove radky, aj.
$uri = new \Nette\Http\UrlScript();
$uri->scheme = 'http';
$uri->port = \Nette\Http\Url::$defaultPorts['http'];
$uri->host = 'example.com';
$uri->path = '/';
$uri->canonicalize();
$uri->path = \Nette\Utils\Strings::fixEncoding($uri->path);
$uri->scriptPath = '/';
return new \Nette\Http\Request($uri, array(), array(), array(), array(), array(), 'GET', null, null);
});
}
//Set up router
$container->removeService("router");
$container->addService("router", new Nette\Application\Routers\SimpleRouter());
?>
ale bez výsledku, pořád jsem měl chybu „InvalidLinkException“
Edit: už to jde, chyba byla jinde. Do bootstrap stačilo přidat:
<?php
$container->router[] = new \Nette\Application\Routers\Route('<presenter>/<action>[/<id>].html[/p-<page>]', 'Default:default');
?>
Editoval MzK (25. 4. 2013 14:26)
- kedrigern
- Člen | 102
#13 : viz https://forum.nette.org/…php-skrz-cli#… (ale mám obavu, že s aktualizací dev verze Nette se tam něco rozbilo – snad si najdu čas mrknout na to).
- sifik
- Člen | 27
Shodneme se na tom, že to bude jednoduší testovat pomocí Selenia. :-)
Proto jsem vytvořil jednoduché rozšíření pro nette/tester, aby s ním bylo možné spouštet selenium testy.
- Musel jsem udělat fork php webdriveru pro ovládání prohlížeče.