vienībtestēšana (ar phpunit)
DESCRIPTION
(atjaunots pēc lekcijas, pielikta saite uz lekcijā rādīto kodu: https://github.com/naivists/PHPUnit)TRANSCRIPT
PHP koda vienībtestēšana(ar PHPUnit)
Krišs Rauhvargers,
27.02.2012
IEVADSPar kādu testēšanu ir runa?
Kas ir vienībtestēšana?
• Oficiāli:– Metode, ko lieto atsevišķu programmatūras
koda daļu pārbaudei, vai tās darbojas saskaņā ar specifikāciju.
– Testē mazāko iespējamo koda vienību• klases metodi• moduļa funkciju
• Vienkāršotā izpratnē– Testi, ko raksta pats programmētājs
Galvenie mērķi
• Pārliecināties, ka – kods dara to, kas paredzēts– labojumi kodā (t.sk. refaktorēšana) nesabojā
kaut ko citu
• Uzlabot koda kvalitāti pirms integrācijas testēšanas
• Padarīt kodu uzturamu arī citiem• Automatizācija
Vienībtestēšana VS integrācijas testēšana
• Vienībtesti nav integrācijas testi!– Integrācijas testi apskata vairāku moduļu
sadarbību vai visu sistēmu kopumā– Vienībtests pārbauda katru moduli atsevišķi
Vienībtests: - vai šim vītnes platums visur ir vienāds?
Integrācijas tests: - vai ar šo var uzspiest līdz 45?
http://www.bolt-manufacturer.com/picture/hex-bolts/heavy-hex-bolt.jpg
http://inhabitat.com/files/mowercycle23.jpg
Ko nozīmē "katru moduli atsevišķi"?
• Vienībtestā jācenšas izolēt pārbaudāmo moduli no citiem moduļiem
• Kļūdu gadījumā gribam zināt, kas tieši vainīgs
• Lai izolētu no pārējiem moduļiem, lieto imitācijas (mock) un aizbāžņus (stub) saistīto moduļu vietā
xUnit
• xUnit: vienībtestēšanas ietvaru saime dažādām valodām, kas– izmanto programmatiskus testus– lieto vienus un tos pašus jēdzienus
• Vēsturiski pirmais ir SUnit (SmallTalk unit testing framework)
• Vēlāk arī JUnit (Java), CPPUnit (C++), NUnit (.Net saimes valodas), PHPUnit.
xUnit termini
• Testu kopa (test suite)– Atsevišķi testi, ko izpilda moduļa funkcionalitātes pārbaudei– Pārbaude kādam koda modulim (piemēram, klasei DateTime
būtu testu kopa DateTimeTest)
• Testpiemērs (test case)– Tests, ko izpilda kādas funkcionalitātes pārbaudei
• Testa konteksts (test fixture)– Datu/vides sagatavošana testu izpildīšanai
• Testu izpilde (test execution)– Testu darbināšana dotajā kontekstā
• Apgalvojumi (assertions)– Kodā pierakstāmi pieņēmumi, kam jābūt spēkā pirms/pēc koda
izpildes
• http://www.martinfowler.com/bliki/Xunit.html
xUnit testu kopas uzbūve
public class SomethingTest inerhits Test {//sagatavošanās ('fixture')public void SetUp() {
} //savākšana aiz sevis public void TearDown{ } //paši testi public void TestMethod1(){} public void TestMethod2(){} ...}
xUnit testu izpildes principi
• Meklē visas testu kopas• Katrā testu kopā meklē visas metodes, kas sākas ar
"Test"• Katrai šādai metodei izpilda:
SomethingTest->SetUp();SomethingTest->TestMethod1();SomethingTest->TearDown();
SomethingTest->SetUp();SomethingTest->TestMethod2();SomethingTest->TearDown();
Vienībtestēšanas maksimums
• Nopietnākais vienībtestēšanas lietojums – testu bāzētā izstrāde (test driven development)– specificē moduļu interfeisus– raksta testus, kas pārbauda šos interfeisus– tikai tad sāk rakstīt pašu kodu
• Sākotnēji visi testi būs "izlaisti" vai "failed" • Beigās būs strādājoša sistēma un 100%
veiksmīgi testi
INSTALĒŠANA
PHPUnit
• PHPUnit ir skriptu komplekts, kas nodrošina – testu izpildi– testu rezultātu attēlošanu– koda pārklājuma analīzi
PHPUnit instalēšana
• Vieglākais PHPUnit instalēšanas risinājums ir PEAR pakotnepear channel-discover pear.phpunit.depear channel-discover components.ez.nopear channel-discover pear.symfony-project.compear install phpunit/PHPUnit
• Lai uzstādītu pilnu versiju, vajadzēs arī Xdebug
PEAR: kas tas tāds?
• PEAR: PHP Extension and Application Repository
• Ideja: komdandrindas rīks, kas ļautu instalēt PHP paplašinājumus
• Uzlikšana:1. iedarbina PHP komandrindas interfeisu
2. lejuplādē http://pear.php.net/go-pear.phar
3. php go-pear.phar4. pārstartē tīmekļa serveri
• Var gadīties, ka noderpear upgrade --force PEAR
Kas ir Xdebug?
• PHP ir skriptēšanas valoda, tas izpildās kāda procesa ietvaros (tīmekļa serverī, komandrindā)– "klasiska" atkļūdošanas pieeja, kur pieslēdzas
procesam, būtu sarežģīta
• Xdebug ir PHP modulis, kas– darbojas PHP interpretatora iekšienē– uz ārpusi sniedz atkļūdošanas informāciju– darbojas kā HTTP serviss
XDebug uzlikšana
• Xdebug ir PECL modulis• Instalējams ar PEAR/PECL:
– pecl install xdebug
• Ini failā papildus:
[xdebug] zend_extension=/Applications/XAMPP/xamppfiles/lib/
php/php-5.3.1/extensions/no-debug-non-zts-20090626/xdebug.so
xdebug.remote_enable=onxdebug.remote_handler=dbgpxdebug.remote_host=127.0.0.1xdebug.remote_port=9000
PEAR uz XAMPP/Wamp
• XAMPP– Jaunākās versijas ir ar PEAR, – Xdebug jāinstalē pašiem
• WampSever– Vecākās versijās PEAR var būt jāliek pašiem– Xdebug vajadzētu būt
Xdebug atbalsts
• NetBeans – kopš 6.versijas integrēts atbalsts
• Notepad++ var iekonfigurēt:– http://dowdrake.com/showthread.php?343-
Xdebug-with-WAMPServer-and-Notepad
Netbeans iekonfigurēšana
Preferences / PHP
NetBeans iekonfigurēšana (2)
Vienībtestēšana: prefrences / unit testingPiedāvā meklēt phpunit.sh, patiesībā saucas phpunit
Eclipse + PHPUnit
• Eclipse Galileo + PDT 2.0– http://pkp.sfu.ca/wiki/index.php/
Configure_Eclipse_for_PHPUnit
PHPUnit + ietvari?
• Zend– Atbalsts jau iekļauts ietvarā– http://framework.zend.com/wiki/display/ZFDEV/
Testing+Standards
• CodeIgniter – Atbalsta ietvarā nav (ir slikts), ir 3. puses risinājums– http://jensroland.com/projects/toast/
• (nav PHPUnit, bet esot labs)
– https://bitbucket.org/kenjis/my-ciunit/overview– https://gist.github.com/1142213
• Symfony– Ir spraudnis:
http://www.symfony-project.org/plugins/sfPhpunitPlugin
DARBOŠANĀS
Failu struktūra
• Labā prakse ir katru (īstā) koda klasi likt atsevišķā failā
• Katrai klasei "atbilst" ir sava testu kopa• Tipisks risinājums: saknes katalogā veidot
apakškatalogu "tests" ar līdzīgu struktūru īstajai/ /common_includes /database /exporters /test
/test /common_includes /database /exporters
Testa kopas struktūra<?phpclass ManaKlaseTest extends PHPUnit_Framework_TestCase { protected $object; //testējamās klases instance
protected function setUp() {$this->object = new ManaKlase();
}
protected function tearDown() {unset($this->object);
}
public function testMetodesPasauksana() {$this->object->PasauktMetodi();$this->assert...();
}} ?>
Ko rakstīt testpiemēros
• Katrai metodei raksta vienu vai vairākus testpiemērus
• Testpiemērs pasauc kādu funkciju un fiksē apgalvojumus, kam jābūt spēkā pēc izsaukšanas
• Labais stils – viens apgalvojums uz vienu testpiemēru
Apgalvojumu veidi
• visi apgalvojumi ir PHPUnit_Framework_TestCase metodes. Tāpēc $this->assert..
• assertEquals(what1, what2);• assertTrue(), assertFalse()• assertGreaterThan(); assertLessThanOrEqual();• assertStringStartsWith(); assertSelectRegexp();• + daudz citu:
http://www.phpunit.de/manual/3.6/en/writing-tests-for-phpunit.html#writing-tests-for-phpunit.assertions
Atkarības
• Var gadīties, ka nav jēgas pildīt testu B, kamēr nav veiksmīgs tests A
• Tad testam B lieto atribūtu @depends
/*** @depends testA*/public function testB(){ }
Datu piegādātāji
• Ir labi veikt testus ar dažādu ievaddatu kopu• Nav prātīgi visus ievaddatus "iešūt kodā"• "Atpārošana" (decoupling) iespējama,
izmantojot @dataProvider atribūtu• Piegādātājs = metode, kas atgriež testa
datu masīvu• Piemēros parasti izmanto array(), praksē
varētu nolasīt no DB.
Datu piegādātāji – piemērsclass DataTest extends PHPUnit_Framework_TestCase{ protected static $myData = array( array(0, 0, 0), array(0, 1, 1), array(1, 0, 1), array(1, 1, 3) ); public static function provider() { return self::$myData; } /** * @dataProvider provider */ public function testAdd($a, $b, $c) { $this->assertEquals($c, $a + $b); }}
Kas traucē vienībtestēšanai?
• Jebkas, kas padara testu specifisku konkrētajam izpildes brīdim vai izsaukumam:
• Globālie mainīgie– to uzstādīšana traucē veikt tīru testu
• "Singleton" pieeja – Ir radniecīgi globālajiem mainīgajiem
• Biznesa darba veikšana konstruktorā• Atkarība no datiem DB vai failu sistēmā• Koda konstrukcijas:
– privātie & aizsargātie mainīgie
KODA PIEMĒRI
@gitHub
• Lekcijā rādītie koda piemēri atrodami šeit:– https://github.com/naivists/PHPUnit
PAPILDUS INFO
Vēl var palasīt
• "Ievads PHPUnit", Chris Cornutt– Pamati:
• http://www.sitepoint.com/tutorial-introduction-to-unit-testing-in-php-with-phpunit/
– Assert varianti• http://www.sitepoint.com/be-more-asssertive-getting-to-know-phpunits-
assertions/
– Mock objekti• http://www.sitepoint.com/tutorial-introduction-to-unit-testing-in-php-with-
phpunit/
• "Labās PHPUnit prakses", Sebastian Bergmann (PHPUnit autors)– http://www.slideshare.net/sebastian_bergmann/introduction-to-
phpunit-best-practices