Začínáme s PHPUnitem - základní test
Dejte mi půl hodiny a já vás naučím napsat test! Tento text slouží jako základní návod pro účastníky veřejného školení, nicméně by měl pomoci všem vývojářům v PHP, kteří testy ještě pořád nepíší a myslí si, že to je složité nebo zdlouhavé. Mám na vás jediné přání: pište se mnou. Kdo dnes napíše svůj první test, ozvěte se v komentářích článku a vyptejte se, co jste nepochopili, co vám šlo/nešlo.
Instalace
Nejdřív si nainstalujte PEAR. Každý, kdo to s PHP myslí vážně, PEAR má (ostatně zkuste si představit programátora v Rails bez Gemu nebo Linuxáka bez balíčkovacího systému). Přesto pokud PEAR nemáte, instalujte podle návodu na výše odkázané stránce.
Samotná instalace PHPUnitu je primitivní. Do příkazové řádky zadejte:
pear channel-discover pear.phpunit.de pear channel-discover pear.symfony-project.com pear install phpunit/PHPUnit
Pokud nepoužíváte Windows, instalace proběhne v pořádku. Pokud je máte, je šance tak padesát na padesát, že budete muset použít alternativní návod. Že se instalace podařila, poznáte tak, že do příkazové řádky napíšete phpunit a dostanete výstup podobný tomuto:
PHPUnit 3.4.12 by Sebastian Bergmann. Usage: phpunit [switches] UnitTest [UnitTest.php] phpunit [switches] <directory> ... (dlouhý výpis všemožných voleb)
Šablona testu
A teď si zopakujeme šablonu z předchozího dílu a trochu si ji postupně rozepíšeme.
Test je třída. Obvykle jednu třídu kódu testujeme jednou až několika třídami testů. Mám-li třídu Article, test pojmenovávám ArticleTest (pokud je jich víc, můžeme třídu pojmenovat třeba ArticleSaveTest, ArticleListTest etc.). Důležité je, aby název souboru končil na Test, jinak PHPUnit nepozná, že je v souboru právě třída testu. Existují sice způsoby, jak to obejít, ale na ně pro příštích několik let v klidu zapomeňte.
Třída testu dědí z PHPUnit_Framework_TestCase. Aby byla tato třída přístupná, musíme před třídu napsat require_once "PHPUnit/Framework.php". Mnohem lepší je ale napsat to jednou do souboru bootstrap.php, který si uložíte do složky s testy a budete ho requirovat ve všech testech. Časem zjistíte, že těch společných úkonů na začátku testů je s rostoucím rozsahem systému stále víc.
Samotné testování funkcionality se provádí ve veřejných metodách, které začínají na slovíčko test. Tedy například testSaveData, testValidate… můžete se orientovat podle názvů metod dané třídy, ale není to žádné pravidlo.
Před každým testem se spouští metoda setUp. V té si většinou vytváříme instanci testovaného kódu, dáváme prostředí do výchozího stavu, který je společný všem testům.
class ArticleTest extends PHPUnit_Framework_TestCase
{
protected function setUp()
{
}
public function testSave()
{
// kod testu
}
}
Pamatujte si, že test nemá „otestovat každou řádku“, ale podstatu té třídy. Tedy to, co dělá, jak změní prostředí a co vrátí. Test musí jít za podstatou, když otestujete tu, o moc víc zatím testovacího kódu psát nemusíte. To přijde časem samo!
Při vývoji testu si většinou vystačíte s velmi snadnou šablonou:
- test se nazývá stejně jako třída s připojeným slovem
Testna konci - testujte všechny metody mimo setterů a jděte po tom, co se vrátí a co se změní, když nastavíte dané podmínky
- v setupu si vytvářejte objekt, který budete testovat
- vkládejte nějaký bootstrap a ne přímo
PHPUnit/Framework.php, často se Vám bude hodit mít nějaký kód společný (i u poměrně malých aplikací to bývá config).
Asserty
Pro otestování stavu vráceného výsledku (ale i například změny souboru na disku) se používají takzvané asserty. PHPUnit nabízí širokou škálu, my si popíšeme ty nejčastěji používané. Přesto byste si měli pamatovat, že existují i asserty pro testování existence/obsahu souboru a pro testování struktury a obsahu XML.
Nejčastější asserty jsou:
assertTrue($predanaHodnotaKteraMaBytTrue)
assertFalse($predanaHodnotaKteraMaBytFalse)
assertType("ocekavany typ", $predanaHodnota)
assertEquals("ocekavana hodnota", $predanaHodnota)
Použití v testu je následující (předpokládám ještě použití dibi):
class ArticleTest
{
protected function setUp()
{
dibi::query("truncate table articles");
$this->object = new Article;
}
public function testSave()
{
// vykonam kod
$data = array("name"=>"Muj clanek", "content"=>"Lorem");
// otestuju navratovou hodnotu
$this->assertTrue($this->object->save($data));
// otestuju zmenu, ktera mela nastat
$this->assertEquals("Lorem", dibi::query("select content from articles where name = 'Muj clanek'")->fetchSingle());
}
}
Spouštění testů
Test lze spustit více způsoby (populární je především podpora v různých IDE), my si teď povíme o základním způsobu v příkazové řádce.
Předpokládejme, že testy máte v rootu projektu ve složce tests (nemusím připomínat, že root projektu není totéž, co document_root). Vejděte do složky projektu. Pokud je phpunit správně nainstalovaný, když napíšete phpunit tests, spustí se testy (soubory končící na Test obsahující třídu končící na Test). Pokud zadáte přímo phpunit tests/ArticleTest.php, spustí se jeden konkrétní test case.
Praktická cvičení
Máme třídu Calculator:
class Calculator
{
const ZERO_DIVIDER_CODE = 0;
public function divide($a, $b)
{
if (0 == $b)
throw new InvalidArgumentException("Cannot divide by zero", self::ZERO_DIVIDER_CODE);
return $a / $b;
}
}
Cvičení 1:
Napište test, který ověří funkčnost třídy.
Cvičení 2:
Napište si test pro funkci multiply a factorial a pak implementujte kód, který projde testem.
Cvičení 3:
Vytvořte si třídu, která bude serializovat na disk objekty (do souborů) a pak z nich bude zase objekty vytahovat. Vždy napište nejdřív test, pak napište kód.
V případě problémů se ozvěte do komentářů.
Tato série slouží jako základní materiál pro školení testování, které pořádá Internet Info spolu s autorem článku Jiřím Kneslem. Mimo školení testování nabízí Jiří Knesl i školení Zend Frameworku, agilních technik a metodik.
Školení Google+ pro firmy

- Jak využít Google+ pro firemní komunikaci a marketing.
- Čím se liší Google+ od Twitteru a Facebooku z pohledu firemního využití.
- Jak využít Google+ v souladu s pravidly užívání.
- Založení Google+ Page (Stránky) krok po kroku, včetně praktických tipů.
Detailní informace o školení Google+ »
Přehled názorů
Tento text je již více než dva měsíce starý. Chcete-li na něj reagovat v diskusi, pravděpodobně vám již nikdo neodpoví. Pro řešení aktuálních problémů doporučujeme využít naše diskusní fórum.