建議155:隨生產代碼一起提交單元測試代碼

建議155:隨生產代碼一起提交單元測試代碼

首先提出一個問題:我們害怕修改代碼嗎?是否曾經無數次面對亂糟糟的代碼,下決心進行重構,然後在一個月後的某個週一,卻收到來自測試版的報告:新的版本,沒有之前的版本穩定,性能也更差了,Bug似乎也變多了。也就是說,重構的代碼看上去質量更高了,可實際測試結果卻不如人意。

幾乎每個程序員都因爲此類問題糾結過。我們要修改的代碼也許來自某些不負責任或經驗欠佳的程序員,也許這些代碼是自己一年前寫的,但是看上去已經慘不忍睹。我們想要修改這些代碼,卻擔心重構出別的問題。即便是一個開發週期中的產品,也會有這樣的選擇出現。某個模塊可能已經提交測試並確認通過,不過現在發現有更優的算法和邏輯,改還是不改,成了一個問題。

 “單元測試”減輕甚至消除了開發者這種恐懼。如果項目沒有測試代碼,說明我們只是生產“定時炸彈”。很多人將生產代碼和測試代碼分別對待,這是一種過時的做法。程序員在提交自己的生產代碼時,必須同時提交自己的單元測試代碼。很多現代化的版本管理工具可以在後臺訂製項目構建計劃,自動運行測試項目,統計代碼覆蓋率,並生成相應報告。我們應該在早上一邊喝咖啡,一邊讀取這樣的報告。

有了測試代碼做保證,在很大程度上我們可以放心去重構了。如果某個功能偏離了既有成果,就會有醒目的提醒。

將單元測試放在首要地位的一種開發模式是TDD模式。TDD(Test Driven Development測試驅動開發)有三條嚴格的定律:

  • 在編寫不能通過測試的單元測試前,不要編寫任何生產代碼。
  • 只編寫恰好無法通過的單元測試,不能編譯也算不通過。
  • 只編寫剛好足以通過當前失敗測試的生產代碼。

即使我們的團隊沒有完全採用TDD的開發模式,也可以借鑑這些定律來編寫我們自己的測試代碼。我們無需一次性編寫完全部的測試代碼,那沒有必要,這跟過度設計一樣,也不可能實現。事實上,我們應該逐步地編寫測試代碼,而且按如下步驟來編寫:

測試代碼->生產代碼->測試代碼

下面編寫一個單元測試的例子:

先編寫一個Add方法:

複製代碼
    public class SampleClass
    {
        public int Add(int a, int b)
        {
            return a + b;
        }
    }
複製代碼

 

 右鍵創建單元測試:

 VS會自動爲我們生成一個測試方法:

複製代碼
        /// <summary>
        ///Add 的測試
        ///</summary>
        [TestMethod()]
        public void AddTest()
        {
            SampleClass target = new SampleClass(); // TODO: 初始化爲適當的值
            int a = 0; // TODO: 初始化爲適當的值
            int b = 0; // TODO: 初始化爲適當的值
            int expected = 0; // TODO: 初始化爲適當的值
            int actual;
            actual = target.Add(a, b);
            Assert.AreEqual(expected, actual);
            Assert.Inconclusive("驗證此測試方法的正確性。");
        }
複製代碼

 

將方法修改成我們需要的方法就可以了:

複製代碼
        /// <summary>
        ///Add 的測試
        ///</summary>
        [TestMethod()]
        public void AddTest()
        {
            SampleClass target = new SampleClass(); // TODO: 初始化爲適當的值
            int a = 1; // TODO: 初始化爲適當的值
            int b = 2; // TODO: 初始化爲適當的值
            int expected = 3; // TODO: 初始化爲適當的值
            int actual;
            actual = target.Add(a, b);
            Assert.AreEqual(expected, actual);
            Assert.Inconclusive("驗證此測試方法的正確性。");
        }
複製代碼

VS這個可視化測試工具太重量級了,導致開發的過程中運行測試代碼太繁瑣也太耗時。可以考慮用測試工具TestDriven.NET,這裏不再介紹。

單元測試要注意一下幾點:

首先,單元測試不應引入任何人機交互的內容。如,測試過程中不應該彈出對話框,等待用戶輸入或確認。單元測試不應該是被阻滯的。

其次,多線程也不屬於單元測試範疇,單元測試應該是快速被執行的,而不是需要等待的。

最後,單元測試不應該跨應用程序域,例如,數據訪問或者遠程通信屬於集成測試範疇,而不是單元測試。

 

 

 

 

轉自:《編寫高質量代碼改善C#程序的157個建議》陸敏技

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章