PHPUnit 簡介

Outline

  • Unit Test
  • PHPUnit
  • Devel Notes

Unit Test

  • Find problems earlier
  • Facilitates change
  • Simplifies integration

PHPUnit

  • Test Case & Assertion
  • Dependency
  • Expected Exception
  • DB Testing
  • Test Doubles
  • Coverage Analysis

Test Case & Assertion

myTest.php


class MyTest extends PHPUnit_Framework_TestCase{

  function testSomething(){

    $this->assertTrue($user->hasEmail());
    $this->assertEquals('expected', $outputString);
    $this->assertArrayHashKey('expectedKey', $resultArray);
  }
}
         

Dependency


function testOne(){ }

/**
 * @depend testOne
 */
function testTwo(){ }
         

Excepted Exception


function testGeneral(){
  $this->assertTrue(true); // assert success
}

/**
 * @expectedException Exception
 */
function testException(){
  $this->assertTrue(true); // assert faied
}

/**
 * @expectedException Exception
 */
function testException2(){
  throw new Exception();  // assert success
}
         

Fixtures

  • Building test environment
  • Invoke before/after each test

 class SomeTest extends PHPUnit_Framework_TestCase {
    private $config;

    protected function setUp(){
       echo "setting up ...\n";
       $this->config = array('some config');
    }

    protected function tearDown(){
       echo "tearing down ...\n";
       $this->config = null;
    }

    public function testSomething(){
       $this->assertTrue(true);
    }

    public function testSomethingElse(){
       $this->assertTrue(true);
    }
 }
          

$ phpunit SomeTest.php
PHPUnit 3.4.5 by Sebastian Bergmann.
 
setting up ...
tearing down ...
.setting up ...
tearing down ...
.
 
Time: 0 seconds, Memory: 7.75Mb
            

Database Testing

  • Testing Steps
  • DataSet

Testing Steps

  1. Clean Up
  2. Set Up
  3. Run Test
  4. tearDown

DataSet


<?xml  version="1.0" encoding="UTF-8" ?>
<dataset>
  <user id="1" username="test" password="" />
  <user id="2" username="test2" password="123" />
</dataset>
            

 


function testDataSet(){
  $this->createFlatXMLDataSet('dataset.xml')->getTable('user');
}
            

Test Doubles


class Greetings {
  function show($user){
    echo 'Hello, ' . $user->getName();
  }
}
         

function testGreetings(){
  $fakeUser = $this->getMock('User')

  $fakeUser->expects($this->any())
           ->method('getName')
           ->will($this->returnValue('Zero'));

  (new Greetings)->show($fakeUser);  // 'Hello, Zero'
         

Coverage Analysis

Devel Notes

  • Prevent from 'static', 'final', private'
  • Prevent Complex Condition
  • Prevent Global Flag
  • Dependency Injection
  • Be Aggressive

Prevention

  • static, final, private
  • Complex Condition
  • Global Flag

static, final, private


class Worker {
  static function foo(){ }

  final function bar(){ }

  private function foobar(){ }
}
                 

Complex Condition


if(){
  if(){
    if(){
      if(){
        if(){
        }else{
        }
      }else{
      }
    }else{
    }
  }else{
  }
}else{
}
                  

Condition = 2 ^ 5 = 32

Global Flag


function addUser(){
  global $list;
  $db->execute(SQL_INSERT, $list);
}
                

 


// In C, maybe 
#define  if(  if(!
                

Dependency Injection


class Job {
  function execute(){
    //do something;
    (new Logger)->log(DATA);
  }
}

(new Job)->execute();  // Logger can not be mocked
        

class Job {
  function __constructor($logger){
    $this->logger = $logger;
  }

  function execute(){
    // do something
    $this->logger->log(DATA);
  }
}

(new Job(new Logger) )->execute();
        

Be Aggressive

 

Adder(int, int):

  • 1 + 1
  • "1" + 1
  • 2147483648 + 2147483648

x32


$ php -r "echo (int)2147483648 + (int)2147483648;"
-4294967296
        

 

x64


$ php -r "echo (int)2147483648 + (int)2147483648;"
4294967296
        

Q & A

 

騙你的

後面還有 XD

Reference