2014-02-23 68 views
3

我最近開始進行單元測試,想知道,我應該寫100%代碼覆蓋率的單元測試嗎?我應該單元測試每一段代碼

當我最終編寫比生產代碼更多的單元測試代碼時,這似乎是徒勞的。

我正在寫一個PHP Codeigniter項目,有時它似乎寫了很多代碼只是爲了測試一個小函數。

例如,這組測試

public function testLogin(){ 
    //setup 
    $this->CI->load->library("form_validation"); 
    $this->realFormValidation=new $this->CI->form_validation; 
    $this->CI->form_validation=$this->getMock("CI_Form_validation"); 
    $this->realAuth=new $this->CI->auth; 
    $this->CI->auth=$this->getMock("Auth",array("logIn")); 
    $this->CI->auth->expects($this->once()) 
        ->method("logIn") 
        ->will($this->returnValue(TRUE)); 

    //test 
    $this->CI->form_validation->expects($this->once()) 
     ->method("run") 
     ->will($this->returnValue(TRUE)); 
    $_POST["login"]=TRUE; 
    $this->CI->login(); 
    $out = $this->CI->output->get_headers(); 
    //check new header ends with dashboard 
    $this->assertStringEndsWith("dashboard",$out[0][0]); 

    //tear down 
    $this->CI->form_validation=$this->realFormValidation; 
    $this->CI->auth=$this->realAuth; 

} 
public function badLoginProvider(){ 
    return array(
     array(FALSE,FALSE), 
     array(TRUE,FALSE) 
    ); 
} 
/** 
* @dataProvider badLoginProvider 
*/ 
public function testBadLogin($formSubmitted,$validationResult){ 
    //setup 
    $this->CI->load->library("form_validation"); 
    $this->realFormValidation=new $this->CI->form_validation; 
    $this->CI->form_validation=$this->getMock("CI_Form_validation"); 

    //test 
    $this->CI->form_validation->expects($this->any()) 
     ->method("run") 
     ->will($this->returnValue($validationResult)); 
    $_POST["login"]=$formSubmitted; 
    $this->CI->login(); 
    //check it went to the login page 
    $out = output(); 
    $this->assertGreaterThan(0, preg_match('/Login/i', $out)); 

    //tear down 
    $this->CI->form_validation=$this->realFormValidation; 
} 

對於這種生產代碼

public function login(){ 
    if($this->input->post("login")){ 
     $this->load->library('form_validation'); 
     $username=$this->input->post('username'); 
     $this->form_validation->set_rules('username', 'Username', 'required'); 
     $this->form_validation->set_rules('password', 'Password', "required|callback_userPassCheck[$username]"); 
     if ($this->form_validation->run()===FALSE) { 
      $this->load->helper("form"); 
      $this->load->view('dashboard/login'); 
     } 
     else{ 
      $this->load->model('auth'); 
      echo "valid"; 
      $this->auth->logIn($this->input->post('username'),$this->input->post('password'),$this->input->post('remember_me')); 
      $this->load->helper('url'); 
      redirect('dashboard'); 
     } 
    } 
    else{ 
     $this->load->helper("form"); 
     $this->load->view('dashboard/login'); 
    } 
} 

我要去哪裏錯了?

回答

3

在我看來,測試代碼超過產品代碼是正常的。但是測試代碼往往是直截了當的,一旦你掌握了它,這就像編寫測試一樣簡單。儘管如此,如果您發現您的測試代碼太複雜,無法編寫/覆蓋生產代碼中的所有執行路徑,那麼對於某些重構來說,這是一個很好的指示器:您的方法可能太長,或者嘗試執行幾件事情,或有這麼多的外部依賴,等等...

另一點是,它是很好的測試覆蓋率高,但不需要是100%或一些非常高的數字。有時代碼中沒有任何邏輯,就像將代碼簡單地委託給其他人的代碼一樣。在這種情況下,您可以跳過測試它們並使用@codeCoverageIgnore註釋在代碼覆蓋率中忽略它們。

2

在我看來,它的邏輯是測試更多的代碼,因爲你必須測試多個場景,必須提供測試數據,你必須檢查每個案例的數據。

通常80%的測試覆蓋率是一個很好的價值。在大多數情況下,不需要測試100%的代碼,因爲您不應該測試例如setter和getter。不要只測試統計數據;)

+0

謝謝,通過不測試setter和getters去你的意思是像 公共職能foo(){ return somePrivateFoo; } – EdL

+0

是的,目標是測試你的代碼,而不是PHP,Java或任何其他編程語言,也不是測試任何框架的目標。所以測試getter和setter將測試PHP是否可以設置,獲取或返回值;)更多關於您的程序正在正確使用這些東西 – Yser

相關問題