在Visual Studio 2012使用單元測試


本人之前很少使用單元測試,總覺得平時的工作寫得代碼夠多了,單元測試還要再編碼,增加大量工作量,相信不少程序猿也是這么認為吧。


但是我認為,在必要的時候正確運用單元測試,可以大大縮短代碼的調試時間,正所謂磨刀不誤砍柴工,在此建議仍不會單元測試的,還是學一下吧。當然本人在單元測試方面還是菜鳥,無論是雞蛋鮮花都歡迎。

 

最近公司請微軟的人做了一些關於使用VS2012進行單元測試的小培訓,小生微做筆記,結合朦朧的記憶,在此自行總結,並分享之。廢話少說,先上筆記: 

1.先寫單元測試(依我愚見,應該是接口先行,如果有的話) -> 測試失敗 -> 以最小的改動(即編寫實際代碼)使測試通過(而在VS2012中已經不能通過現有項目直接生成測試項目了,我覺得這個功能還是應該保留,微軟總是這副德行,強迫用戶適應他們的產品,但是又不得不適應);

2.不因單元測試而追加功能(代碼),即邏輯不受單元測試影響;

3.改變了代碼的邏輯(增刪改),應及時運行單元測試;

4.在測試方法聲明Attribute —— TestCategory("分類或特征名");

5.在單元測試項目添加Fakes程序集分離外部依賴(如數據庫訪問,獲取配置信息等);

6.初始化單元測試類中的成員等信息,可添加方法並聲明Attribute[TestInitialize](方法需為public);

7.測試自動化。

 

以下我將通過自己編寫代碼來驗證上述筆記中的部分要點。有些未涉及,以后再嘗試了。

1.新建一個單元測試項目,並添加類XmlSerializationTest,代碼如下:

    [TestClass]
    public class XmlSerializationTest
    {
        [TestMethod]
        public void TestWriteXml()
        {
            UserModel user = new UserModel();
            XmlSerialization serialization = new XmlSerialization();
            bool flag = serialization.WriteXml<UserInifo>(user);
            Assert.IsTrue(flag);
        }
    }
View Code

由於我這個項目是對Xml序列化進行測試,因而前提是項目中已存在了一個UserModel類,並且在單元測試項目中添加相應引用

    public class UserModel
    {
        public string LoginName { get; set; }
        public string Password { get; set; }
    }
UserModel

接下來在編寫實際的代碼,微軟講師建議我們先在測試項目編寫,待通過單元測試后再將代碼移到相應的項目下面。

    public class XmlSerialization
    {
        public bool WriteXml<T>(T model)
        {
            throw new NotImplementedException();
        }
    }
XmlSerialization

現在整個解決方案結構如下圖所示

保證整個解決方案生成成功之后點擊菜單“測試” -〉 “運行” -〉 “所有測試”,發現測試不通過,於是就按照第一點筆記,以最小改動使測試通過。

修改WriteXml方法為:

public bool WriteXml<T>(T model)
{
    return true;
}

運行測試通過。對於返回值為bool的方法,個人建議進行至少兩次Assert,也就是分別對返回true和false進行Assert,因而我們再對WriteXml方法添加一個測試方法,

        [TestMethod]
        public void TestWriteXmlFalse()
        {
            Assert.IsFalse(new XmlSerialization().WriteXml<UserModel>(null));
        }

運行測試,不通過,所以我得要好好改我的代碼了,在改動當中堅持執行我的第三點筆記,改動代碼及時運行單元測試。

    public class XmlSerialization
    {
        private string filePath;
        public XmlSerialization(string filePath)
        {
            this.filePath = filePath;
        }

        public bool WriteXml<T>(T model, string filePath = null) where T : class
        {
            bool result = false;
            if (model == null)
            {
                return result;
            }

            if (string.IsNullOrEmpty(filePath))
            {
                filePath = this.filePath;
            }

            XmlSerializer serializer = new XmlSerializer(typeof(T));
            using (TextWriter tr = new StreamWriter(filePath))
            {
                serializer.Serialize(tr, model);
                tr.Close();
                result = true;
            }

            return result;
        }

        public T ReadXml<T>(string filePath = null) where T : class
        {
            T model = null;
            if (string.IsNullOrEmpty(filePath))
            {
                filePath = this.filePath;
            }

            XmlSerializer serializer = new XmlSerializer(typeof(T));
            TextReader tr = null;
            try
            {
                tr = new StreamReader(filePath);
                model = (T)serializer.Deserialize(tr);
            }
            catch { }
            finally
            {
                if (tr != null)
                {
                    tr.Close();
                    tr.Dispose();
                }
            }

            return model;
        }
    }
XmlSerialization

我們發現這個類的構造函數多了一個參數,是對象序列化后保存的路徑,且該類對應的測試類都需要用到,因而我希望在每次測試進行單元測試前先將對象的構建,這就是第六點筆記提供的“聲明Attribute[TestInitialize]”(注意必須是public方法,我用private方法運行測試是不通過)。改造后的測試類如下:

    [TestClass]
    public class XmlSerializationTest
    {
        private XmlSerialization serialization;
        [TestInitialize]
        public void InitTest()
        {
            this.serialization = new XmlSerialization(@"F:\usermodel.seri");
        }

        [TestMethod]
        public void TestWriteXml()
        {
            UserModel user = new UserModel();
            bool flag = serialization.WriteXml<UserModel>(user);
            Assert.IsTrue(flag);
            Assert.IsFalse(serialization.WriteXml<UserModel>(null));
        }

        [TestMethod]
        public void TestReadXml()
        {
            UserModel user = new UserModel();
            user.LoginName = "aa";
            serialization.WriteXml<UserModel>(user);
            UserModel model = serialization.ReadXml<UserModel>();
            Assert.IsNotNull(model);
            Assert.AreEqual(user.LoginName, model.LoginName);

            //路徑不存在,應返回null
            UserModel modelnull = serialization.ReadXml<UserModel>(@"F:\notexists.seri");
            Assert.IsNull(modelnull);
        }
    }
XmlSerializationTest

 

還可以分析測試代碼的覆蓋率,如下圖所示在測試資源管理器點擊“運行”下的相應選項。

居然是100%,真不知道這個東西微軟是怎么分析出來的。

把類XmlSerializationTest移到相應的項目,更改命名空間,在測試項目添加相應引用,測試通過。

將解決方案添加到TFS源碼管理,我這邊是用的是微軟雲TFS免費版。

收工。

VS提供了很多類型的測試,負載、UI等等測試,感覺還是蠻強大的。

下一篇:VS2012 單元測試之泛型類(Generics Unit Test)


免責聲明!

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



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