天天看點

PHPUnit manual

第一章  測試自動化

優秀的程式員也會犯錯。好程式員與壞程式員的差别在于好程式員借助測試來盡快的發現錯誤。對于一個錯誤,你測試的越早,你發現它的可能行就越大,你用來找到并修正它的代價也就越小。這也解釋了為什麼在軟體釋出之前才進行測試是有很大問題的。大部分的錯誤你根本不會捕捉到,而對于那些你捕捉到的bug,由于修複這些bug的成本是如此之高,以緻你不得不對錯誤進行篩選,因為你不可能将它們全部修複。

與你應該已經在做的事情相比,使用PHPUnit來進行測試并非是一個完全不同的活動。它隻不過是換了一種方式。其測試方法的獨特之處在于,檢查你的程式以期望的方式運作,運作一組測試用例,即可運作的代碼片段來自動的測試軟體部件(單元)的正确性。這些可運作的代碼片段被稱作單元測試。

在此章中,我們将從簡單的列印語句為基礎的測試代碼過渡到全自動測試。假設我們被要求測試PHP的内建數組(array)。需要測試的功能之一是count()函數。對于一個新建立的數組我們期望count()函數傳回值為0。當我們增加一個元素後,count()應該傳回1。Example 1.1中展示了我們想測的東西。

Example 1.1: Testing array operations

<?php
$fixture = array();
// $fixture is expected to be empty.
 
$fixture[] = 'element';
// $fixture is expected to contain one element.
?>
           

測試結果是否如我們所想的一個非常簡單的方法是,将count()在增加元素之前和之後的結果列印出來。如果分别達到0和1,那麼array和count()正如我們所期待的。

Example 1.2: Using print to test array operations

<?php
$fixture = array();
print count($fixture) . "\n";
 
$fixture[] = 'element';
print count($fixture) . "\n";
?>
           
0
1
           

現在,我們将需要手動參與的測試用例進化為自動運作的測試。在Example 1.3中,我們在測試代碼中加入了期望值與實際值的比較。如果二者相等,将列印ok, 否則輸出not ok, 這樣一來,我們就知道某些地方出問題了。

Example 1.3: Comparing expected and actual values to test array operations

<?php
$fixture = array();
print count($fixture) == 0 ? "ok\n" : "not ok\n";
 
$fixture[] = 'element';
print count($fixture) == 1 ? "ok\n" : "not ok\n";
?>
           
ok
ok
           

下一步,我們将期望值與實際值的比較提取出來,放在一個函數中,當二者不一緻時,抛出異常。如此一來有兩個好處:寫測試用例變得更簡單,并且隻有在出錯時才會有輸出。

Example 1.4: Using an assertion function to test array operations

<?php
$fixture = array();
assertTrue(count($fixture) == 0);
 
$fixture[] = 'element';
assertTrue(count($fixture) == 1);
 
function assertTrue($condition)
{
    if (!$condition) {
        throw new Exception('Assertion failed.');
    }
}
?>
           

這個測試現在完全自動化了。對比第一個版本,我們僅僅進行了測試,這個版本我們有了一個自動測試。

使用自動測試的目标是制造更少的錯誤。雖然有了精彩的測試之後,你的代碼仍然不完美,但是你将會發現自從使用自動測試後,缺陷激動人心的減少。自動測試會讓你對代碼有理性的自信。有了這自信,你可以更大膽的修改設計(重構),與你的組員相處的更好(跨組測試),改善與客戶的關系,在每天晚上回家之前有了證據證明系統比早上時更好了,因為有了你的努力。