2011-08-16 94 views
4

我正在編寫一個Zend Framework應用程序並使用PHPUnit對其進行單元測試。總的來說,事情正在順利進行,但是我對PHPUnit和代碼覆蓋率有一個小的但令人討厭的問題 - 它有時會告訴我一個特定的行沒有被測試,我不知道如何強制它被測試。如何使用PHPUnit獲得100%的代碼覆蓋率

例如,在下面的代碼中,我啓動了兩個測試:一個帶有GET請求,另一個帶有POST請求。測試通過,這一切都很好。但是,當我查看代碼覆蓋範圍時,它向我顯示「else」行未被執行。

public function editAction() 
{   
    if ($request->isPost()) { 
     // do actions related to POST 
    } else { 
     // do action related to GET 
    } 
} 

任何想法?作爲一個側面的問題,你通常堅持單元測試,直到你獲得100%的代碼覆蓋率?或者這不是很實際?

感謝長久......

+0

你可以發佈你的測試嗎? – vascowhite

回答

8

您只有意見的代碼纔是最重要的。如果代碼覆蓋率報告可能落到頭尾,則塊的右大括號將顯示爲可執行文件。尋找一個你沒有真正測試的分支。

if ($request->isPost()) { 
    if ($x < 5) { 
     return '<'; 
    } 
    elseif ($x > 5) { 
     return '>'; 
    } 
    // Do you have a test for $x == 5? 
} 

至於100%的代碼覆蓋率目標,我完全同意Bill的意見。對於我寫的一些框架類,我會努力做到100%,但我知道這並不意味着我已經真正測試過每一種可能性。通常,當我發現自己努力工作以達到100%的覆蓋率時,可能是強迫症踢入。:)

只是。 。 。一個。 。 。更多 。 。 。測試。 。 。

+0

謝謝大衛,你已經釘住了它。我真的很感謝Bill和edorian關於代碼覆蓋的觀點,然而你對'墮落到最後'的評論將幫助我指出那些注入'不可測試'的位! –

+0

在這裏添加一件事。當你使用幫助者方法改變控制流時,這種情況會發生很多,例如調用'exit()'或引發異常的方法。代碼覆蓋工具不知道該函數永遠不會將控制權返回給調用者。我將通過PHPCC提交一個針對'@ neverReturns'方法註釋的增強請求,但是我懷疑Sebastian會爲此付出代價。 –

12

我是Zend框架的項目負責人,幾年前,通過ZF 1.0的版本。我非常努力地提高所有組件的測試覆蓋率,並且我們制定了一個策略,即組件必須具有一定的最低代碼覆蓋率,以便從孵化器中採納到ZF中。

但是,您說得對,試圖從所有類的測試中獲得100%的代碼覆蓋率並不實際。 ZF的一些課程有100%的覆蓋率,但對於這些,一個或多個以下內容是真實的:

  • 該課程非常簡單。
  • 這些測試需要非凡的工作來編寫。例如。複雜的設置代碼來創建條件來鍛鍊所有不起眼的角落案例。看看我寫的Zend_Db的單元測試!雖然強迫自己測試這些角落案例是有益的,因爲我保證它會將您引導至需要修復的代碼。
  • 該類必須被重構爲更「可測試」。無論如何,這通常是件好事,因爲最終得到的OO代碼更好,耦合更少,靜態元素更少等。請參閱Zend_Log的類和測試。

但是我們也意識到100%的代碼覆蓋率有時是人爲的目標。儘管如此,測試套件可以達到較低的100%覆蓋率。而一個達到100%覆蓋率的測試套件並不一定能保證質量。

爲以下功能獲得100%的代碼覆蓋率將非常容易。但是我們測試了零除嗎?

function div($numerator, $denominator) { 
    return $numerator/$denominator; 
} 

所以,你應該使用代碼覆蓋率爲一體的測試指標,但不是終極目標。

3

如果這是所有有你的測試不是我會假設你的測試looks like Matthew described

class UserControllerTest extends Zend_Test_PHPUnit_ControllerTestCase { 
    // [...] 
    public function testSomething() 
    { 
     $this->request 
      ->setMethod('POST') 
      ->setPost(array(
       'username' => 'foobar', 
       'password' => 'foobar' 
      )); 
     $this->editAction(); 
     // assertThatTheRightThingsHappend 
    } 
} 

,並在這種情況下,我看不出有任何理由不應該很容易得到100%代碼覆蓋率。

但是:這很難測試Zend Framework控制器,並且在某些時候,您必須非常努力地將所有的應用程序邏輯從您的控制器中移出或者與之一起生活。

雖然同樣的事情不適用於你的模型。即使在採埃孚應用中,這些應該也很容易測試。

代碼覆蓋服務的目的是它告訴你代碼庫的哪些部分不是甚至執行。它不會告訴你什麼是真正測試過的,只能作爲一個「最小」來了解你的測試套件的質量(如果你不使用@覆蓋,即使這可能是你的謊言)。

簡而言之:如果您擁有大型控制器,並且不太容易更改體系結構,只需使用如此經過測試的控制器進行設置,但不會將相同邏輯應用於您的模型。 ZF中沒有任何內容可以阻止您正確測試這些內容

相關問題