EPHPC Webinar Slides: Unit Testing by Arthur Purnama

1,419 views

Published on

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
1,419
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
25
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

EPHPC Webinar Slides: Unit Testing by Arthur Purnama

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

×