unit_testing.pdf

Post on 28-Aug-2014

54 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

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

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

Tujuan

Memperkenalkan Unit Testing

Mendorong atau memotivasi penggunaan

Unit Testing

Memperkenalkan Unit Testing Framework

PHPUnit

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

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

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.

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;

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.

Kelebihan Unit Testing

Menjadi bagian dari dokumentasi code

Mempermudah Integrasi antar komponen

Meningkatkan kualitas code

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

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

Unit Testing Framework

PHPUnit

Unit Testing Framework

Ditulis oleh Sebastian Bergmann

De facto standard untuk PHP

Banyak didukung oleh Tools dan Framework lain

Contoh Unit Testing Multiplikasi

<?php

//MultiplikasiTest.php

require_once 'multiplikasi.php';

class BelajarUnitTest extends PHPUnit_Framework_TestCase{

}

?>

Contoh Unit Testing Multiplikasi

<?php

//MultiplikasiTest.php

require_once 'multiplikasi.php';

class BelajarUnitTest extends PHPUnit_Framework_TestCase{

//Nama fungsi menggunakan awalan “test“

public function testMultiplicate(){

}

}

?>

Contoh Unit Testing Multiplikasi

<?php

//MultiplikasiTest.php

require_once 'multiplikasi.php';

class BelajarUnitTest extends PHPUnit_Framework_TestCase{

//Nama fungsi menggunakan awalan “test“

public function testMultiplicate(){

$this->assertEquals(2, multiplicate(1, 2));

}

}

?>

Contoh Unit Testing Multiplikasi

$>phpunit BelajarUnitTest MultiplikasiTest.php

PHPUnit 3.5.12 by Sebastian Bergmann.

.

Time: 0 seconds, Memory: 3.00Mb

OK (1 test, 1 assertion)

Contoh Unit Testing Multiplikasi

<?php

//MultiplikasiTest.php

require_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));

}

}

?>

Contoh Unit Testing Multiplikasi

$>phpunit BelajarUnitTest MultiplikasiTest.php

PHPUnit 3.5.12 by Sebastian Bergmann.

F

Time: 0 seconds, Memory: 3.00Mb

There was 1 failure:

1) BelajarUnitTest::testMultiplicate

Failed asserting that <integer:6> matches expected <integer:5>.

$\MultiplikasiTest.php:10

FAILURES!

Tests: 1, Assertions: 2, Failures: 1.

Contoh Unit Testing Multiplikasi

<?php

//MultiplikasiTest.php

require_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));

}

}

?>

Contoh Unit Testing Multiplikasi

$>phpunit MultiplikasiTest.php

PHPUnit 3.5.12 by Sebastian Bergmann.

.F.

Time: 0 seconds, Memory: 3.00Mb

There was 1 failure:

1) BelajarUnitTest::testMultiplicate3And2

Failed asserting that <integer:6> matches expected <integer:5>.

$\MultiplikasiTest.php:12

FAILURES!

Tests: 3, Assertions: 3, Failures: 1.

Contoh Unit Testing Multiplikasi

<?php

//MultiplikasiTest.php

require_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));

}

}

?>

Contoh Unit Testing Multiplikasi

$>phpunit BelajarUnitTest MultiplikasiTest.php

PHPUnit 3.5.12 by Sebastian Bergmann.

...

Time: 0 seconds, Memory: 3.00Mb

OK (3 tests, 3 assertions)

Contoh Unit Testing Multiplikasi

$>phpunit --testdox BelajarUnitTest MultiplikasiTest.php

PHPUnit 3.5.12 by Sebastian Bergmann.

BelajarUnitTest

[x] Multiplicate 1 and 2

[x] Multiplicate 3 and 2

[x] Multiplicate 2 and 2

Tapi.. Code saya seperti ini..

<?php

// Connects to your Database

mysql_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 in

if (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" );

}

?>

Core techniques

Refactoring

Separation of Concern

Inversion of Control (Dependency Injection)

Design by Contract

Design Patterns

Contoh Refactoring

<?php

namespace myapp\security;

use myapp\daos\interfaces\User;

use myapp\util\interfaces\Session;

class Authorize implements interfaces\Authorize{

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;

}

}

}

?>

Mocks & Stubs

<?php

namespace myapp\mocks;

use myapp\daos\interfaces\User;

class UserPalsu implements User{

public function getById($id){

return null;

}

public function getByUsername($username){

return null;

}

public function getAll(){

return null;

}

}

?>

<?php

namespace myapp\mocks;

use myapp\util\interfaces\Session;

class SessionPalsu implements Session{

public function getUsername(){

return null;

}

public function getPassword(){

return null;

}

public function isAuthenticate(){

return false;

}

}

?>

Unit Test Authorize

<?php

use myapp\security\Authorize;

use myapp\mocks\SessionPalsu;

use myapp\mocks\UserPalsu;

class AuthorizeTest extends PHPUnit_Framework_TestCase {

public function testIsAuthorizeSessionNotAuthenticate(){

$userDAO = new UserPalsu();

$session = new SessionPalsu();

$authorize = new Authorize($userDAO, $session);

$this->assertFalse($authorize->isAuthorize());

}

}

?>

Mocks & Stubs

<?php

namespace myapp\mocks;

use myapp\models;

use myapp\daos\interfaces\User;

class UserPalsu implements User{

private $user;

public function getById($id){

return null;

}

public function getByUsername($username){

return $this->user;

}

public function getAll(){

return null;

}

public function

setUser(models\interfaces\User $user){

$this->user = $user;

}

}

?>

<?php

namespace myapp\mocks;

use myapp\util\interfaces\Session;

class SessionPalsu implements Session{

private $username;

private $password;

private $authenticate;

public function getUsername() {

return $this->username;

}

public function setUsername($username) {

$this->username = $username;

}

public function getPassword() {

return $this->password;

}

public function setPassword($password) {

$this->password = $password;

}

public function isAuthenticate(){

return $this->authenticate;

}

public function setAuthenticate($authenticate){

$this->authenticate = $authenticate;

}

}

?>

Unit Test Authorize

<?php

use myapp\models\User;

use myapp\security\Authorize;

use myapp\mocks\SessionPalsu;

use myapp\mocks\UserPalsu;

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());

}

}

?>

Mengorganisir Unit Test

Fixture

Bootstrap

Stubs & Mocks Tools

Test Suite

Code Coverage

Fixtures

<?php

use myapp\models\User;

use myapp\security\Authorize;

use myapp\mocks\SessionPalsu;

use myapp\mocks\UserPalsu;

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());

}

}?>

Bootstrap

<phpunit bootstrap="/path/to/bootstrap.php"

colors="false"

convertErrorsToExceptions="true"

convertNoticesToExceptions="true"

convertWarningsToExceptions="true"

stopOnFailure="true">

<!-- ... -->

</phpunit>

Stubs and Mocks Tools

<?php

use myapp\security\Authorize;

class AuthorizeTest extends PHPUnit_Framework_TestCase {

private $userDAO;

private $session;

public function setUp() {

$this->userDAO = $this->getMock ( '\myapp\daos\User' );

$user = $this->getMock ( 'myapp\models\User', 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 ( '\myapp\util\Session', 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 () );

}

}

?>

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 Tests

PHPUnit 3.5.13 by Sebastian Bergmann.

............................................................ 60 / 75

...............

Time: 0 seconds

OK (75 tests, 164 assertions)

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>

Code Coverage

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

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

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

Web: http://arthur.purnama.de

Mail: arthur [at] purnama.de

Twitter: @purnama

Groups:

phpug@yahoogroups.com

Id-php@yahoogroups.com

top related