Successfully reported this slideshow.
Your SlideShare is downloading. ×

Unit testing

Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Unit Testing Merangkak Menuju Pengembangan Aplikasi PHP yang Berkualitas dan Tahan Banting Arthur Purnama arthur [at] purn...

YouTube videos are no longer supported on SlideShare

View original on YouTube

Arthur Purnama <ul><li>Diplom Informatiker Hochschule Fulda </li></ul><ul><li>Sejak 2004 bekerja sebagai PHP Programmer </...
Loading in …3
×

Check these out next

1 of 42 Ad

Unit testing

EPHPC Webinar
Unit Testing

Merangkak Menuju Pengembangan Aplikasi PHP yang Berkualitas dan Tahan Banting.

Date: Wednesday, April 6, 2011
Time: 1:00 pm, Bangkok Time (Bangkok, GMT+07:00)

EPHPC Webinar
Unit Testing

Merangkak Menuju Pengembangan Aplikasi PHP yang Berkualitas dan Tahan Banting.

Date: Wednesday, April 6, 2011
Time: 1:00 pm, Bangkok Time (Bangkok, GMT+07:00)

Advertisement
Advertisement

More Related Content

Slideshows for you (20)

Viewers also liked (18)

Advertisement

Similar to Unit testing (20)

Advertisement

Recently uploaded (20)

