practical approach for testing your software with php unit

52
Practical Approach for testing your software with PHPUnit Mario Bittencourt

Upload: mario-bittencourt

Post on 06-Jul-2015

184 views

Category:

Technology


0 download

DESCRIPTION

Practical approach for testing software using PHPUnit

TRANSCRIPT

Page 1: Practical approach for testing your software with php unit

Practical Approach for testing your software with PHPUnit

Mario Bittencourt

Page 2: Practical approach for testing your software with php unit

Agenda

Current situation

PHPUnit as part of the solution

Best Practices

Page 3: Practical approach for testing your software with php unit

Current situation

Page 4: Practical approach for testing your software with php unit

Complexity, dependencies and pace over time

Page 5: Practical approach for testing your software with php unit

Software Development Life Cycle

Page 6: Practical approach for testing your software with php unit

Testing

Tedious

Can only cover a small subset of the use cases

Takes a lot of time

Change the code to test it

Page 7: Practical approach for testing your software with php unit

Automation is key

Goal is to create tests that can be executed automatically to verify that the expected behaviour is met

Page 8: Practical approach for testing your software with php unit

PHPUnit as part of the solution

Page 9: Practical approach for testing your software with php unit

Example

class Account

{

protected $balance;

public function __construct($initialAmount)

{

$this->balance = $initialAmount;

}

public function getBalance()

{

return $this->balance;

}

public function deposit($amount)

{

$this->balance += $amount;

}

}

Page 10: Practical approach for testing your software with php unit

Unit Test

class AccountTest extends PHpUnit_Framework_TestCase{

public function testDepositIncreasesBalance(){

$account = new Account(10);$account->deposit(1);$this->assertEquals(11, $account->getBalance());

}}

Page 11: Practical approach for testing your software with php unit

Unit Test

PHPUnit 4.3.1 by Sebastian Bergmann.

Account

[x] Deposit increases balance

Page 12: Practical approach for testing your software with php unit

Best Practices

Page 13: Practical approach for testing your software with php unit

Give meaningful names to your tests

public function testDeposit() {

$account = new Account(10);$account->deposit(1);$this->assertEquals(

11,$account->getBalance()

);}

DON’T

Page 14: Practical approach for testing your software with php unit

Give meaningful names to your tests

PHPUnit 4.3.1 by Sebastian Bergmann.

Account

[ ] Deposit

Page 15: Practical approach for testing your software with php unit

Give meaningful names to your tests

public function testDepositIncreaseBalance() {

$account = new Account(10);$account->deposit(1);$this->assertEquals(

11,$account->getBalance()

);}

Page 16: Practical approach for testing your software with php unit

Use the most specific assertion available

public function testDepositIncreasesBalance(){

$account = new Account(10);$account->deposit(10);$this->assertGreaterThan(

10,$account->getBalance());

}

DON’T

Page 17: Practical approach for testing your software with php unit

Use the most specific assertion available

public function testDepositIncreasesBalance(){

$account = new Account(10);$account->deposit(10);$this->assertEquals(20, $account->getBalance());

}

Page 18: Practical approach for testing your software with php unit

Use the most specific assertion available

public function deposit($amount){

$this->balance += $amount;

if ($amount >= 10) {$this->balance += 1;

}

return true;}

Page 19: Practical approach for testing your software with php unit

Use the most specific assertion available

There was 1 failure:

1) AccountTest::testDepositIncreasesBalanceFailed asserting that 21 matches expected 20.

AccountTest.php:14

Page 20: Practical approach for testing your software with php unit

Don’t forget about protectedmethods

class Account{

public function deposit($amount){

if ($this->validateAmount($amount)) {$this->balance += $amount;

} else {throw new Exception('Invalid amount');

}}

}

Page 21: Practical approach for testing your software with php unit

Don't forget about your protected methods

protected function validateAmount($amount){

if ($amount < 0) {return false;

} else {return true;

}}

Page 22: Practical approach for testing your software with php unit

Don't forget about your protected methods

public function testValidateAmountWithNegativeIsFalse(){

$account = new Account(10);$this->assertFalse($account->validateAmount(-1));

}

Fatal error: Call to protected method Account::validateAmount()

Page 23: Practical approach for testing your software with php unit

Don't forget about your protected methods

public function testValidateAmountWithNegativeIsFalse(){

$account = new Account(10);$reflection = new ReflectionObject($account);$method = $reflection->getMethod('validateAmount');$method->setAccessible(true);$this->assertFalse(

$method->invokeArgs($account, array(-1)));

}

Page 24: Practical approach for testing your software with php unit

Don't forget about your protected methods

PHPUnit 4.3.1 by Sebastian Bergmann.

Account

[x] Deposit increases balance

[x] Validate amount with negative is false

Page 25: Practical approach for testing your software with php unit

Test just one thing at a time

public function deposit($amount){

if ($amount == 0) {return false;

}$this->balance += $amount;return true;

}

Page 26: Practical approach for testing your software with php unit

Test just one thing at a time

public function testDepositIncreasesBalance(){

$account = new Account(10);$this->assertTrue($account->deposit(1));$this->assertEquals(11, $account->getBalance());

$this->assertFalse($account->deposit(0));}

Page 27: Practical approach for testing your software with php unit

Test just one thing at a time

PHPUnit 4.3.1 by Sebastian Bergmann.

.

Time: 35 ms, Memory: 3.00Mb

OK (1 test, 3 assertions)

Page 28: Practical approach for testing your software with php unit

