不喜歡寫測試的朋友看過來,與你分享寫測試的經驗 做一個愛寫測試的程序員


自從掌握了單元測試的要領之后,經常寫測試,做測試,也非常喜歡做單元測試。我的文章《數據采集:完美下載淘寶Ip數據庫 簡單的程序節省60元人民幣而不必購買數據庫》中的代碼,也是個測試方法,源代碼在QQ群中公布過。

現在把它公開給大家,分享這個Ip地址信息下載功能的測試代碼:

[TestMethod]
public void IPLibraryTest()
 {
            string whole = "211.64.0-255.0-255";
            IPRange ipRange = new IPRange(whole);
            List<IPAddress> addresses = ipRange.GetAllIP() as List<IPAddress>;
            DataTable table = new DataTable("Ip");
            JavaScriptSerializer serializer = new JavaScriptSerializer();
            string url = string.Empty, json = string.Empty;
            Parallel.ForEach(addresses, (address) =>
                {
                     url = string.Format("http://ip.taobao.com/service/getIpInfo.php?ip={0}", address.ToString());
                     json = string.Empty;
                    try
                    {
                        json = Convert.ToString(NetworkHelper.PostRequest(url));
                    }
                    catch (Exception)
                    {
                            
                    }
                    Object obj2 = serializer.DeserializeObject(json);
                    if (string.IsNullOrWhiteSpace(json)||obj2 == null)
                        return;

                    Dictionary<String, Object> dictionary = (Dictionary<String, Object>)obj2;

                    foreach (KeyValuePair<string, object> valuePair in dictionary)
                    {
                        if (valuePair.Value.GetType() == typeof (Dictionary<string, object>))
                        {
                            Dictionary<String, Object> subdictionary = valuePair.Value as Dictionary<String, Object>;
                            lock (table)
                            {
                                if (table.Columns.Count == 0)
                                {
                                    foreach (KeyValuePair<string, object> pair in subdictionary)
                                    {
                                        table.Columns.Add(pair.Key, typeof (string));
                                    }
                                }

                                DataRow row = table.NewRow();
                                foreach (KeyValuePair<string, object> pair in subdictionary)
                                {
                                    row[pair.Key] = pair.Value;
                                }
                                table.Rows.Add(row);
                            }
                        }
                    }
                });
 
            string databaseFile = @"H:\Development\Source\Test\Database\64IpLibrary.accdb";
            OleDbHelper accessHelper = new OleDbHelper(databaseFile);
            accessHelper.AppendData(table);
}

程序中的不合理的地方,歡迎批評指正。

三個工具的組合 Visual Studio + Resharper + Visual Source Safe,經過幾年的積累,累積了大量的測試代碼。

Visual Studio內置的MSTest本身好用,NUnit也可以,這是測試的基礎工具,再配合Reshaprer的測試管理器,在方法前面點一個小按鈕,即可以調試或是運行的方式開始測試,相當方便。最后,累積的測試代碼,直接提交到源代碼管理工具中,備以后查驗。

我們開發中經常遇到這樣的情景,有一個小方法不知道是否正確,需要測試一下。不需要復雜的用戶輸入的功能,可以開一個控制台程序,執行測試,如用戶輸入復雜,則需要開一個Windows Forms程序。測試完成后,把可用的功能代碼拷貝走,剩下的測試程序通常會扔掉。在沒有學會MSTest之前,我經常這么做。等到以后發現有問題時,再回來來找當初的測試情景和代碼,傳遞的參數數據,已經無從得知。

經過這種痛苦之后,我開始嘗試單元測試,把要測試的代碼和數據都保存一個Test項目中,每個解決方案都跟一個測試項目,用於執行測試,保存測試參數:

image

經過若干年的積累,這里面積累了很多實用的代碼。

比如在做許可驗證時,生成公匙和私匙,就下面二行代碼,於是寫成一個測試方法,保存在我的源代碼服務器中

[TestMethod]
public void SolutionValidationTest()
{
      string publickey = RSACryptionHelper.GeneratePublickKey(false);
      string privateKey = RSACryptionHelper.GeneratePublickKey(true);
}