Unit testing

  1. 1. Unit Testing Merangkak Menuju Pengembangan Aplikasi PHP yang Berkualitas dan Tahan Banting Arthur Purnama arthur [at] purnama.de http://arthur.purnama.de 06.04.2011
  2. 2. Arthur Purnama <ul><li>Diplom Informatiker Hochschule Fulda </li></ul><ul><li>Sejak 2004 bekerja sebagai PHP Programmer </li></ul><ul><li>Sejak 2008 bekerja sebagai ITConsultant divisi Portal Solutions </li></ul><ul><li>Saat ini tinggal di Frankfurt am Main, Jerman </li></ul>
  3. 3. Tujuan <ul><li>Memperkenalkan Unit Testing </li></ul><ul><li>Mendorong atau memotivasi penggunaan Unit Testing </li></ul><ul><li>Memperkenalkan Unit Testing Framework PHPUnit </li></ul>
  4. 4. Rutinitas Test Programer PHP <ul><li>Berjam-jam mencari bug </li></ul><ul><li>Debugger? apaan tuh? </li></ul><ul><li>Teman setia: echo, print_r, var_dump </li></ul><ul><li>Mati satu tumbuh seribu (bug baru) </li></ul><ul><li>Bug Lama Bersemi Kembali </li></ul>
  5. 5. Unit Testing <ul><li>In computer programming, unit testing is a method by which individual units of source code are tested to determine if they are fit for use. </li></ul><ul><li>A unit is the smallest testable part of an application. </li></ul><ul><li>In object-oriented programming a unit is usually a method. </li></ul>http://en.wikipedia.org/wiki/Unit_testing
  6. 6. Unit Testing <ul><li>Dalam pemrograman komputer, unit testing merupakan suatu metode yang mana satu unit dalam source code diuji untuk menunjukkan bahwa code tersebut bekerja sebagaimana mestinya. </li></ul><ul><li>Unit adalah bagian terkecil dari satu aplikasi yang dapat diuji. </li></ul><ul><li>Dalam pemrograman berorientasi obyek, unit biasanya adalah method. </li></ul>
  7. 7. Contoh function multiplicate($a, $b){ return $a*$b; } echo multiplicate(1, 2) === 2 ? true : false ; echo PHP_EOL; echo multiplicate(2, 2) === 4 ? true : false ; echo PHP_EOL; echo multiplicate(3, 2) !== 5 ? true : false ;
  8. 8. Kelebihan Unit Testing <ul><li>Yakin setiap saat bahwa code berfungsi sebagaimana mestinya. </li></ul><ul><li>Yakin setiap kali aplikasi berkembang, code tetap berfungsi sebagaimana mestinya. </li></ul><ul><li>Yakin setiap kali melakukan re-design atau refakturisasi, code tetap berfungsi sebagaimana mestinya. </li></ul>
  9. 9. Kelebihan Unit Testing <ul><li>Menjadi bagian dari dokumentasi code </li></ul><ul><li>Mempermudah Integrasi antar komponen </li></ul><ul><li>Meningkatkan kualitas code </li></ul>
  10. 10. Unsur Unit Testing <ul><li>Harus di otomatisasi </li></ul><ul><li>Dapat dijalankan dengan sekali klick </li></ul><ul><li>Dapat dengan mudah diulang </li></ul><ul><li>Mudah diimplementasikan </li></ul><ul><li>Setelah ditulis dapat dijalankan kapan saja </li></ul><ul><li>Setiap orang dapat menjalankannya </li></ul><ul><li>Berjalan dengan cepat </li></ul>
  11. 11. Unit Test != Integration Test <ul><li>Unit Test </li></ul><ul><ul><li>Tidak berinteraksi dengan basis data </li></ul></ul><ul><ul><li>Tidak berinteraksi dengan Jaringan </li></ul></ul><ul><ul><li>Tidak berinteraksi dengan File System </li></ul></ul><ul><ul><li>Tidak membutuhkan konfigurasi khusus untuk menjalankannya </li></ul></ul><ul><ul><li>Terisolasi dari komponen atau kelas konkrit lainnya </li></ul></ul>
  12. 12. Unit Testing Framework <ul><li>PHPUnit </li></ul><ul><ul><li>Unit Testing Framework </li></ul></ul><ul><ul><li>Ditulis oleh Sebastian Bergmann </li></ul></ul><ul><ul><li>De facto standard untuk PHP </li></ul></ul><ul><ul><li>Banyak didukung oleh Tools dan Framework lain </li></ul></ul>
  13. 13. Contoh Unit Testing Multiplikasi <ul><li><?php </li></ul><ul><li>//MultiplikasiTest.php </li></ul><ul><li>require_once 'multiplikasi.php' ; </li></ul><ul><li>class BelajarUnitTest extends PHPUnit_Framework_TestCase{ </li></ul><ul><li>} </li></ul><ul><li>?> </li></ul>
  14. 14. Contoh Unit Testing Multiplikasi <ul><li><?php </li></ul><ul><li>//MultiplikasiTest.php </li></ul><ul><li>require_once 'multiplikasi.php' ; </li></ul><ul><li>class BelajarUnitTest extends PHPUnit_Framework_TestCase{ </li></ul><ul><li>//Nama fungsi menggunakan awalan “test“ </li></ul><ul><ul><li>public function testMultiplicate(){ </li></ul></ul><ul><ul><li>} </li></ul></ul><ul><li>} </li></ul><ul><li>?> </li></ul>
  15. 15. Contoh Unit Testing Multiplikasi <ul><li><?php </li></ul><ul><li>//MultiplikasiTest.php </li></ul><ul><li>require_once 'multiplikasi.php' ; </li></ul><ul><li>class BelajarUnitTest extends PHPUnit_Framework_TestCase{ </li></ul><ul><li>//Nama fungsi menggunakan awalan “test“ </li></ul><ul><ul><li>public function testMultiplicate(){ </li></ul></ul><ul><ul><li>$this->assertEquals(2, multiplicate(1, 2)); </li></ul></ul><ul><ul><li>} </li></ul></ul><ul><li>} </li></ul><ul><li>?> </li></ul>
  16. 16. Contoh Unit Testing Multiplikasi <ul><li>$>phpunit BelajarUnitTest MultiplikasiTest.php </li></ul><ul><li>PHPUnit 3.5.12 by Sebastian Bergmann. </li></ul><ul><li>. </li></ul><ul><li>Time: 0 seconds, Memory: 3.00Mb </li></ul><ul><li>OK (1 test, 1 assertion) </li></ul>
  17. 17. Contoh Unit Testing Multiplikasi <ul><li><?php </li></ul><ul><li>//MultiplikasiTest.php </li></ul><ul><li>require_once 'multiplikasi.php' ; </li></ul><ul><li>class BelajarUnitTest extends PHPUnit_Framework_TestCase{ </li></ul><ul><ul><li>public function testMultiplicate(){ </li></ul></ul><ul><ul><li>//Sangat tidak dianjurkan. Pastikan hanya selalu menguji SATU hal </li></ul></ul><ul><ul><ul><li>$this->assertEquals(2, multiplicate(1, 2)); </li></ul></ul></ul><ul><ul><ul><li>$this->assertEquals(5, multiplicate(3, 2)); </li></ul></ul></ul><ul><ul><ul><li>$this->assertEquals(4, multiplicate(2, 2)); </li></ul></ul></ul><ul><ul><li>} </li></ul></ul><ul><li>} </li></ul><ul><li>?> </li></ul>
  18. 18. Contoh Unit Testing Multiplikasi <ul><li>$>phpunit BelajarUnitTest MultiplikasiTest.php </li></ul><ul><li>PHPUnit 3.5.12 by Sebastian Bergmann. </li></ul><ul><li>F </li></ul><ul><li>Time: 0 seconds, Memory: 3.00Mb </li></ul><ul><li>There was 1 failure: </li></ul><ul><li>1) BelajarUnitTest::testMultiplicate </li></ul><ul><li>Failed asserting that <integer:6> matches expected <integer:5>. </li></ul><ul><li>$ultiplikasiTest.php:10 </li></ul><ul><li>FAILURES! </li></ul><ul><li>Tests: 1, Assertions: 2, Failures: 1. </li></ul>
  19. 19. Contoh Unit Testing Multiplikasi <ul><li><?php </li></ul><ul><li>//MultiplikasiTest.php </li></ul><ul><li>require_once 'multiplikasi.php' ; </li></ul><ul><li>class BelajarUnitTest extends PHPUnit_Framework_TestCase{ </li></ul><ul><ul><li>public function testMultiplicate1And2(){ </li></ul></ul><ul><ul><li>$this->assertEquals(2, multiplicate(1, 2)); </li></ul></ul><ul><ul><li>} </li></ul></ul><ul><ul><li>public function testMultiplicate3And2(){ </li></ul></ul><ul><ul><li>$this->assertEquals(5, multiplicate(3, 2)); </li></ul></ul><ul><ul><li>} </li></ul></ul><ul><ul><li>public function testMultiplicate2And2(){ </li></ul></ul><ul><ul><li>$this->assertEquals(4, multiplicate(2, 2)); </li></ul></ul><ul><ul><li>} </li></ul></ul><ul><li>} </li></ul><ul><li>?> </li></ul>
  20. 20. Contoh Unit Testing Multiplikasi <ul><li>$>phpunit MultiplikasiTest.php </li></ul><ul><li>PHPUnit 3.5.12 by Sebastian Bergmann. </li></ul><ul><li>.F. </li></ul><ul><li>Time: 0 seconds, Memory: 3.00Mb </li></ul><ul><li>There was 1 failure: </li></ul><ul><li>1) BelajarUnitTest::testMultiplicate3And2 </li></ul><ul><li>Failed asserting that <integer:6> matches expected <integer:5>. </li></ul><ul><li>$ultiplikasiTest.php:12 </li></ul><ul><li>FAILURES! </li></ul><ul><li>Tests: 3, Assertions: 3, Failures: 1. </li></ul>
  21. 21. Contoh Unit Testing Multiplikasi <ul><li><?php </li></ul><ul><li>//MultiplikasiTest.php </li></ul><ul><li>require_once 'multiplikasi.php' ; </li></ul><ul><li>class BelajarUnitTest extends PHPUnit_Framework_TestCase{ </li></ul><ul><ul><li>public function testMultiplicate1And2(){ </li></ul></ul><ul><ul><li>$this->assertEquals(2, multiplicate(1, 2)); </li></ul></ul><ul><ul><li>} </li></ul></ul><ul><ul><li>public function testMultiplicate3And2(){ </li></ul></ul><ul><ul><li>$this->assertNotEquals(5, multiplicate(3, 2)); </li></ul></ul><ul><ul><li>} </li></ul></ul><ul><ul><li>public function testMultiplicate2And2(){ </li></ul></ul><ul><ul><li>$this->assertEquals(4, multiplicate(2, 2)); </li></ul></ul><ul><ul><li>} </li></ul></ul><ul><li>} </li></ul><ul><li>?> </li></ul>
  22. 22. Contoh Unit Testing Multiplikasi <ul><li>$>phpunit BelajarUnitTest MultiplikasiTest.php </li></ul><ul><li>PHPUnit 3.5.12 by Sebastian Bergmann. </li></ul><ul><li>... </li></ul><ul><li>Time: 0 seconds, Memory: 3.00Mb </li></ul><ul><li>OK (3 tests, 3 assertions) </li></ul>
  23. 23. Contoh Unit Testing Multiplikasi <ul><li>$>phpunit --testdox BelajarUnitTest MultiplikasiTest.php </li></ul><ul><li>PHPUnit 3.5.12 by Sebastian Bergmann. </li></ul><ul><li>BelajarUnitTest </li></ul><ul><li>[x] Multiplicate 1 and 2 </li></ul><ul><li>[x] Multiplicate 3 and 2 </li></ul><ul><li>[x] Multiplicate 2 and 2 </li></ul>
  24. 24. Tapi.. Code saya seperti ini.. <ul><li><?php </li></ul><ul><li>// Connects to your Database </li></ul><ul><li>mysql_connect ( &quot;your.hostaddress.com&quot; , &quot;username&quot; , &quot;password&quot; ) or die ( mysql_error () ); </li></ul><ul><li>mysql_select_db ( &quot;Database_Name&quot; ) or die ( mysql_error () ); </li></ul><ul><li>//checks cookies to make sure they are logged in </li></ul><ul><li>if ( isset ( $_SESSION [ 'ID_my_site' ] )) { </li></ul><ul><ul><li>$username = $_ SESSION [ 'ID_my_site' ]; </li></ul></ul><ul><ul><li>$pass = $_ SESSION [ 'Key_my_site' ]; </li></ul></ul><ul><ul><li>$check = mysql_query ( &quot;SELECT * FROM users WHERE username = ' $username '&quot; ) or die ( mysql_error () ); </li></ul></ul><ul><ul><li>$result = mysql_fetch_array ( $check ); </li></ul></ul><ul><ul><li>foreach ( $result as $info ) { </li></ul></ul><ul><ul><ul><li>//if the cookie has the wrong password, they are taken to the login page </li></ul></ul></ul><ul><ul><ul><li>if ($pass != $info [ 'password' ]) { </li></ul></ul></ul><ul><ul><ul><li>header ( &quot;Location: login.php&quot; ); </li></ul></ul></ul><ul><ul><ul><li>} else { //otherwise they are shown the admin area </li></ul></ul></ul><ul><ul><ul><ul><li>echo &quot;<p>Admin Area</p>&quot; ; </li></ul></ul></ul></ul><ul><ul><ul><ul><li>echo &quot;<p>Your Content<p>&quot; ; </li></ul></ul></ul></ul><ul><ul><ul><ul><li>echo &quot;<a href=logout.php>Logout</a>&quot; ; </li></ul></ul></ul></ul><ul><ul><ul><li>} </li></ul></ul></ul><ul><ul><li>} </li></ul></ul><ul><li>} else { </li></ul><ul><ul><li>//if the cookie does not exist, they are taken to the login screen </li></ul></ul><ul><ul><li>header ( &quot;Location: login.php&quot; ); </li></ul></ul><ul><li>} </li></ul><ul><li>?> </li></ul>
  25. 25. Core techniques <ul><li>Refactoring </li></ul><ul><li>Separation of Concern </li></ul><ul><li>Inversion of Control (Dependency Injection) </li></ul><ul><li>Design by Contract </li></ul><ul><li>Design Patterns </li></ul>
  26. 26. Contoh Refactoring <ul><li><?php </li></ul><ul><li>namespace myappecurity; </li></ul><ul><li>use myappaosnterfacesser; </li></ul><ul><li>use myapptilnterfacesession; </li></ul><ul><li>class Authorize implements interfacesuthorize{ </li></ul><ul><ul><li>private $userDAO ; </li></ul></ul><ul><ul><li>private $session ; </li></ul></ul><ul><ul><li>public function __construct(User $userDAO, Session $session) { </li></ul></ul><ul><ul><ul><li>$this-> userDAO = $userDAO; </li></ul></ul></ul><ul><ul><ul><li>$this-> session = $session; </li></ul></ul></ul><ul><ul><li>} </li></ul></ul><ul><ul><li>public function isAuthorize(){ </li></ul></ul><ul><ul><ul><li>if ($this-> session ->isAuthenticate()){ </li></ul></ul></ul><ul><ul><ul><ul><li>$user = $this-> userDAO ->getByUsername($this-> session ->getUsername()); </li></ul></ul></ul></ul><ul><ul><ul><ul><li>return $this-> session ->getPassword() === $user->getPassword(); </li></ul></ul></ul></ul><ul><ul><ul><li>} else { </li></ul></ul></ul><ul><ul><ul><li>return false ; </li></ul></ul></ul><ul><ul><ul><li>} </li></ul></ul></ul><ul><ul><li>} </li></ul></ul><ul><li>} </li></ul><ul><li>?> </li></ul>
  27. 27. Mocks & Stubs <ul><li><?php </li></ul><ul><li>namespace myappocks; </li></ul><ul><li>use myappaosnterfacesser; </li></ul><ul><li>class UserPalsu implements User{ </li></ul><ul><ul><li>public function getById($id){ </li></ul></ul><ul><ul><li>return null ; </li></ul></ul><ul><ul><li>} </li></ul></ul><ul><ul><li>public function getByUsername($username){ </li></ul></ul><ul><ul><li>return null ; </li></ul></ul><ul><ul><li>} </li></ul></ul><ul><ul><li>public function getAll(){ </li></ul></ul><ul><ul><li>return null ; </li></ul></ul><ul><ul><li>} </li></ul></ul><ul><li>} </li></ul><ul><li>?> </li></ul><ul><li><?php </li></ul><ul><li>namespace myappocks; </li></ul><ul><li>use myapptilnterfacesession; </li></ul><ul><li>class SessionPalsu implements Session{ </li></ul><ul><ul><li>public function getUsername(){ </li></ul></ul><ul><ul><li>return null ; </li></ul></ul><ul><ul><li>} </li></ul></ul><ul><ul><li>public function getPassword(){ </li></ul></ul><ul><ul><li>return null ; </li></ul></ul><ul><ul><li>} </li></ul></ul><ul><ul><li>public function isAuthenticate(){ </li></ul></ul><ul><ul><li>return false ; </li></ul></ul><ul><ul><li>} </li></ul></ul><ul><li>} </li></ul><ul><li>?> </li></ul>
  28. 28. Unit Test Authorize <ul><li><?php </li></ul><ul><li>use myappecurityuthorize; </li></ul><ul><li>use myappocksessionPalsu; </li></ul><ul><li>use myappocksserPalsu; </li></ul><ul><li>class AuthorizeTest extends PHPUnit_Framework_TestCase { </li></ul><ul><ul><li>public function testIsAuthorizeSessionNotAuthenticate(){ </li></ul></ul><ul><ul><ul><li>$userDAO = new UserPalsu(); </li></ul></ul></ul><ul><ul><ul><li>$session = new SessionPalsu(); </li></ul></ul></ul><ul><ul><ul><li>$authorize = new Authorize($userDAO, $session); </li></ul></ul></ul><ul><ul><ul><li>$this->assertFalse($authorize->isAuthorize()); </li></ul></ul></ul><ul><ul><li>} </li></ul></ul><ul><li>} </li></ul><ul><li>?> </li></ul>
  29. 29. Mocks & Stubs <ul><li><?php </li></ul><ul><li>namespace myappocks; </li></ul><ul><li>use myappodels; </li></ul><ul><li>use myappaosnterfacesser; </li></ul><ul><li>class UserPalsu implements User{ </li></ul><ul><ul><li>private $user ; </li></ul></ul><ul><ul><li>public function getById($id){ </li></ul></ul><ul><ul><li>return null ; </li></ul></ul><ul><ul><li>} </li></ul></ul><ul><ul><li>public function getByUsername($username){ </li></ul></ul><ul><ul><li>return $this-> user ; </li></ul></ul><ul><ul><li>} </li></ul></ul><ul><ul><li>public function getAll(){ </li></ul></ul><ul><ul><li>return null ; </li></ul></ul><ul><ul><li>} </li></ul></ul><ul><ul><li>public function setUser(modelsnterfacesser $user){ </li></ul></ul><ul><ul><li>$this-> user = $user; </li></ul></ul><ul><ul><li>} </li></ul></ul><ul><li>} </li></ul><ul><li>?> </li></ul><ul><li><?php </li></ul><ul><li>namespace myappocks; </li></ul><ul><li>use myapptilnterfacesession; </li></ul><ul><li>class SessionPalsu implements Session{ </li></ul><ul><ul><li>private $username ; </li></ul></ul><ul><ul><li>private $password ; </li></ul></ul><ul><ul><li>private $authenticate ; </li></ul></ul><ul><ul><li>public function getUsername() { </li></ul></ul><ul><ul><li>return $this-> username ; </li></ul></ul><ul><ul><li>} </li></ul></ul><ul><ul><li>public function setUsername($username) { </li></ul></ul><ul><ul><li>$this-> username = $username; </li></ul></ul><ul><ul><li>} </li></ul></ul><ul><ul><li>public function getPassword() { </li></ul></ul><ul><ul><li>return $this-> password ; </li></ul></ul><ul><ul><li>} </li></ul></ul><ul><ul><li>public function setPassword($password) { </li></ul></ul><ul><ul><li>$this-> password = $password; </li></ul></ul><ul><ul><li>} </li></ul></ul><ul><ul><li>public function isAuthenticate(){ </li></ul></ul><ul><ul><li>return $this-> authenticate ; </li></ul></ul><ul><ul><li>} </li></ul></ul><ul><ul><li>public function setAuthenticate($authenticate){ </li></ul></ul><ul><ul><li>$this-> authenticate = $authenticate; </li></ul></ul><ul><ul><li>} </li></ul></ul><ul><li>} </li></ul><ul><li>?> </li></ul>
  30. 30. Unit Test Authorize <ul><li><?php </li></ul><ul><li>use myappodelsser; </li></ul><ul><li>use myappecurityuthorize; </li></ul><ul><li>use myappocksessionPalsu; </li></ul><ul><li>use myappocksserPalsu; </li></ul><ul><li>class AuthorizeTest extends PHPUnit_Framework_TestCase { </li></ul><ul><ul><li>//public function testIsAuthorizeSessionNotAuthenticate(){... </li></ul></ul><ul><ul><li>public function testIsAuthorizeSessionAuthenticateButWrongPassword(){ </li></ul></ul><ul><ul><ul><li>$userDAO = new UserPalsu(); </li></ul></ul></ul><ul><ul><ul><li>$user = new User( &quot;username&quot; , &quot;password&quot; ); </li></ul></ul></ul><ul><ul><ul><li>$userDAO->setUser($user); </li></ul></ul></ul><ul><ul><ul><li>$session = new SessionPalsu(); </li></ul></ul></ul><ul><ul><ul><li>$session->setPassword( &quot;wrongpassword&quot; ); </li></ul></ul></ul><ul><ul><ul><li>$authorize = new Authorize($userDAO, $session); </li></ul></ul></ul><ul><ul><ul><li>$this->assertFalse($authorize->isAuthorize()); </li></ul></ul></ul><ul><ul><li>} </li></ul></ul><ul><ul><li>public function testIsAuthorizeSessionAuthenticateCorrectPassword(){ </li></ul></ul><ul><ul><ul><li>$userDAO = new UserPalsu(); </li></ul></ul></ul><ul><ul><ul><li>$user = new User( &quot;username&quot; , &quot;password&quot; ); </li></ul></ul></ul><ul><ul><ul><li>$userDAO->setUser($user); </li></ul></ul></ul><ul><ul><ul><li>$session = new SessionPalsu(); </li></ul></ul></ul><ul><ul><ul><li>$session->setPassword( &quot;password&quot; ); </li></ul></ul></ul><ul><ul><ul><li>$authorize = new Authorize($userDAO, $session); </li></ul></ul></ul><ul><ul><ul><li>$this->assertTrue($authorize->isAuthorize()); </li></ul></ul></ul><ul><ul><li>} </li></ul></ul><ul><li>} </li></ul><ul><li>?> </li></ul>
  31. 31. Mengorganisir Unit Test <ul><li>Fixture </li></ul><ul><li>Bootstrap </li></ul><ul><li>Stubs & Mocks Tools </li></ul><ul><li>Test Suite </li></ul><ul><li>Code Coverage </li></ul>
  32. 32. Fixtures <ul><li><?php </li></ul><ul><li>use myappodelsser; </li></ul><ul><li>use myappecurityuthorize; </li></ul><ul><li>use myappocksessionPalsu; </li></ul><ul><li>use myappocksserPalsu; </li></ul><ul><li>class AuthorizeTest extends PHPUnit_Framework_TestCase { </li></ul><ul><ul><li>private $userDAO ; </li></ul></ul><ul><ul><li>private $session ; </li></ul></ul><ul><ul><li>public function setUp(){ </li></ul></ul><ul><ul><ul><li>$this-> userDAO = new UserPalsu(); </li></ul></ul></ul><ul><ul><ul><li>$user = new User( &quot;username&quot; , &quot;password&quot; ); </li></ul></ul></ul><ul><ul><ul><li>$this-> userDAO ->setUser($user); </li></ul></ul></ul><ul><ul><ul><li>$this-> session = new SessionPalsu(); </li></ul></ul></ul><ul><ul><ul><li>$this-> session ->setAuthenticate( true ); </li></ul></ul></ul><ul><ul><li>} </li></ul></ul><ul><ul><li>public function tearDown(){ </li></ul></ul><ul><ul><ul><li>$this-> userDAO = null ; </li></ul></ul></ul><ul><ul><ul><li>$this-> session = null ; </li></ul></ul></ul><ul><ul><li>} </li></ul></ul><ul><ul><li>//public function testIsAuthorizeSessionNotAuthenticate(){.. </li></ul></ul><ul><ul><li>public function testIsAuthorizeSessionAuthenticateButWrongPassword(){ </li></ul></ul><ul><ul><ul><li>$this-> session ->setPassword( &quot;wrongpassword&quot; ); </li></ul></ul></ul><ul><ul><ul><li>$authorize = new Authorize($this-> userDAO , $this-> session ); </li></ul></ul></ul><ul><ul><ul><li>$this->assertFalse($authorize->isAuthorize()); </li></ul></ul></ul><ul><ul><li>} </li></ul></ul><ul><ul><li>public function testIsAuthorizeSessionAuthenticateCorrectPassword(){ </li></ul></ul><ul><ul><ul><li>$this-> session ->setPassword( &quot;password&quot; ); </li></ul></ul></ul><ul><ul><ul><li>$authorize = new Authorize($this-> userDAO , $this-> session ); </li></ul></ul></ul><ul><ul><ul><li>$this->assertTrue($authorize->isAuthorize()); </li></ul></ul></ul><ul><ul><li>} </li></ul></ul><ul><li>} ?> </li></ul>
  33. 33. Bootstrap < phpunit bootstrap = &quot;/path/to/bootstrap.php&quot; colors = &quot;false&quot; convertErrorsToExceptions = &quot;true&quot; convertNoticesToExceptions = &quot;true&quot; convertWarningsToExceptions = &quot;true&quot; stopOnFailure = &quot;true&quot; > <!-- ... --> </ phpunit >
  34. 34. Stubs and Mocks Tools <ul><li><?php </li></ul><ul><li>use myappecurityuthorize; </li></ul><ul><li>class AuthorizeTest extends PHPUnit_Framework_TestCase { </li></ul><ul><ul><li>private $userDAO ; </li></ul></ul><ul><ul><li>private $session ; </li></ul></ul><ul><ul><li>public function setUp() { </li></ul></ul><ul><ul><li>$this-> userDAO = $this->getMock ( 'yappaosser' ); </li></ul></ul><ul><ul><li>$user = $this->getMock ( 'myappodelsser' , array (), array (), '' , false , false , false ); </li></ul></ul><ul><ul><li>$user->expects ( $this->any () )->method ( 'getUsername' )->will ( $this->returnValue ( 'username' ) ); </li></ul></ul><ul><ul><li>$user->expects ( $this->any () )->method ( 'getPassword' )->will ( $this->returnValue ( 'password' ) ); </li></ul></ul><ul><ul><li>$this-> userDAO ->expects ( $this->any () )->method ( 'getByUsername' )->will ( $this->returnValue ( $user ) ); </li></ul></ul><ul><ul><li>$this-> session = $this->getMock ( 'yapptilession' , array (), array (), '' , false , false , false ); </li></ul></ul><ul><ul><li>$this-> session ->expects ( $this->any () )->method ( 'isAuthenticate' )->will ( $this->returnValue ( true ) ); </li></ul></ul><ul><ul><li>} </li></ul></ul><ul><ul><li>public function tearDown() { </li></ul></ul><ul><ul><ul><li>$this-> userDAO = null ; </li></ul></ul></ul><ul><ul><ul><li>$this-> session = null ; </li></ul></ul></ul><ul><ul><li>} </li></ul></ul><ul><ul><li>//public function testIsAuthorizeSessionNotAuthenticate(){... </li></ul></ul><ul><ul><li>public function testIsAuthorizeSessionAuthenticateButWrongPassword() { </li></ul></ul><ul><ul><ul><li>$this-> session ->expects ( $this->any () )->method ( 'getPassword' )->will ( $this->returnValue ( 'wrongpassword' ) ); </li></ul></ul></ul><ul><ul><ul><li>$authorize = new Authorize ( $this-> userDAO , $this-> session ); </li></ul></ul></ul><ul><ul><ul><li>$this->assertFalse ( $authorize->isAuthorize () ); </li></ul></ul></ul><ul><ul><li>} </li></ul></ul><ul><ul><li>public function testIsAuthorizeSessionAuthenticateCorrectPassword() { </li></ul></ul><ul><ul><ul><li>$this-> session ->expects ( $this->any () )->method ( 'getPassword' )->will ( $this->returnValue ( 'password' ) ); </li></ul></ul></ul><ul><ul><ul><li>$authorize = new Authorize ( $this-> userDAO , $this-> session ); </li></ul></ul></ul><ul><ul><ul><li>$this->assertTrue ( $authorize->isAuthorize () ); </li></ul></ul></ul><ul><ul><li>} </li></ul></ul><ul><li>} </li></ul><ul><li>?> </li></ul>
  35. 35. Test Suite File System Object Tests |-- Freezer |-- Freezer | |-- HashGenerator | |-- HashGenerator | | `-- NonRecursiveSHA1.php | | `-- NonRecursiveSHA1Test.php | |-- HashGenerator.php | | | |-- IdGenerator | |-- IdGenerator | | `-- UUID.php | | `-- UUIDTest.php | |-- IdGenerator.php | | | |-- LazyProxy.php | | | |-- Storage | |-- Storage | | `-- CouchDB.php | | `-- CouchDB | | | | |-- WithLazyLoadTest.php | | | | `-- WithoutLazyLoadTest.php | |-- Storage.php | |-- StorageTest.php | `-- Util.php | `-- UtilTest.php `-- Freezer.php `-- FreezerTest.php $>phpunit Tests PHPUnit 3.5.13 by Sebastian Bergmann. ............................................................ 60 / 75 ............... Time: 0 seconds OK (75 tests, 164 assertions)
  36. 36. Test Suite XML < phpunit > < testsuites > < testsuite name = &quot;Object_Freezer&quot; > < file > Tests/Freezer/HashGenerator/NonRecursiveSHA1Test.php < / file > < file > Tests/Freezer/IdGenerator/UUIDTest.php < / file > < file > Tests/Freezer/UtilTest.php < / file > < file > Tests/FreezerTest.php < / file > < file > Tests/Freezer/StorageTest.php < / file > < file > Tests/Freezer/Storage/CouchDB/WithLazyLoadTest.php < / file > < file > Tests/Freezer/Storage/CouchDB/WithoutLazyLoadTest.php < / file > < / testsuite > < / testsuites > < / phpunit >
  37. 37. Code Coverage
  38. 38. Memulai Unit Testing <ul><li>Yakinkan diri sendiri </li></ul><ul><li>Kumpulkan Case Study atau Success Story </li></ul><ul><ul><li>http://biblio.gdinwiddie.com/biblio/StudiesOfTestDrivenDevelopment </li></ul></ul><ul><li>Cari Pendukung / Panggil Konsultan </li></ul><ul><li>Tentukan Tujuan </li></ul><ul><li>Catat Perkembangan </li></ul><ul><li>Bersiap menghadapi rintangan </li></ul>
  39. 39. Kemana Setelah Ini <ul><li>Metodologi </li></ul><ul><ul><li>Test Driven Development </li></ul></ul><ul><ul><li>Behaviour Driven Development </li></ul></ul><ul><li>Tools Pendukung </li></ul><ul><ul><li>IDE (Zend Studio, PHPStorm, PDT, NetBeans) </li></ul></ul><ul><ul><li>Build Automation (Ant, Maven, Phing) </li></ul></ul><ul><ul><li>Continuous Integration </li></ul></ul><ul><li>Test Lain menggunakan PHPUnit </li></ul><ul><ul><li>Database Testing </li></ul></ul><ul><ul><li>UI Testing (Selenium) </li></ul></ul><ul><li>Diskusi terbuka di Milist / Groups </li></ul>
  40. 40. Referensi <ul><li>Wikipedia </li></ul><ul><ul><li>http://en.wikipedia.org/wiki/Unit_testing </li></ul></ul><ul><li>„ PHPUnit Manual“ – Sebastian Bergmann </li></ul><ul><ul><li>http://www.phpunit.de/manual/current/en/ </li></ul></ul><ul><li>„ Getting Started With PHPUnit “ – Sebastian Bergmann </li></ul><ul><ul><li>http://www.slideshare.net/sebastian_bergmann/getting-started-with-phpunit </li></ul></ul><ul><li>„ The Art of Unit Testing“ - Roy Osherove </li></ul><ul><li>„ Unit Testing Fundamentals“ – Richard Paul </li></ul><ul><ul><li>http://www.slideshare.net/rapaul/unit-testing-fundamentals </li></ul></ul><ul><li>„ Embrace Unit Testing“ – Alessio Pace </li></ul><ul><ul><li>http://www.slideshare.net/alessiopace/embrace-unit-testing </li></ul></ul>
  41. 41. <ul><li>Web: http://arthur.purnama.de </li></ul><ul><li>Mail: arthur [at] purnama.de </li></ul><ul><li>Twitter: @purnama </li></ul><ul><li>Groups: </li></ul><ul><ul><li>[email_address] </li></ul></ul><ul><ul><li>[email_address] </li></ul></ul>

Editor's Notes

  • Selamat Datang di acara webinar kali ini, kali ini kita akan membahas mengenai Unit testing
  • Perkenalkan dulu, Nama Saya Arthur Purnama, Saya menyelesaikan kuliah saya di Hochschule Fulda, sejenis sekolah tinggi di satu kota kecil di jerman berpenduduk kurang lebih 70 ribu orang. Disana saya mengambil jurusan studi Informatika dengan bidang studi Multimedia dan meraih gelar kesarjanaan jerman Diplom Informatiker. Saya mengenal PHP sejak 2001 dan mulai bekerja secara produktif sebagai PHP Programmer sejak 2004 di satu perusahaan IT -di Fulda juga- yang memproduksi Web aplikasi untuk Time Management System yang didistribusikan dalam bentuk Software as a Service, Disana saya juga memproduksi sejenis Portal Bursa Pekerjaan yang khusus ditujukan untuk orang jerman. Sejak 2008 saya pindah kota ke Frankfurt am Main untuk bekerja sebagai IT Consultant di divisi Portal Solutions untuk satu Perusahaan Konsultasi IT yang berpusat München Jerman. Client yang saya layani sebagian besar dari Financial Services, Telekomunikasi, Asuransi dan Automobilindustri. Solusi solusi yang saya kerjakan disini umumnya berbasis Java.
  • Sebelum masuk ke pokok pembicaraan saya ingin menjelaskan tujuan dari pertemuan kita kali ini. Beberapa minggu lalu waktu saya nyanggupin tawarannya mas Rama Yurindra untuk membawakan webinar, saya bertanya Thema apa yang cocok. Mas Rama bilang, bahwa ada baiknya saya mengangkat satu Thema Quality Assurance yang kelihatannya belum begitu umum di komunitas PHP Indonesia. Jadilah saya ingin mencoba untuk mengangkat Thema tentang unit testing ini. Pada kesempatan ini saya akan mencoba untuk memperkenalkan unit testing ke kalian. Apa itu unit testing, bagaimana caranya, dan apa untungnya. Saya akan mencoba untuk mendorong atau memotivasi kalian menggunakan, melakukan, dan atau menerapkan unit testing dalam pekerjaan kalian mengembangkan Aplikasi. Saya akan menggunakan bahasa pemrograman PHP untuk mendukung pembahasan ini. Dan disini saya akan memperkenalkan Unit Testing Framework PHPUnit sebagai salah satu tools/alat dalam mengautomatisasi Unit Testing di bahasa pemrograman PHP. Saya bilang merangkak karena saya sadar thema ini cukup luas dan tidak bisa saya kupas semua untuk satu jam kedepan, terlebih lagi, thema ini bukan hal baru dan sudah cukup banyak dibahas dan didiskusikan di internet. akan tetapi saya akan tetap berusaha untuk menjamah poin-poin penting yang ada. Dan juga supaya kalian di akhir pertemuan ini tidak pergi hanya dengan teori dan gagasan yang muluk, tapi juga punya pegangan yang bisa dipakai untuk lebih mendalami lebih jauh tentang unit testing. Pada akhir pembicaraan saya akan mencoba memberikan link atau referensi untuk jadi bahan studi atau penelitian lanjutan. Jadi kalo sekarang merangkak, minimal nanti saya harap kalian bisa berdiri sendiri hehehehehe. Hal-hal teknis spesifik seperti, bagaimana menginstall PHPUnit sengaja tidak akan saya bahas karena informasi atau tutorial seperti itu cukup banyak tersebar di Internet dan di dalam website PHPUnit sendiri. So sekarang mari kita mulai.
  • PHP dikenal merupakan salah satu bahasa pemrogramman yang mudah dipelajari. Banyak orang belajar sebentar langsung bisa bikin Web yang dinamis dan cukup canggih. Hal ini membuat orang semakin berani untuk menulis web aplikasi yang cukup kompleks. Tidak jarang justru hal ini juga yang membuat reputasi php menjadi buruk. Tidak sedikit aplikasi yang ditulis dalam PHP memiliki reputasi sebagai aplikasi yang tidak aman dan penuh bugs. Padahal kualitas sebuah aplikasi tersebut tidak bergantung banyak pada bahasanya akan tetapi juga pada pengembangnya yang menulis aplikasi tersebut. Yaitu sejauh mana pengembangnya peduli akan kualitas aplikasinya. Kita bisa menulis aplikasi web yang cukup kompleks dengan begitu cepat menggunakan PHP. Akan tetapi kecepatan itu kita bayar dengan duduk berjam-jam mencari bugs dalam code kita. Scrolling 5000 baris code sudah hal yang wajar ya. Dan karena PHP gak perlu di compile, tinggal pencet F5 di browser atau ctrl F5 kita tidak butuh debugger. Kalo penasaran satu variabel nilainya apa tinggal echo, print_r, atau var_dump. Tidak jarang setelah kita benerin satu bug, malah muncul bug lain yang bikin kita jadi penasaran, „ini bug karena tadi saya koreksi bug lain atau memang dari tadi ada ya?“ Atau malah, „loh perasaan bug ini udah saya benerin deh bulan lalu. Kok muncul lagi? Atau jangan-jangan itu modul yang lain yang saya benerin ya?“ Kalian mungkin akhirnya berpikir. Oke, dengan ini sebenarnya saya sudah melakukan test dong terhadap aplikasi yang saya tulis, itu menunjukkan bahwa saya peduli sama kualitas aplikasi saya. Bagaimanapun juga bugs akan tetap muncul dan tidak bisa dihindari. Pendapat ini tidak salah. Hanya saja apabila kita mengerti untuk menerapkan methode dan tehnik software testing yang benar, kita dapat setidaknya meminimalisasi jumlah bugs yang hadir seiring berkembangnya atau semakin kompleksnya aplikasi kita. Dan Salah satu tehnik Software testing yang akan kita bahas disini adalah Unit Testing
  • So apa itu Unit Testing. Paling gampang ya buka Wiki. Saat ini di wiki belum ada versi bahasa indonesianya. Jadi saya coba mengambil versi bahasa inggrisnya. Kalau setelah ini ada yang punya kesempatan dan kemauan untuk menulis versi bahasa indonesianya. Silahkan saja. Saat ini saya akan mencoba menterjemahkannya saja secara bebas.
  • Yang penting perlu diketahui disini tidak hanya apa itu unit testing, akan tetapi apa itu unit dan apa yang dapat didefinisikan sebagai unit dalam pemrograman berorientasi obyek. Karena php juga bisa jalan tanpa pemrograman berorientasi obyek. Unit bisa kita definisikan juga sebagai fungsi dalam php. Dengan begitu maka Unit Testing bisa dicontohkan seperti berikut
  • Dalam contoh ini bisa dilihat bahwa saya menguji satu unit atau fungsi php namanya multiplicate untuk menunjukkan bahwa fungsi tersebut bekerja sebagaimana mestinya. Saya menguji bahwa 1 kali 2 harus mengembalikan nilai 2, 2 kali dua mengembalikan nilai 4 dan tiga kali dua tidak menghasilkan nilai 5. Kalian pasti berpikir, „wah kayak gini mah saya juga pernah bikin. Malah banyak sekali dan lebih kompleks dari ini.“ Ya memang betul. Kita sebenarnya sedikit banyak juga sudah pernah melakukan unit testing. Akan tetapi meskipun dilihat secara teknis kita sudah pernah melakukan unit testing, hal ini tidak membantu membuat kita menulis aplikasi kita menjadi lebih baik. Dalam kesempatan ini saya ingin membahas Unit Testing tidak terbatas dalam lingkup definisinya saja. Akan tetapi juga bagaimana mengorganisir, mengontrol, merawat dan lain-lain. Singkat nya kita akan belajar bagaimana menulis unit testing yang baik dan benar.
  • So… Perlukah sebenarnya belajar unit testing yang baik dan benar? Apa yang kurang dari test yang selama ini dilakukan? Kelebihan apa yang bisa didapat apabila Unit Testing diterapkan dalam pengembangan aplikasi? Yang pertama dan yang pasti adalah bahwa unit testing dapat meyakinkan kita, setiap saat bahwa code kita berfungsi. Apabila saya mencetak tebal kata setiap saat, maka saya maksudkan juga setiap saat. Tidak hanya berfungsi di laptop tapi juga di test server. Tidak hanya berfungsi di test server tapi juga di produktiv server. Setiap saat, dimana saja kita dapat memastikan dengan unit testing bahwa code kita berfungsi dengan benar. Kita juga memiliki keyakinan bahwa seiring berkembangnya aplikasi kita, kita bisa selalu mengetahui bahwa code kita tetap berfungsi sebagaimana mestinya. Dengan ini kita juga bisa memprediksi, melihat atau bahkan menemukan bugs cukup dini, bahkan mungkin sebelum fitur baru selesai diimplementasikan. Dan tidak hanya itu… Apabila fitur baru mengharuskan kita melakukan redesign atau refakturisasi dalam code kita, Unit testing membantu kita dengan mudah untuk meyakinkan bahwa dalam tahap redesign atau sesudah redesign code kita tetap berfungsi sebagaimana mestinya.
  • Selain itu, dengan unit testing, kita jadi dapat melihat bagaimana code tersebut digunakan. Ini membuat unit testing menjadi seperti bagian dari dokumentasi. Saya sempat mengikuti pengembangan satu library PHP untuk Object Relational Mapping. Saya ingin menggunakannya karena saya merasa library ini cocok buat aplikasi saya. Ketika itu library ini belum final, dan dokumentasi belum lengkap. Saya mempelajari penggunaannya melalui Unit Testing nya. Kemudahan untuk mengerti bagaimana code berfungsi dan digunakan akan mempermudah pengembang untuk mengintegrasikan code tersebut dengan code yang sedang ditulisnya. Atau dalam contoh saya mengintegrasikan library PHP tersebut ke dalam aplikasi saya. Dengan ini tentunya diharapkan pada akhirnya kualitas code itu sendiri meningkat. Ya.. Ya.. Yang terakhir kedengerannya marketing banget. Perlu di ingat.. Semua kelebihan ini hanya dapat dicapai apabila kita menerapkan unit testing dengan baik dan benar. Baik dan benar ini penting ya… antara kita menerapkan unit testing dengan baik dan benar, atau tidak sama sekali. Apabila kita menerapkan nya setengah-setengah. Kelebihan tersebut gak akan kelihatan, yang ada malah menjadi beban. Apabila sudah menjadi beban, moral bisa turun, kalian bisa kecewa dan hilang kepercayaan dengan unit testing. Aplikasi jadi bukan makin baik malah makin buruk. Kalau begitu apa saja sih unsur2 yang mendefinisikan unit testing yang baik dan benar?
  • Yang pasti unit testing tersebut harus di otomatisasi, tinggal klick mouse atau ketik command sekali, langsung bisa jalan. Apabila unit testing tersebut membutuhkan banyak sekali utak atik konfigurasi atau siapin ini itu dulu, nyalain ini itu dulu, itu sudah bukan unit testing lagi. Karena otomatis, tentunya unit testing harus dapat dengan mudah diulang berkali-kali. Ini jelas penting, karena unit testing bukan sesuatu yang dijalankan hanya ketika mau deploy aplikasi ke test server atau produktiv server, tapi unit testing dijalankan sambil mengembangkan aplikasi. Unit Testing juga harus mudah diimplementasikan. Kalo sulit, ya bisa buang waktu dan kita malah sibuk nyiapin unit testing daripada menulis code yang sebenarnya. Dan setelah diimplementasikan unit testing harus bisa dijalankan, kapan saja, oleh siapa saja dan di mana saja. Seperti yang saya bilang tadi. Tidak di laptop saja jalan tapi juga di test server. Tidak hanya jalan kemaren, tapi juga bisa jalan hari ini, besok, besok lusa, minggu depan dan seterusnya. Dan tentunya Unit test harus berjalan dengan cepat. Apabila tidak cepat, orang tidak akan sering pakai. Boro-boro pakai berulang-ulang apalagi dipakai sambil ngembangin aplikasi. So.. Kita sudah melihat unsur2 dari unit test. Sekarang kita bandingkan dengan segala jenis test yang sudah pernah kita jalankan dalam mengembangkan aplikasi kita, dan ajukan pertanyaan berikut pada diri masing masing. Apakah test yang saya jalankan, bisa saya jalankan lagi beberapa saat kemudian? Besok? Lusa? Minggu depan? Apakah teman kerja saya bisa menjalankan test yang saya lakukan beberapa waktu lalu? Apakah saya dapat menjalankan semua test saya dengan cepat dan hanya dengan sekali klick? Tidak bisa?... Hmmm terus selama ini saya ini melakukan test apa? Tja Teman-teman, kalian selama ini melakukan apa yang disebut dengan integration test..
  • Dalam integration test kita mengetes fungsi akhir dari aplikasi kita yang umumnya kita lakukan melalui User interface kita. Kita klik sana, klik sini, posting formulir dan lain sebagainya. Fungsi-fungsi, kelas-kelas dan komponen yang kita tulis saling bekerja sama untuk memproses hasil akhir yang kita inginkan. Pada umumnya terjadi juga interaksi dengan aplikasi atau system lain, yang paling umum misalnya database, file-file data, atau web service. Pada dasarnya, apabila test yang kita lakukan gagal, kita tidak hanya harus mencari dimana gagalnya, akan tetapi juga proses yang seperti apa yang mengacu pada kegagalan tersebut. Apabila proses tersebut cukup mudah, maka nyarinya gampang. Tapi umumnya proses dalam aplikasi kita kan sangat-sangat kompleks. Lain halnya dengan Unit Testing. Dalam menguji code kita menggunakan unit testing, code kita terisolasi dari komponen atau kelas konkrit yang berinteraksi dengannya. Dengan ini kita dapat dengan mudah mengatur dan menciptakan semua kemungkinan yang akan terjadi dengan code kita. Bukan berarti integration test tidak penting. Tentunya penting juga, masing – masing memiliki tujuan test yang berbeda dan masing – masing saling melengkapi. Dengan unit test kita dapat melihat bahwa masing-masing individu dari unit kita melakukan pekerjaan mereka dengan benar. Akan tetapi dengan unit test kita tidak melihat bagaimana mereka bekerja sama menjadi satu kesatuan aplikasi. OK kalau test yang selama ini dikerjakan merupakan Integration Test, bagaimana kita bisa merealisasikan unsur-unsur unit testing tersebut? Harus diotomatisasi, tinggal klick, jalan dimana saja, bisa dilakukan berulang-ulang, tidak bicara sama sistim lain, harus cepet lagi…. Gimana caranya? Kita Pakai yang namanya…
  • Unit Testing Framework. Pada dasarnya unit testing framework untuk php tidak cuma ada satu. Hanya saja PHPUnit menjadi salah satu yang paling banyak dipakai, dan banyak Tools seperti IDE dan Framework PHP mendukung penggunaan PHPUnit. Sehingga PHPUnit menjadi de facto standard dalam php untuk melakukan Unit Testing. PHPUnit sendiri sebenarnya tidak bisa dibilang Unit Testing Framework, karena dia bisa melakukan lebih dari sekedar Unit Testing. Dia juga sebenarnya bisa mengotomatisasi integration testing. Bahkan dia juga sebenarnya bisa mengotomatisasi database testing. Maka dari itu sebenernya PHPUnit lebih cocok disebut testing Framework. Untuk pertemuan kali ini kita akan melihat PHPUnit sebagai Unit testing framework. Mari kita coba test contoh multiplikasi kita yang diatas menggunakan PHPUnit.
  • Untuk membuat unit Testing kita membuat satu file php dengan nama TestMultiplikasi yang didalamnya ada kelas php yang memiliki nama BelajarUnitTesting, dan menurunkan kelas PHPUnit_Framework_TestCase.
  • Di dalamnya kita membuat satu fungsi public yang dinamakan testMultiplicate. Awalan test dalam nama method menunjukkan bahwa fungsi tersebut merupakan unit testing dan akan dijalankan secara otomatis oleh PHPUnit. Selain menggunakan awalan test dalam fungsi, dalam phpunit kita juga bisa menggunakan sejenis annotation.
  • Di dalam fungsi tersebut kita menjalankan test multiplikasi 1 kali 2 sama dengan 2. Dengan menggunakan methode assertEquals, kita memerintahkan kepada phpunit untuk membuktikan bahwa hasil multiplikasi tersebut sesuai dengan expektasi kita yaitu 2. kalau tidak, maka test tersebut akan ditandai sebagai gagal. assertEquals bukan hanya satu-satunya methode pembuktian dalam PHPUnit. Ada berbagai macam methode pembuktian yang bisa digunakan sesuai kebutuhan. Seperti misalnya notequals, greaterthan, lessthan, contains, notcontains, same, notsame dan lain-lain.
  • Dalam menjalankannya kita menuliskan nama kelas dan nama file yang kita mau test. Apabila nama file kita sama dengan nama kelas, maka kita cukup menuliskan nama kelasnya. Apabila dalam satu file terdapat lebih dari satu kelas, dan kita ingin menjalankan semuanya, maka cukup dengan menuliskan nama filenya saja.
  • Untuk melengkapi contoh unit test kita, kita juga bisa menuliskan semua kemungkinan yang ingin kita test dalam satu fungsi. Meskipun begitu tehnik ini tidak begitu dianjurkan, karena apabila di tengah-tengah test tersebut gagal, maka PHPUnit tidak akan melanjutkan test berikutnya. Terkadang hal ini penting untuk membuktikan bahwa yang salah benar-benar hanya satu dan tidak lebih. Pastikan apabila melakukan unit testing, kita selalu hanya menguji satu hal. Dalam contoh disini saya sengaja membuat test ketiga salah. 3 kali 2 seharusnya 6. tapi saya mengharapkan fungsi tersebut mengembalikan angka 5
  • Setelah dijalankan bisa dilihat bahwa kita hanya mendapat informasi bahwa terdapat 1 test dan dua asersi dan satu kesalahan. Padahal sebenarnya kita memiliki 3 asersi. Asersi ketiga tidak dijalankan, karena asersi kedua sudah keburu salah. Kita bisa menghindari hal ini dengan membuat test methode untuk masing-masing asersi.
  • Dengan ini masing masing test dijalankan secara individu.
  • Disini kita bisa melihat bahwa kita memiliki 3 test dengan 3 asersi dimana dalam salah satu test tersebut terjadi kesalahan. Disini kita juga jadi bisa lebih jelas melihat bahwa test yang mendapat kesalahan adalah multiplikasi 3 dikali 2 harusnya 6 bukan 5.
  • Apabila kita ingin melihat test tersebut dengan menyatakan bahwa multiplikasi 3 dikali 2 hasilnya „bukan“ 5. maka kita bisa menggunakan methode asersi AssertNotEquals.
  • Disini kita bisa melihat bahwa semua test berjalan dengan benar.
  • Antar muka phpunit juga bisa kita modifikasi sedikit untuk membuatnya lebih informatif. Dengan parameter testdox, kita bisa membuat antar mukanya berupa check list. Ini terkadang lebih intuitiv untuk dibaca, tapi kurang efektiv kalau hanya ingin mengautomatisasi. Bayangkan kalau nanti test kalian sudah banyak sekali, gak Cuma 3 kayak disini.. Pasti akan tidak terbaca. So kita sudah melihat secara singkat phpunit in action. Keliatannya mudah sekali. Andai saja realita kehidupan nyata seperti itu. Sayangnya realitanya tidak begitu. Siapa juga yang bikin aplikasi php yang Cuma punya fungsi multiplikasi. Pastinya code kalian sangat kompleks. Mungkin seperti ini…
  • Ini saya iseng saja ambil contoh code tentang autorisasi script atau sejenisnya. Kita bisa lihat ya, dalam satu file, ada koneksi database, sql statements, html dan hal-hal sejenis. Sekarang pertanyaannya. Gimana caranya saya bikin unit testing untuk code seperti ini? Kalau mau jawaban cepat, saya jawab, ya tidak bisa. Contoh diatas memperlihatkan cukup banyak rintangan dalam menjalankan unit testing. Sebagai contoh. Dalam code tersebut terjadi komunikasi dengan database, komunikasi dengan http respons, dan html. Code tersebut tidak bisa ditest di tempat lain atau oleh orang lain tanpa mengkonfigurasi informasi tentang database terlebih dahulu. Saya akan berusaha mencoba menjelaskan tehnik utama, untuk membuat code kita dapat di test menggunakan unit testing. Saya tidak akan membahas tehnik ini satu-satu secara mendalam, karena waktunya tidak akan cukup. Maka dari itu saya biarkan definisinya tertulis dalam bahasa inggris supaya kalian yang ingin memperdalam lebih jauh bisa menggunakannya sebagai kata kunci di google atau sejenisnya.
  • Untuk membuat code tersebut diatas dapat di unit test. Kita harus merefakturisasi code kita, istilahnya refactoring. Kita harus mencoba memisahkan concern (apa itu ya.. Tujuan atau kepentingan). Sebagai contoh concern yang bisa dipisahkan dari contoh diatas adalah Database. Segala sesuatu yang berhubungan dengan database, kita bisa pisahkan. Dibuatkan kelas atau fungsi tersendiri. Segala sesuatu yang berhubungan dengan http response dipisahkan, dan segala sesuatu yang berhubungan dengan generate html dipisahkan. Pada akhirnya code tersebut akan murni melakukan tugasnya yaitu membuktikan apakah user berhak melihat content atau tidak. Kalian mungkin berpikir.. „Wah si Arthur ini.. Mau belajar unit testing, tapi core technique nya kayak gini. Kapan mulainya kalo musti belajar ini dulu.“ Sebenernya begini.. Dengan kita belajar unit testing dan berusaha membuat code kita dapat di unit test.. Kita secara otomatis juga belajar prinsip dan tehnik ini. Bukan berarti kita harus belajar tehnik dan prinsip ini dulu baru kita bisa melakukan unit testing. Silahkan mulai mencoba unit test, apabila menemui rintangan coba dipecahkan sedikit demi sedikit dengan menggunakan solusi ini. Dari pengalaman yang akan didapat, tehnik tersebut pun makin terasah. Tentunya kalau kalian sudah memahami dari awal prinsip tersebut, melakukan unit testing akan menjadi jauh lebih cepat. Saya gak akan menjelaskan lebih jauh lagi. Daripada nanti bikin bingung. Mendingan kita lihat contoh saja. Seperti yang saya bilang sebelumnya, kalian bisa memperdalam sendiri tehnik-tehnik ini. Sumber di internet sangat banyak beserta contoh-contoh. Buku-buku juga tidak sedikit. Yang penting modal bahasa inggris. Sekarang Mari kita lihat contoh code yang barusan setelah saya refakturisasi dengan tehnik dasar yang saya tulis disini.
  • Dalam contoh ini saya ingin memperlihatkan bagaimana tujuan utama (concern) dari code tersebut diimplementasikan. Pada dasarnya code tersebut hanya ingin membuktikan apakah user boleh masuk halaman ini atau tidak. Hal tersebut dilihat di methode isAuthorize. Disini kita tidak melihat lagi koneksi database, response header, atau output html. Concern tersebut sudah saya pisahkan. Komunikasi dengan object atau sistim lain, dalam hal ini akses data dan session handling, hanya sebatas kontrak, atau nota kesepahaman hehehe.. Implementasi sesungguhnya pun dia tidak tahu dan memang tidak perlu tahu. Apakah akses data menggunakan mysql, oracle atau database lain.. Dia tidak peduli.. Apakah session handling menggunakan file system, atau database Dia juga tidak peduli. implementasi ini tidak hanya memudahkan kita, bahwa yang kita mau unit test menjadi lebih jelas dan lebih mudah, akan tetapi juga karena interaksi atau komunikasi dengan implementasi lain hanya dalam bentuk kontrak / interface, kita jadi tidak perlu menggunakan implementasi aslinya untuk melakukan unit test. Kita bisa menggunakan object tiruan. Dalam Unit Testing istilahnya Mock atau Stub. Dan dengan adanya object tiruan ini, maka unit test yang kita lakukan terisolasi dari efek samping apapun yang datang dari luar. Mari kita lihat contohnya..
  • Biasanya barang tiruan itu kann palsu ya.. Saya kasih suffix palsu ya kelasnya…. Ini merupakan contoh kelas tiruan yang akan kita gunakan untuk membantu kita menguji kelas authorize barusan. Kelas kelas ini mengimplementasi kontrak yang digunakan juga oleh kelas authorize. Kelas aslinya tentunya memiliki logik di dalamnya dan kemungkinan besar melakukan interaksi atau komunikasi lebih lanjut dengan obyek lainnya. Akan tetapi kita tidak perduli akan hal itu. Kita hanya butuh informasi yang perlu digunakan untuk menguji kelas authorise kita. So mari kita lihat contohnya.
  • So dalam test ini kita bisa lihat bahwa objekt userpalsu dan session palsu diberikan ke kelas authorise untuk digunakan. Lalu kita menguji methode isauthorize. Dalam unit test ini saya berniat menguji if statement pertama, yaitu apabila methode isAuthenticate dari object session mengembalikan nilai false, maka methode isAuthorize akan mengembalikan nilai false. Dengan ini kita belajar melakukan unit test dalam isolasi menggunakan objekt tiruan. Tapi tentunya hanya dengan satu test ini belum semua kemungkinan yang ada dalam methode isAuthorize diuji. bagaimana apabila methode isAuthenticate dari object session mengembalikan nilai true? Ini belum kita test, dan untuk mengetest kemungkinan ini, kita harus membuat object tiruan kita bisa mengembalikan nilai sesuai yang kita mau. Misalnya begini.
  • Ini saya ambil contoh saja dimana saya mempersiapkan kelas tiruan disini hanya untuk menguji methode isAuthorize. Dengan ini maka kita bisa menguji methode kita dalam unit testing seperti ini….
  • Mungkin diantara kalian ada yang berpikir. Wah banyak sekali yang harus saya tulis. Saya harus membuat replika dari semua kelas-kelas yang berinteraksi dengan kelas yang mau saya test. Dan code untuk unit test jadi jauh lebih banyak dari code yang musti di test. Untuk mengatasi masalah seperti ini Unit Testing framework tidak hanya memberikan fasilitas untuk mengautomatisasi test. Tapi juga memberikan fasilitas dalam mengorganisir test.
  • Dengan mengorganisir unit test, maka code yang kita tulis untuk unit test tidak hanya lebih efisien, tapi juga lebih rapi dan mudah dibaca. Disini saya tuliskan beberapa fasilitas dalam PHPUnit yang dapat mempermudah hidup kita dalam ber unit testing. Saya akan coba memberikan contohnya.
  • Yang pertama istilahnya Fixtures. Fasilitas ini memberikan kita kesempatan untuk istilahnya mempersiapkan dan/atau meniadakan keadaan yang dibutuhkan oleh semua fungsi dalam kelas unit test kita. Sehingga kita gak perlu mempersiapkannya satu persatu dalam setiap fungsi. Fungsi fixtures ada dua yaitu setup dan teardown. Sesuai istilahnya yang satu mempersiapkan, yang satu lagi menghancurkan atau meniadakan. Fungsi setup akan dipanggil setiap kali sebelum unit test dijalankan, dan fungsi teardown akan dipanggil setiap kali unit test selesai dijalankan. Apabila dalam contoh saya memiliki dua (oke 3 sebenarnya) unit test. Maka fungsi setup dan teardown tersebut akan masing-masing dipanggil 3 kali. Dalam contoh diatas, saya mengalokasikan semua code yang dibutuhkan berulang kali dalam unit test saya. Ini cukup membantu membuat code saya jadi lebih efisien. Akan tetapi kadang kita juga harus mempersiapkan keadaan atau situasi yang berdampak pada seluruh code kita. Hal ini umum sekali terjadi apabila kita menggunakan Framework. Karena framework umumnya memiliki proses atau aturan tertentu dalam penulisan code yang berdampak pada keseluruhan aplikasi. Istilah ini sering kita dengar sebagai Bootstrap..
  • PHPUnit juga memberikan kita fasilitas untuk membuat bootstrap tersebut. File bootstrap tersebut akan dijalankan sebelum unit testing dijalankan. Bootstrap ini sangat membantu terutama apabila kita menggunakan framework atau library khusus.
  • Yang berikutnya adalah Stubs and Mocks Tools. Kalo kalian lihat contoh yang sebelumnya tadi. Untuk dapat menggunakan replika dari objekt-objekt yang berinteraksi dengan kelas Authorise.. Kita harus membuat kelas replika tersebut. Hal ini cukup merepotkan dan membuat code kita jadi semakin banyak. Akan tetapi dengan menggunakan PHPUnit. Kita diberikan fasilitas untuk membuat replika tersebut secara otomatis. Jadi kita gak perlu menulis kelas tiruan atau kelas palsu. Dalam contoh ini bisa dilihat bagaimana penggunaan nya. Setelah kita Menulis banyak unit test untuk sekian banyak kelas. Kita harus bisa menjalankan semua testnya dalam sekali klik, atau satu komando. Unit Testing Framework seperti PHPUnit memiliki fasilitas untuk menjalankan semua unit test tersebut sekaligus. Istilahnya Test Suite.
  • Dalam php unit ada 2 cara menggunakan test suite. Cara yang pertama adalah dengan mengumpulkannya dalam satu hirarki direktori dalam file system. Dengan memanggil direktori utamanya, phpunit akan mendeteksi semua kelas unit testing dan menjalankannya satu persatu. Cara yang lain adalah dengan menggunakan xml.
  • Dengan xml kita mendapat kesempatan untuk memberitahu phpunit, ada di directory mana saja unit test kita, atau file mana saja yang merupakan unit test.
  • Fasilitas lain yang cukup praktis dalam unit testing framework adalah code coverage. Dengan code coverage, kita bisa melihat apakah unit test yang kita tulis sudah mencakup semua code yang mau kita test. Dalam contoh diatas bisa dilihat misalnya bahwa dalam kelas yang kita test tersebut ada baris yang tidak terliput oleh unit test kita. Informasi ini memang praktis tapi tetap harus dilihat dengan bijaksana. Bukan berarti kalau unit test kita sudah mencakup semua code kita, berarti semua kemungkinan yang terjadi dalam logik semua sudah di test. Seperti misalnya kalau kita menguji fungsi multiplikasi diatas dengan hanya 2x2 = 4. maka secara code coverage fungsi tersebut sudah 100% di test. Tapi kemungkinan nya tetap belum cukup ya, karena 2+2 juga sama dengan 4. kalo kita sudah mengetest dengan beberapa multiplikasi dan nilainya cocok. Baru kita bisa yakin fungsi tersebut melakukan multiplikasi dengan benar. So.. Saya sudah memperlihatkan ke kalian Unit Testing.. Ini masih di permukaan nya saja ya, namanya juga merangkak. Kalau begitu.. Setelah selesai dari sini.. kalian akan mulai menerapkan unit test.. Tapi mulai dari mana?
  • How do we start unit test? Unit Testing termasuk thema diantara thema lain.. yang mudah sekali bikin orang patah semangat apabila dihadapi dengan kegagalan. Mengerti bagaimana menggunakan unit testing jelas gampang ya, akan tetapi merubah pola berpikir dalam mengembangkan aplikasi menggunakan unit test itu sulit sekali. Merubah pola pikir diri sendiri saja sudah susah, bagaimana merubah pola pikir satu divisi development? Yang pasti keinginan untuk berubah dan perubahan itu harus datang dari diri sendiri terlebih dahulu. Apabila kita sudah bisa merubah pola bekerja kita, maka langkah berikut bisa jadi.. merubah pola bekerja teman, tim atau perusahaan kita. Untuk meyakinkan boss teman atau client bisa dengan memperlihatkan kesuksesan hasil kerja sendiri, atau success story perusahaan lain. Disini saya kasih link tentang studi kasus. Studi kasus ini tidak spesifik pada unit testing itu sendiri melainkan lebih kepada unit testing dalam hubungannya dengan metodologi pengembangan aplikasi. Hal ini tidak masalah, karena unit testing sendiri hubungannya tidak hanya erat pada software testing tapi juga erat hubungannya dengan metodologi pengembangan aplikasi. Kita juga bisa cari teman yang pikiran dan pendapatnya sejalan dengan kita untuk memulai menerapkan perubahan dalam tim atau organisasi kita. Kalau kita sendiri memiliki kesulitan menerapkan dalam tim atau organisasi, dan punya duit lebih sedikit.. kita bisa panggil konsultan untuk membantu dan mengajari kita di awal sampai kita bisa bergerak sendiri. Dan Dalam perjalanan menuju ke perubahan ada baiknya kita menentukan tujuan yang jelas, kecil dulu tidak muluk-muluk yang penting realistis. Catat perkembangan yang terjadi dalam perubahan untuk melihat mana yang perlu diperbaiki, mana yang perlu dioptimalkan, dan mana yang sukses dijalankan. Dan tentunya gak mudah patah semangat, kalau dalam usaha pertama menerapkan unit test menghadapi kegagalan.
  • Selain mendalami dan mengimplementasikan unit testing itu sendiri, Masih ada banyak topik yang berhubungan dengan unit test atau PHPUnit sebagai unit testing framework. Topik topik atau thema ini sangat-sangat mendukung kita untuk menjalankan unit test atau test secara umum dengan lebih baik. Antara lain Test metodologi seperti Test Driven Development atau Behaviour Driven Development. Penggunaan Tools2 pendukung lain yang berguna terutama untuk proyek dan tim yang besar. Meskipun tidak jelek juga kalo dipake sendiri. Atau juga test-test lain seperti database test atau UI test yang juga merupakan salah satu fasilitas atau fungsi yang sudah disiapkan PHPUnit. Karena thema ini cukup luas dan tidak hanya menyangkut tentang Unit Testing, bagi mereka yang mungkin lebih tahu, bisa sharing di lain waktu, atau dibahas bersama-sama di milist :D . Saya juga tentunya akan tertarik mendengar pengalaman orang lain tentang unit test ya.
  • Pada akhirnya, bagaimanapun juga apa yang saya bicarakan dari tadi bukan barang baru, dan bukan saya ciptakan sendiri.. Maka dari itu disini saya tulis referensi yang saya pakai untuk membuat presentasi ini. Referensi ini tentunya juga bisa kalian pakai sendiri untuk lebih mendalami unit testing. Dan tentunya juga gak Cuma ini. Buku-buku lain yang berhubungan dengan unit testing tentunya juga bisa dipakai. Bahasanya gak harus php. Yang penting konsepnya bisa dimengerti.
  • Bagi kalian yang masih penasaran sama saya bisa kontakt saya menggunakan fasilitas yang saya tuliskan diatas. Kalo masih penasaran sama unit testing jangan datang ke saya saja, tapi ada baiknya kita bahas sama-sama di milis. Maka dari itu pertanyaan teknis yang di japri ke saya, gak mau saya jawab ya :D Pertanyaan yang di lempar ke milist.. Ya saya usahakan jawab sebisanya dan sesempetnya :D Kritik dan saran silahkan ditulis di milist saja. Jadi perbaikan juga bukan buat saya, tapi juga bisa buat yang lain. Terima Kasih buat kalian semua yang sudah rela ngedengerin saya, dan tentunya terima kasih buat om Rama atas waktu dan fasilitas webinar nya.

×