Test just one thing at a time

public function deposit($amount){

if ($amount < 0) {return false;

}$this->balance += $amount;return true;

}

NEW CRITERIA

Page 29: Practical approach for testing your software with php unit

Test just one thing at a time

PHPUnit 4.3.1 by Sebastian Bergmann.

There was 1 failure:

1) AccountTest::testDepositIncreasesBalance

Failed asserting that true is false.

AccountTest.php:15

FAILURES!

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

Page 30: Practical approach for testing your software with php unit

Test just one thing at a time

public function testDepositIncreasesBalance(){$account = new Account(10);$this->assertTrue($account->deposit(1));$this->assertEquals(11, $account->getBalance());}

public function testDepositWithNegativeShouldReturnFalse(){

$account = new Account(10);$this->assertFalse($account->deposit(-1));

}

Page 31: Practical approach for testing your software with php unit

Test just one thing at a time

PHPUnit 4.3.1 by Sebastian Bergmann.

..

Time: 49 ms, Memory: 3.00Mb

OK (2 tests, 3 assertions)

Page 32: Practical approach for testing your software with php unit

Use Data Providers for repetitive tests

class Score{

protected $score;

public function update($balance, $numberCc, $amountInLoans)

{// do something ...return $newScore;

}}

Page 33: Practical approach for testing your software with php unit

Use Data Providers for repetitive tests

class ScoreTest extends PHpUnit_Framework_TestCase{

public function testScoreSomething1(){

$score = new Score(10);$this->assertEquals(300, $score->update(100, 0, 1));

}

public function testScoreSomething2(){

$score = new Score(10);$this->assertEquals(99, $score->update(100, 1, 2));

}}

Page 34: Practical approach for testing your software with php unit

Use Data Providers for repetitive tests

/*** @dataProvider scoreProvider*/public function testScore($balance, $numberCc, $amountInLoans, $expectedScore){

$score = new Score(10);$this->assertEquals(

$expectedScore, $score->update($balance, $numberCc, $amountInLoans)

);}

Page 35: Practical approach for testing your software with php unit

Use Data Providers for repetitive tests

public function scoreProvider(){

return array(array(100, 0, 1, 300),array(100, 1, 2, 99),

);}

Page 36: Practical approach for testing your software with php unit

Use Data Providers for repetitive tests

PHPUnit 4.3.1 by Sebastian Bergmann.

..

Time: 25 ms, Memory: 3.00Mb

OK (2 tests, 2 assertions)

Page 37: Practical approach for testing your software with php unit

Isolate your test

public function wire($amount, SwiftInterface $targetBank){

if ($targetBank->transfer($amount)) {$this->balance -= $amount;return true;

} else {return false;

}}

Page 38: Practical approach for testing your software with php unit

Isolate your test

class Hsbc implements SwiftInterface {public function transfer($amount){

// slow method}

}

Page 39: Practical approach for testing your software with php unit

Isolate your test

public function testWireTransferShouldReturnTrueIfSuccessful(){

$account = new Account(10);$bank = new Hsbc();$this->assertTrue($account->wire(5, $bank));

}

Page 40: Practical approach for testing your software with php unit

Isolate your test

public function testWireTransferShouldReturnFalseIfFailed(){

// how to fail?$account = new Account(10);$bank = new Hsbc();$this->assertFalse($account->wire(5, $bank));

}

Page 41: Practical approach for testing your software with php unit

Isolate your test

public function testWireTransferShouldReturnTrueIfSuccessful(){

$account = new Account(10);$bank = $this->getMock(‘Hsbc');$bank->expects($this->any())

->method('transfer')->will($this->returnValue(true));

$this->assertTrue($account->wire(5, $bank));}

Page 42: Practical approach for testing your software with php unit

Isolate your test

public function testWireTransferShouldReturnFalseIfFailed(){

$account = new Account(10);$bank = $this->getMock('Hsbc');$bank->expects($this->any())

->method('transfer')->will($this->returnValue(false));

$this->assertFalse($account->wire(5, $bank));}

Page 43: Practical approach for testing your software with php unit

Specify what you are testing with @covers

Use --coverage-html to generate the code coverage report of your code

Page 44: Practical approach for testing your software with php unit

Specify what you are testing with @covers

Page 45: Practical approach for testing your software with php unit

Specify what you are testing with @covers

class Exchange {public function convert($amountUsd, $targetCurrency){

// Do some conversion}

}

Page 46: Practical approach for testing your software with php unit

Specify what you are testing with @covers

public function convertBalance($targetCurrency){

$exchange = new Exchange();return $exchange->convert($this->balance, $targetCurrency);

}

Page 47: Practical approach for testing your software with php unit

Specify what you are testing with @covers

public function testConvertBalance(){

$account = new Account(10);$this->assertLessThan(

10, $account->convertBalance('GBP'));

}

Page 48: Practical approach for testing your software with php unit

Specify what you are testing with @covers

Page 49: Practical approach for testing your software with php unit

Specify what you are testing with @covers

Page 50: Practical approach for testing your software with php unit

Specify what you are testing with @covers

/**

* @covers Account::convertBalance

*/

public function testConvertBalance(){…

}

Page 51: Practical approach for testing your software with php unit

Specify what you are testing with @covers

Page 52: Practical approach for testing your software with php unit

That is all folks!

Contacts

Twitter - @bicatu

Email – [email protected]

https://joind.in/12279

http://slidesha.re/1xtcT4y