VS2012 Unit Test —— 我對IdleTest庫動的大手術以及對Xml相關操作進行測試的方式

dong.net發表於2013-10-20

【1】我的IdleTest原始碼地址:http://idletest.codeplex.com/

【2】IdleTest改動說明:2013年10月份在保持原有功能的情況下對其動了較大的手術,首先將基本的斷言方法分離成為介面,以便於擴充套件,例如現在可以支援切換測試框架(實現IAssertInstance介面,並修改AssertCommon_Editable.cs中的DEFAULT_INSTANCE為新的物件),然後就是增加對xml一些操作的支援。儘管如此,但並不是完全遵循OCP,可以說對擴充套件開放,對修改適當關閉。體現在AssertCommon_Editable.cs檔案,該檔案提供了AssertCommon的一個分部類,用以進行修改和增加功能,而AssertCommon.cs則儘可能不去修改,所以這是一個侷限性,但是又由於需要保留AssertCommon(因為該類是IdleTest最根本的功能)這個包含大量靜態成員的類,導致了難以實現對修改關閉的原則了。

  專案結構如下圖所示

專案多了就要畫些圖示說明,不然過段時間自己都不知道這個程式碼為什麼是這樣子的結構了。

以上都是比較簡單的圖示,下方這個則以介面和類為單位進行的類圖建模

【3】測試對Xml的操作之我的方式,如果您有更好的方式請不吝分享。

  1. 假設在IdleTest.DemoBeTest專案下有類XmlExtensionMethods需要測試

VS2012 Unit Test —— 我對IdleTest庫動的大手術以及對Xml相關操作進行測試的方式
    public static class XmlExtensionMethods
    {
        /// <summary>
        /// 獲取XML節點的屬性值
        /// </summary>
        /// <param name="node">節點</param>
        /// <param name="attr">屬性名</param>
        public static string GetAttribute(this XmlNode node, string attr)
        {
            if (string.IsNullOrEmpty(attr) || node.Attributes[attr] == null)
            {
                return string.Empty;
            }

            return node.Attributes[attr].Value;
        }

        /// <summary>
        /// 獲取XML節點的屬性值
        /// </summary>
        /// <param name="node">節點</param>
        /// <param name="attr">屬性名</param>
        public static T GetAttribute<T>(this XmlNode node, string attr)
        {
            if (string.IsNullOrEmpty(attr) || node.Attributes[attr] == null
                || string.IsNullOrEmpty(node.Attributes[attr].Value))
            {
                return default(T);
            }

            return (T)Convert.ChangeType(node.Attributes[attr].Value, typeof(T));
        }

        /// <summary>
        /// 查詢滿足條件的節點
        /// </summary>
        public static XmlNode Find(this XmlNodeList source, Func<XmlNode, bool> func)
        {
            foreach (object o in source)
            {
                XmlNode item = o as XmlNode;
                if (item != null && func(item))
                    return item;
            }

            return null;
        }

        /// <summary>
        /// 查詢滿足條件的節點集合
        /// </summary>
        public static ICollection<XmlNode> FindAll(this XmlNodeList source, Func<XmlNode, bool> func)
        {
            List<XmlNode> list = new List<XmlNode>();
            foreach (XmlNode item in source)
            {
                if (func(item))
                    list.Add(item);
            }

            return list;
        }
    }
XmlExtensionMethods

  2. 在專案IdleTest.DemoToUse新增引用

  3. 由於對類似XmlNode測試時需要用到Stub,故須對System.Xml新增Fakes程式集(參見上一篇《VS2012 Unit Test——Microsoft Fakes入門》)

  4. 在IdleTest.DemoBeTest專案下新增類,由於是對擴充套件方法進行測試,故要記得“using IdleTest.DemoBeTest;“

