是PHP的單元測試架構。單元測試在軟體開發中越來越受到重視,測試先行程式設計、極限程式設計和測試驅動開發在實踐中被廣泛。利用單元測試,也可以實作契約式設計。
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5CM4UGZkRmZ4cjZwImY4MjYzgzY0YDOmNmMhJzNlFWY48CX5d2bs92Yl1iclB3bsVmdlR2LcNWaw9CXt92Yu4GZjlGbh5yYjV3Lc9CX6MHc0RHaiojIsJye.png)
接下來,我們通過一個例子說明如何利用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);