2011-04-04 82 views
4

我在CakePHP中進行單元測試時遇到了一些問題,特別是在測試數據庫插入/更新時。比方說,我有一個模型,它是這樣的:測試驅動的開發 - 單元測試(在CakePHP中)

class User { 
    var $name = 'User'; 

    function updatePassword($data) { 
    return $this->updateAll($data); 
    } 
} 

class UserTestCase { 
    function testUpdatePassword() { 
    $tmpData = array(
     'User' => array(
     'password' => sha1(uniqid('', true)) //dummy pass 
    ); 

    $result = $this->User->updatePassword($tmpData); 

    $this->assertTrue($result); 
    } 
} 

我的問題是,在我的測試案例:

  • 我必須提供將通常從形式
  • 檢索到的虛擬數據
  • 虛擬數據的格式沒有考慮到實際表單數據可能不正確的事實
  • 我只測試更新是否成功:它似乎需要很多努力才能創建所有虛擬數據測試這個

這個例子似乎有點做作(I可以做在控制器的update而不必創建例如一個額外的模型法),但主要的一點是,測試更新/插入時,該數據是僞數據和從表單中檢索的數據可能會有所不同,但好處似乎並不高於成本。

您對TDD和單元測試的方法非常感謝,並且您一般會嘗試給出什麼樣的覆蓋範圍會很好。

乾杯

TDD對我
+0

我建議您閱讀一本關於此主題的書,例如:https://leanpub.com/cakephpunittesting/ – rrd 2013-04-13 12:24:57

回答

8

有人曾經說單元測試應該講一個故事。這種方法可以幫助您編寫測試,這些測試對於您正在編寫的應用程序而言是有意義的。撰寫描述性的名稱爲每個測試方法,如:

function testUpdatingInsecurePasswordShouldFail() { 
    $data = array('User' => array(
     'password' => 'password' 
    )); 
    $result = $this->User->updatePassword($data); 
    $this->assertFalse($result); 

    $data = array('User' => array(
     'password' => '' 
    )); 
    $result = $this->User->updatePassword($data); 
    $this->assertFalse($result); 
} 

已經告訴了不安全的密碼的「故事」,就可以讓新的測試通過,那麼寫的型號代碼。另一個例子:

function testUpdatingStrongPasswordShouldSucceed() { 
    $data = array('User' => array(
     // forget about hashing for the moment 
     'password' => 'battery hoarse collect maple' 
    )); 
    $this->User->updatePassword($data); 
    $result = $this->User->find('count', array(
     'conditions' => array(
      // making some assumptions about the test data here 
      'User.username' => 'test_user1', 
      'User.password' => 'battery hoarse collect maple', 
     ), 
    ); 
    $this->assertEqual($result, 1); 
} 

注意我們正在做更多的工作來驗證更新是否正常工作。當測試框架開始提取錯誤和迴歸時,您會很高興您付出了額外的努力。好的描述測試名

一邊好處是,現在我們可以使用cake test --testdox選項輸出的結果可以理解英語:

[x] Updating insecure password should fail 
[x] Updating strong password should succeed 
3

利益(一旦你完全讓你的頭包裹着它):

  1. 我可以調試我的代碼,而無需瀏覽器
  2. 如果我的代碼是依賴於各種部分代碼和我(或其他人)做了一個意外的改變,意外地破壞了我以前測試過的東西,我的自動化單元測試將立即捕捉到這個結果
  3. (個人)它改變了我對輸入的想法 - 而不是輸入g數據手動轉換爲文本字段,我發現自己開始考慮可能來自腳本而不是瀏覽器的輸入 - 真的讓我專注於清理輸入更多
  4. 自動化測試 - 一旦系統完成,我就可以運行所有我的測試,並讓他們在幾秒鐘內執行,以確保一切正常,而不是嘗試手動運行整個系統,這可能需要幾個小時,這取決於複雜性。
2

ddawber,

你提三點:

1.

我必須提供虛擬數據, 通常會從 形式

檢索您應該看一看到CakePHP的fixtures

2.

虛擬數據 的格式不考慮到這樣的事實 是實際表格數據可能是 不正確

表格數據根據模型的驗證規則see here進行驗證。

3.

我只測試 更新是否成功:好像努力了很多 創建的所有虛擬數據 測試這個

這應該然後簡單地通過編寫一個測試方法來解決(並且只挑選相關案例),考慮1.和2.。 也許您對事實感興趣,即CakePHP開發人員可以在2.0版本中從simpletest切換到phpunit,這可以幫助您規劃您的工作。

無論如何,我們都可以輕鬆進入CakePHP的測試工具。

編輯0: 代碼覆蓋的第四點似乎有爭議。如果你想達到100%的覆蓋率,你必須寫很多模擬對象,只是爲了確保控制器的行爲在你調用它時被實際調用。寫這樣的東西對於框架開發者來說是一項任務,省略編寫這種多餘的代碼直接影響了代碼覆蓋率。

+0

+1 for fixtures – kaklon 2011-10-11 14:14:26