初次使用單元測試后的體會
我們搞開發的往往覺得自己寫的代碼沒問題,用不著測試,以前,我也這么認為,覺得測試浪費時間,也就沒仔細研究過測試。
最近,閑來想試試單元測試,結合之前的編程經驗,發現,單元測試至少是保證軟件質量的最佳方式之一。一波一波程序員開發、維護一個產品,程序員之間的差別太大了,就像“明顯沒有錯誤”和“沒有明顯錯誤”的區別,怎么來保證產品在不斷迭代中的質量,保留里面正確的部分,去掉bug呢?架構設計里面講究面向接口,單元測試就能起到接口的作用。
通過單元測試的類,它的行為是符合當初單元設計的目標的。只要編寫單元測試時,從多方面檢驗類的行為,就能確保在這樣的情景下,類是符合設計的。在Vistual Studio中,最簡單的單元測試就是使用本身自帶的功能(不需要從網上找NUnit的程序集,直接在項目上引用"Microsoft.VisualStudio.QualityTools.UnitTestFramework"程序集就ok了)。還有另外一個好處,是方便調試。單元測試項目可以在測試運行時,對被測試類下斷點,非常節約調試時間。
我是這么做的,單元測試的代碼放到獨立的項目中去,引用要測試的項目,在被測試項目中添加Assembly特性如下:
[assembly: InternalsVisibleTo("Projky.UnitTests")]
這樣,單元測試就能對被測試項目中internal修飾符的類可見,又不破壞程序集的可見性。
舉一個簡單的需求,要將如“30d9132169211a45”或者“30-D9-13-21-69-21-1A-45”或者“30 D9 13 21 69 21 1A 45”這樣的16進制字符串轉換為Byte[]數組。設計了一個ByteString的類來實現需求。
internal class ByteString { public static Byte[] ConverterToBytes(string value) { if (value.IndexOf("-") > -1) { value = value.Replace("-", ""); } else if (value.IndexOf(" ") > -1) { value = value.Replace(" ", ""); } Debug.Assert(value.Length % 2 == 0, "Invalid byte string length."); List<Byte> list = new List<Byte>(value.Length / 2); for (int i = 0; i < value.Length; i += 2) { int bHi = GetInteger(value[i]); int bLow = GetInteger(value[i + 1]); Byte temp = (Byte)(bHi << 4 | bLow); list.Add(temp); } return list.ToArray(); } static int GetInteger(char ch) { if (Char.IsDigit(ch)) { return ch - '0'; } int value = 10; switch (ch) { case 'a': case 'A': value = 10; break; case 'b': case 'B': value = 11; break; case 'c': case 'C': value = 12; break; case 'd': case 'D': value = 13; break; case 'e': case 'E': value = 14; break; case 'f': case 'F': value = 15; break; default: throw new NotSupportedException(ch.ToString() + " is not valid char."); } return value; } } |
那么,簡單驗證該類的行為(接口)可以編寫下面的測試類:
[TestClass] public class ByteStringTest { [TestMethod] public void ConverterToBytes() { string input = "30d9132169211a45"; Byte[] bytes = ByteString.ConverterToBytes(input); Assert.IsTrue(bytes.Length == input.Length / 2); Assert.IsTrue(bytes[0] == 0x30); Assert.IsTrue(bytes[1] == 0xd9); Assert.IsTrue(bytes[2] == 0x13); Assert.IsTrue(bytes[3] == 0x21); Assert.IsTrue(bytes[4] == 0x69); Assert.IsTrue(bytes[5] == 0x21); Assert.IsTrue(bytes[6] == 0x1a); Assert.IsTrue(bytes[7] == 0x45); input = "30-D9-13-21-69-21-1A-45"; bytes = ByteString.ConverterToBytes(input); Assert.IsTrue(bytes.Length == 8); Assert.IsTrue(bytes[0] == 0x30); Assert.IsTrue(bytes[1] == 0xd9); Assert.IsTrue(bytes[2] == 0x13); Assert.IsTrue(bytes[3] == 0x21); Assert.IsTrue(bytes[4] == 0x69); Assert.IsTrue(bytes[5] == 0x21); Assert.IsTrue(bytes[6] == 0x1a); Assert.IsTrue(bytes[7] == 0x45); input = "30 D9 13 21 69 21 1A 45"; bytes = ByteString.ConverterToBytes(input); Assert.IsTrue(bytes.Length == 8); Assert.IsTrue(bytes[0] == 0x30); Assert.IsTrue(bytes[1] == 0xd9); Assert.IsTrue(bytes[2] == 0x13); Assert.IsTrue(bytes[3] == 0x21); Assert.IsTrue(bytes[4] == 0x69); Assert.IsTrue(bytes[5] == 0x21); Assert.IsTrue(bytes[6] == 0x1a); Assert.IsTrue(bytes[7] == 0x45); } } |
如果單元測試運行失敗,例如Assert.IsTrue()方法中,參數為False,則在VS中會拋異常,這樣,就知道哪里不正確了。
注意用[TestClass]標記作為單元測試承載的類,是public可見性,而里面單個的獨立測試方法,則采用[TestMethod]標記,同樣是public可見性。
在Visual Studio里面還有一個技巧,按Ctrl + R,A可以自動運行單元測試項目。如果被測試類有斷點的話,測試到該位置時,也會斷下來。
posted on 2014-08-21 09:42 順其自然EVO 閱讀(157) 評論(0) 編輯 收藏 所屬分類: 測試學習專欄