天天看點

phpunit PHP單元測試的利器

PHPUnit

是PHP的單元測試架構。單元測試在軟體開發中越來越受到重視,測試先行程式設計、極限程式設計和測試驅動開發在實踐中被廣泛。利用單元測試,也可以實作契約式設計。

phpunit PHP單元測試的利器

接下來,我們通過一個例子說明如何利用PHPUnit來實踐測試驅動開發。

假設我們需要編寫一個銀行賬戶的功能:

BankAccount

。該功能用于設定銀行賬戶收支,存取現金,必須確定:

  • 銀行賬戶初始化時餘額為0。
  • 餘額不能為負數。

在編寫代碼之前,我們先為

BankAccout

類編寫測試:

require_once 'BankAccount.php';

class BankAccountTest extends PHPUnit_Framework_TestCase

{

    protected $ba;

    protected function setUp()

    {

        $this->ba = new BankAccount;

    }

    public function testBalanceIsInitiallyZero()

        $this->assertEquals(0, $this->ba->getBalance());

    public function testBalanceCannotBecomeNegative()

        try {

            $this->ba->withdrawMoney(1);

        }

        catch (BankAccountException $e) {

            $this->assertEquals(0, $this->ba->getBalance());

            return;

        $this->fail();

    public function testBalanceCannotBecomeNegative2()

            $this->ba->depositMoney(-1);

}

現在我們編寫為了讓第一個測試

testBalanceIsInitiallyZero()

通過所需要的代碼:

class BankAccount

    protected $balance = 0;

    public function getBalance()

        return $this->balance;

現在第一個測試可以通過了,第二個還不行:

phpunit BankAccountTest

PHPUnit 3.7.0 by Sebastian Bergmann.

.

Fatal error: Call to undefined method BankAccount::withdrawMoney()

為了讓第二個測試通過,我們需要實作

withdrawMoney()

depositMoney()

setBalance()

方法。這些方法在違反限制條件時,會抛出一個

BankAccountException

    protected function setBalance($balance)

        if ($balance >= 0) {

            $this->balance = $balance;

        } else {

            throw new BankAccountException;

    public function depositMoney($balance)

        $this->setBalance($this->getBalance() + $balance);

        return $this->getBalance();

    public function withdrawMoney($balance)

        $this->setBalance($this->getBalance() - $balance);

現在第二個測試也能通過啦~

...

Time: 0 seconds

OK (3 tests, 3 assertions)

你也可以使用契約式設計的風格,隻需使用

PHPUnit_Framework_Assert

類提供的靜态斷言方法編寫契約條件。下面例子中,如果斷言不成立,就會抛出一個

PHPUnit_Framework_AssertionFailedError

。這種方式可以增加你的代碼的可讀性。但是這也意味着你需要PHPUnit會成為你的運作時依賴。

    private $balance = 0;

        PHPUnit_Framework_Assert::assertTrue($balance >= 0);

        $this->balance = $balance;

    public function depositMoney($amount)

        PHPUnit_Framework_Assert::assertTrue($amount >= 0);

        $this->setBalance($this->getBalance() + $amount);

    public function withdrawMoney($amount)

        PHPUnit_Framework_Assert::assertTrue($this->balance >= $amount);

        $this->setBalance($this->getBalance() - $amount);