使用TDD來改善你的代碼質量

做爲一名開發人員,咱們常常會聽到這樣一句忠告:"在開發軟件時編寫寫測試代碼(單元測試,功能測試等)能有效的減小產品中的bug",如何來驗證這種言論呢,最大的驗證案例應該就是TDD(測試驅動開發),下面本文將經過TDD這種開發技術來改進你的代碼質量和穩定性php

(1、)什麼是TDD

測試驅動開發(Test Driven Development)簡稱TDD,最初概念始於1993年,於2003年興起,逐漸被大衆接受。編程

TDD是一種軟件開發理念,與極限編程概念相似「測試優先」,能夠經過3個步驟來學習到TDD的開發法則.安全

  1. 將需求轉換具體的測試用例
  2. 對軟件需求進行編碼&&編寫經過測試用例
  3. 對軟件代碼進行重構,消除冗餘代碼

每次有需求變動或者功能增長,可重複循環這3個步驟來完善你的代碼,使它最大化減小錯誤率,也是一個完整的TDD開發週期函數

(2、)TDD的好處

TDD的優勢不少,一下列舉了我的認爲比較重要的一些單元測試

  1. 任務分解,開發人員更瞭解用戶:一般開發人員在編寫業務的時候,大多數只會考慮到Input與Output,並無轉換到用戶的角度去思考產品(面向用戶編程),經過TDD,開發人員會更加站在用戶角度思考,會深度考慮用戶可能進行的全部操做,而不是站在開發者角度想用戶應該會如何去使用咱們的產f品.
  2. 測試用例覆蓋率高,Bug減小:使用TDD的開發過程當中,由於須要先編寫測試,而後才能開始業務需求編碼,當全部測試經過後,開發人員才能提交代碼,這樣會使得軟件代碼測試覆蓋很是高,測試覆蓋率高同時也代表代碼是通過充分測試的,這樣才正式環境運行遇到BUG也會相對少不少。
  3. 更清晰整潔的代碼:在TDD的開發過程當中,咱們在不斷重構代碼,消除很差的代碼,這會讓咱們的代碼變得更加整潔和高效,從而改善優化咱們的軟件駕考,讓項目變得更加靈活易擴展。
  4. 更安全的重構:重構改變的是代碼的內部結構,而不會改變外部接口功能,因爲代碼的測試覆蓋率高,因爲代碼的測試覆蓋率高,每一個功能都有對應的測試代碼,開發人員能夠更大膽進行重構,由於有充分的測試代碼,當咱們重構時,若是破壞了原有的功能,測試就會立刻失敗。
  5. 更好的信心,由於存在大量測試用例,你不用擔憂每次提交的新代碼都會影響到項目中以前的服務運行,每次運行測試用例便可檢測到你的代碼是否會影響到原來系統的運行,極大提升了開發者的自信。

(3、)實現第一個簡單的TDD

下面將經過PHP代碼來展現一個簡單的小案例,將輸入的金幣兌換成餘額,餘額只保留整數,餘額不可爲負數學習

1.編寫測試用例

按照預期結果去編寫自動化參數的測試用例.測試

<?php

namespace Tests\Feature;

use App\Exchange;
use Tests\TestCase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;

class ExchangeTest extends TestCase
{
    public function exchangeBalance()
    {
        $gold = mt_rand(1,100000);  //隨機輸入金幣
        $balance = Exchange::computeAmount($gold);  //計算兌換金額;
        //斷言結果是否爲整數餘額
        $this->assertTrue($balance);
    }
}

此時咱們當即運行該測試用例是失敗的,由於業務需求還沒實現,下面須要到咱們的第二步.優化

2.編寫業務代碼實現

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Exchange extends Model
{

    const RATE = 600;

    public static function computeAmount($gold)
    {
        return intval($gold / self::RATE);
    }

}

3.運行測試

測試1:
    Command: run ExchangeTest
    自動化參數:3000
    運行返回結果:5
    
測試2:
    Command: run ExchangeTest
    自動化參數:-3000
    運行返回結果:-5

運行ExchangeTest測試用例,發現此次雖然返回了兌換後的餘額,第一次運行成功,第二次運行失敗,由於不符合第二項不可出現爲負數的結果.this

4.改進實現

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Exchange extends Model
{

    const RATE = 600;

    public static function computeAmount($gold)
    {
        if($gold <= 0){
            return 0;
        }

        return $gold / self::RATE;
    }

}

5再次運行測試

測試:
    Command: run ExchangeTest
    自動化參數:-3000
    運行返回結果:0

運行成功,符合咱們的業務需求,提交代碼。編碼

4.TDD學習總結

當年學習了TDD以後,你就掌握到了任務分解、小步快跑的這種開發方式,你能夠把它應用到你沒有太大自信的功能開發中,他將提升你的代碼質量和整潔度,來減小生產Bug的產生率,同時TDD的關鍵部分在於驅動(driven),要讓測試驅動咱們來進行功能開發,每寫一個測試,都驅動咱們寫更多的生產代碼,都在向實現咱們的功能的方向前進。

最後想要良好的使用TDD或者應用到工做模式中,是須要不斷練習的,掌握TDD的祕訣,就是要讓你的代碼變得具備可測試性,來讓它更好的覆蓋到你的項目中。

關於TDD的爭議性依然存在很大的分歧,我的的觀點是:具體的權衡仍是須要落實到項目實際的實施上,在時間容許的過程當中,每一個重要的函數均可以編寫單元測試,覆蓋正確性測試、邊界測試、異常測試等等。以後的代碼改動再運行一遍測試便可,這樣會節省到許多開發時間,也提升了項目的穩定性,最後也治好了部分開發者不愛寫文檔和測試用例的習慣。

相關文章
相關標籤/搜索