VS2012 Unit Test —— 我對IdleTest庫動的大手術以及對Xml相關操作進行測試的方式
    [TestClass]
    public class XmlExtensionMethodsTest : BaseXmlTest
    {
        #region XML

        /// <summary>
        ///Find 的測試
        ///</summary>
        [TestMethod()]
        public void FindTest()
        {
            AssertCommon.AssertEmpty<XmlNodeList, XmlNode>(new XmlNodeList[]{
                GetStubXmlNodeList(), GetStubXmlNodeList(null), GetStubXmlNodeList(null, null), 
                xmlBuilder.GetNodeList()
            }, true, p => p.Find(falseFunc));

            XmlNodeList nodeList = xmlBuilder.GetNodeList(DEFAULT_XPATH);
            XmlNode expectedNode = GetExpectedTureNode();
            XmlNode actualNode = nodeList.Find(trueFunc);
            AssertCommon.AssertEqual(expectedNode, actualNode);
        }

        /// <summary>
        ///FindAll 的測試
        ///</summary>
        [TestMethod()]
        public void FindAllTest()
        {
            AssertCommon.AssertEmpty<XmlNodeList, ICollection<XmlNode>>(new XmlNodeList[]{
                GetStubXmlNodeList(), GetStubXmlNodeList(null), GetStubXmlNodeList(null, null), 
                xmlBuilder.GetNodeList()
            }, true, p => p.FindAll(falseFunc));

            XmlNodeList nodeList = xmlBuilder.GetNodeList(DEFAULT_XPATH);
            XmlNodeList expectedNodes = GetExpectedTureNodes();
            ICollection<XmlNode> actualNodes = nodeList.FindAll(trueFunc);
            AssertCommon.AssertEqual<IEnumerable>(expectedNodes, actualNodes);
        }

        /// <summary>
        ///GetAttribute 的測試
        ///</summary>
        [TestMethod()]
        public void GetAttributeTest()
        {
            XmlNode node = GetExpectedTureNode();
            GetAttributeTestHelper<string>(node, ATTR_VALUE, ATTR_NAME, p => node.GetAttribute(p));

            XmlNode attrValueNull = GetAttrValueNullNode();
            AssertCommon.AssertEmpty<string>(attrValueNull.GetAttribute(ATTR_INT_NAME));
        }

        [TestMethod()]
        public void GetAttributeTest1()
        {
            XmlNode node = GetExpectedTureNode();
            GetAttributeTestHelper<string>(node, ATTR_VALUE, ATTR_NAME, p => node.GetAttribute<string>(p));

            node = xmlBuilder.GetNode(string.Format("{0}[@{1}='{2}']", DEFAULT_XPATH, ATTR_INT_NAME, ATTR_INT_VALUE));
            GetAttributeTestHelper<int>(node, ATTR_INT_VALUE, ATTR_INT_NAME, p => node.GetAttribute<int>(p));

            AssertCommon.AssertEqual<string, int>(0, TestCommon.GetEmptyStrings(), true, p => node.GetAttribute<int>(p));

            XmlNode attrValueNull = GetAttrValueNullNode();
            int actual = attrValueNull.GetAttribute<int>(ATTR_INT_NAME);
            AssertCommon.AssertEmpty<int>(actual, false);
            AssertCommon.AssertEqual(0, actual);
        }

        /// <summary>
        ///GetAttribute 的測試
        ///</summary>
        public void GetAttributeTestHelper<T>(XmlNode node, T expected, string attr, Func<string, T> testFunc)
        {
            AssertCommon.AssertEmpty<string, string>(
                TestCommon.GetEmptyStrings(), true, p => node.GetAttribute(p));

            AssertCommon.AssertEqual(expected, testFunc(attr));
        }
        #endregion
    }
XmlExtensionMethodsTest

  5.執行測試,OK!

  6. 執行覆蓋率分析,剛好100%。

【4】最後一個內容,其實就是將XML字串儲存的一個方法的測試,這裡就涉及到了儲存介質,我是先呼叫方法儲存,然後再從儲存的路徑中獲取Xml文件再將他們的文字對比。目前沒有找到更好的測試方式,同樣的如您有其他辦法,願聞其詳。

VS2012 Unit Test —— 我對IdleTest庫動的大手術以及對Xml相關操作進行測試的方式
    [TestClass()]
    public class XmlHelperTest : BaseXmlTest
    {
        /// <summary>
        ///CopyFile 的測試
        ///</summary>
        [TestMethod()]
        public void XmlToFileTest()
        {      
            string expected = base.xmlBuilder.InnerXml;
            string toPath = TestCommon.TestFilePath + "testxmlhelper.xml";
            XmlHelper.XmlToFile(expected, toPath);

            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(toPath);
            
            AssertCommon.AssertEqual(expected, xmlDoc.InnerXml);

            //為空時的測試
        }
    }
View Code

相關文章