這種代碼庫的積累,如果回憶起來,比查MSDN還快。

再比如,我的許可證機制是以Signature Xml為基礎的,下面的方法可以測試許可證文件,驗證它的正確性。

[TestMethod]
public void SolutionLicenseValidationTest()
 {
            SolutionLicense license = SolutionLicense.ReadLicense();
            string licenseFile = @"H:\Development\Build\License.lic";

            StreamReader reader = new StreamReader(licenseFile, Encoding.UTF8, true);

            XmlTextReader xmlReader = new XmlTextReader(licenseFile);
            XmlDocument doc = new XmlDocument();
            doc.Load(xmlReader);
            doc.Load(reader);

            license = SolutionLicense.ReadLicense();
            license.VerifyLicense();
}
 

有時候真的很偷懶,不想寫個GUI程序,就用這種方法來進行。調試過程中,如果有異常,MSTest會中斷運行,顯示異常的原因。用NUnit寫的測試也一樣的效果。有了Resharper的幫助,做代碼的單元測試時,你完全像是在做功能測試一樣,告訴VS我想運行一個方法,在方法名稱前點擊Run或是Debug即可。

image

行號左邊的那個小按鈕,對測試的運行和調試起到關鍵性的作用,極大的簡化了測試代碼的運行和檢測。

有時候,我並不想調用Assert去判斷值的真或假,比如上面的生成許可證文件,我去硬盤里面看看,檢查一下內容也可以判斷,自動化的步驟是加一個Assert(true, File.Exist(fileName)) ,但是由決定權在你手里,能把代碼測試好,功能調試好就可以收工回家。

 

通俗的理解,單元測試的二個主要作用:

1  保存API接口或是功能的調用方式和參數值,以留作改善或是問題查找的源頭

2  記錄對新技術的學習,掌握情況,供快速參考。

Lambda表達式代表一個匿名方法,如果調用這個方法,對它求值呢,參考下面的代碼例子

[TestMethod]
public void TraceTestMethod()
{
       Expression<Func<DateTime>> expr = () => DateTime.Now.AddDays(1);
       Func<DateTime> tomorrow = expr.Compile();
       Console.WriteLine(tomorrow());
        
}

看了這個例子后,肯清楚的解釋了步驟,照葫蘆化瓢,一下子就可以應用到工作中。

再來看幾個擴展方法的例子,看下面的代碼,生成字節數

[TestMethod]
public void ByteTest()
{
     var kb = 1.KB();
     var mb = 1.MB();
     var gb = 1.GB();
     var tb = 1.TB();
}

追綜到源代碼中,原來是這樣的幾個擴展方法:

/// <summary> 
        /// Kilobytes 
        /// </summary> 
        /// <param name="value"></param> 
        /// <returns></returns> 
        public static int KB(this int value)
        {
            return value * 1024;
        }

        /// <summary> 
        /// Megabytes 
        /// </summary> 
        /// <param name="value"></param> 
        /// <returns></returns> 
        public static int MB(this int value)
        {
            return value.KB() * 1024;
        }

        /// <summary> 
        /// Gigabytes 
        /// </summary> 
        /// <param name="value"></param> 
        /// <returns></returns> 
        public static int GB(this int value)
        {
            return value.MB() * 1024;
        }

        /// <summary> 
        /// Terabytes 
        /// </summary> 
        /// <param name="value"></param> 
        /// <returns></returns> 
        public static long TB(this int value)
        {
            return (long)value.GB() * (long)1024;
        }

測試代碼是為自己而寫,為自己掌握這項技術,熟悉這下技術,記的筆記。

Visual Studio本身就是個很好的代碼收藏工具,有最好的編輯器,調試器,再以一個源代碼管理工具作為輔助,這就組合成一個很好的代碼收藏工具。看了我這篇文章之后,你可能再也不想用代碼收藏工具了。我鼓勵你把它扔掉,把收藏的代碼片段直接保存在一個測試項目中,堅持積累,積跬步而行千里路,庖丁解牛,游刃有余。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM