反序列化期间任何深度获取XMLElement

时间:2019-02-22 05:05:07

标签: c# xml nunit deserialization

我是C#和XML反序列化的新手,请原谅我输入的任何错误单词/信息不正确。

我正在反序列化带有根元素的Nunit3测试结果XML,因为test-run和子元素分别是测试套件和测试用例。

测试用例会重复执行多次,具体取决于执行的测试用例的数量以及我感兴趣的元素。

Nunit XML的C#类如下。

[XmlRoot(ElementName = "test-run")]
public class Testrun
{
    [XmlElement(ElementName = "command-line")]
    public string Commandline { get; set; }
    [XmlElement(ElementName = "test-suite")]
    public Testsuite Testsuite { get; set; }
}

[XmlRoot(ElementName = "test-suite")]
public class Testsuite
{
[XmlElement(ElementName = "test-case")]
    public Testcase Testcase { get; set; }
}

但是有时嵌套的测试套件元素会在Nunit XML中出现,如下所示。

<test-suite type="TestSuite" id="0-1005" name="TopGearFramework" fullname="TopGearFramework" runstate="Runnable" testcasecount="2" result="Failed" site="Child" start-time="2019-02-21 04:17:28Z" end-time="2019-02-21 04:19:16Z" duration="108.354384" total="2" passed="1" failed="1" warnings="0" inconclusive="0" skipped="0" asserts="14">
  <test-suite type="TestSuite" id="0-1006" name="CFTestCases" fullname="TopGearFramework.CFTestCases" runstate="Runnable" testcasecount="2" result="Failed" site="Child" start-time="2019-02-21 04:17:28Z" end-time="2019-02-21 04:19:16Z" duration="108.353019" total="2" passed="1" failed="1" warnings="0" inconclusive="0" skipped="0" asserts="14">
      <test-suite type="TestSuite" id="0-1007" name="PoCTestCases" fullname="TopGearFramework.CFTestCases.PoCTestCases" runstate="Runnable" testcasecount="2" result="Failed" site="Child" start-time="2019-02-21 04:17:28Z" end-time="2019-02-21 04:19:16Z" duration="108.352989" total="2" passed="1" failed="1" warnings="0" inconclusive="0" skipped="0" asserts="14">
        <test-suite type="TestSuite" id="0-1008" name="FeatureFiles" fullname="TopGearFramework.CFTestCases.PoCTestCases.FeatureFiles" runstate="Runnable" testcasecount="2" result="Failed" site="Child" start-time="2019-02-21 04:17:28Z" end-time="2019-02-21 04:19:16Z" duration="108.352968" total="2" passed="1" failed="1" warnings="0" inconclusive="0" skipped="0" asserts="14">
           <test-suite type="TestFixture" id="0-1002" name="IndividualDealerPartyCreationFeature" fullname="TopGearFramework.CFTestCases.PoCTestCases.FeatureFiles.IndividualDealerPartyCreationFeature" classname="TopGearFramework.CFTestCases.PoCTestCases.FeatureFiles.IndividualDealerPartyCreationFeature" runstate="Runnable" testcasecount="1" result="Passed" start-time="2019-02-21 04:17:28Z" end-time="2019-02-21 04:19:07Z" duration="99.414157" total="1" passed="1" failed="0" warnings="0" inconclusive="0" skipped="0" asserts="10">
                  <test-case id="0-1003" name="XF_PAM_004_CheckNewDealerPartyCreationForIndividual" fullname="TopGearFramework.CFTestCases.PoCTestCases.FeatureFiles.IndividualDealerPartyCreationFeature.XF_PAM_004_CheckNewDealerPartyCreationForIndividual" methodname="XF_PAM_004_CheckNewDealerPartyCreationForIndividual" classname="TopGearFramework.CFTestCases.PoCTestCases.FeatureFiles.IndividualDealerPartyCreationFeature" runstate="Runnable" seed="293675085" result="Passed" start-time="2019-02-21 04:17:29Z" end-time="2019-02-21 04:19:07Z" duration="98.585096" asserts="10">

请注意,在发生测试用例之前,将测试套件重复5次。在反序列化过程中,对于测试用例对象,它为空。

如何处理测试套件元素的动态嵌套或重复以获取测试用例?

谢谢。

编辑1#完整的XML复制以供参考。

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<test-run id="2" testcasecount="2" result="Failed" total="2" passed="1" failed="1" inconclusive="0" skipped="0" asserts="14" engine-version="3.9.0.0" clr-version="4.0.30319.42000" start-time="2019-02-21 04:17:25Z" end-time="2019-02-21 04:19:16Z" duration="111.183778">
  <command-line><![CDATA["C:\Program Files (x86)\NUnit.org\nunit-console\nunit3-console.exe"   TopGearFramework\bin\Debug\TopGearFramework.dll --result=TestResult.xml --labels=All --out=TestResult.txt]]></command-line>
  <test-suite type="Assembly" id="0-1004" name="TopGearFramework.dll" fullname="TopGearFramework.dll" runstate="Runnable" testcasecount="2" result="Failed" site="Child" start-time="2019-02-21 04:17:28Z" end-time="2019-02-21 04:19:16Z" duration="108.409138" total="2" passed="1" failed="1" warnings="0" inconclusive="0" skipped="0" asserts="14">
    <environment framework-version="3.11.0.0" clr-version="4.0.30319.42000" os-version="Microsoft Windows NT 10.0.16299.0" platform="Win32NT" cwd="C:\Users\qxm5789\.jenkins\workspace\TopGearTestRunner_master" machine-name="VMUC0034748" user="qxm5789" user-domain="MUC" culture="en-US" uiculture="en-US" os-architecture="x64" />
    <settings>
      <setting name="DisposeRunners" value="True" />
    </settings>
    <properties>
      <property name="_PID" value="1852" />
      <property name="_APPDOMAIN" value="domain-" />
    </properties>
    <failure>
      <message><![CDATA[One or more child tests had errors]]></message>
    </failure>
    <test-suite type="TestSuite" id="0-1005" name="TopGearFramework" fullname="TopGearFramework" runstate="Runnable" testcasecount="2" result="Failed" site="Child" start-time="2019-02-21 04:17:28Z" end-time="2019-02-21 04:19:16Z" duration="108.354384" total="2" passed="1" failed="1" warnings="0" inconclusive="0" skipped="0" asserts="14">
      <failure>
        <message><![CDATA[One or more child tests had errors]]></message>
      </failure>
      <test-suite type="TestSuite" id="0-1006" name="CFTestCases" fullname="TopGearFramework.CFTestCases" runstate="Runnable" testcasecount="2" result="Failed" site="Child" start-time="2019-02-21 04:17:28Z" end-time="2019-02-21 04:19:16Z" duration="108.353019" total="2" passed="1" failed="1" warnings="0" inconclusive="0" skipped="0" asserts="14">
        <failure>
          <message><![CDATA[One or more child tests had errors]]></message>
        </failure>
        <test-suite type="TestSuite" id="0-1007" name="PoCTestCases" fullname="TopGearFramework.CFTestCases.PoCTestCases" runstate="Runnable" testcasecount="2" result="Failed" site="Child" start-time="2019-02-21 04:17:28Z" end-time="2019-02-21 04:19:16Z" duration="108.352989" total="2" passed="1" failed="1" warnings="0" inconclusive="0" skipped="0" asserts="14">
          <failure>
            <message><![CDATA[One or more child tests had errors]]></message>
          </failure>
          <test-suite type="TestSuite" id="0-1008" name="FeatureFiles" fullname="TopGearFramework.CFTestCases.PoCTestCases.FeatureFiles" runstate="Runnable" testcasecount="2" result="Failed" site="Child" start-time="2019-02-21 04:17:28Z" end-time="2019-02-21 04:19:16Z" duration="108.352968" total="2" passed="1" failed="1" warnings="0" inconclusive="0" skipped="0" asserts="14">
            <failure>
              <message><![CDATA[One or more child tests had errors]]></message>
            </failure>
            <test-suite type="TestFixture" id="0-1002" name="IndividualDealerPartyCreationFeature" fullname="TopGearFramework.CFTestCases.PoCTestCases.FeatureFiles.IndividualDealerPartyCreationFeature" classname="TopGearFramework.CFTestCases.PoCTestCases.FeatureFiles.IndividualDealerPartyCreationFeature" runstate="Runnable" testcasecount="1" result="Passed" start-time="2019-02-21 04:17:28Z" end-time="2019-02-21 04:19:07Z" duration="99.414157" total="1" passed="1" failed="0" warnings="0" inconclusive="0" skipped="0" asserts="10">
              <properties>
                <property name="Description" value="Individual Dealer Party Creation" />
              </properties>
              <output><![CDATA[-> Using app.config
]]></output>
              <test-case id="0-1003" name="XF_PAM_004_CheckNewDealerPartyCreationForIndividual" fullname="TopGearFramework.CFTestCases.PoCTestCases.FeatureFiles.IndividualDealerPartyCreationFeature.XF_PAM_004_CheckNewDealerPartyCreationForIndividual" methodname="XF_PAM_004_CheckNewDealerPartyCreationForIndividual" classname="TopGearFramework.CFTestCases.PoCTestCases.FeatureFiles.IndividualDealerPartyCreationFeature" runstate="Runnable" seed="293675085" result="Passed" start-time="2019-02-21 04:17:29Z" end-time="2019-02-21 04:19:07Z" duration="98.585096" asserts="10">
                <properties>
                  <property name="Description" value="XF_PAM_004_Check New Dealer Party Creation for Individual" />

                </properties>
                <output><![CDATA[Given Browser is launched
-> done: IndividualDealerPartyCreationSteps.GivenBrowserIsLaunched() (0.0s)
]]></output>
                <attachments>
                  <attachment>
                    <filePath>C:\Users\qxm5789\.jenkins\workspace\TopGearTestRunner_master\TestResults\\XF_PAM_004_Check New Dealer Party Creation for Individual2019-02-21-11_19_02.jpg</filePath>
                    <description><![CDATA[Screenshot captured]]></description>
                  </attachment>
                </attachments>
              </test-case>
            </test-suite>
            <test-suite type="TestFixture" id="0-1000" name="TestOriginationAPIFeature" fullname="TopGearFramework.CFTestCases.PoCTestCases.FeatureFiles.TestOriginationAPIFeature" classname="TopGearFramework.CFTestCases.PoCTestCases.FeatureFiles.TestOriginationAPIFeature" runstate="Runnable" testcasecount="1" result="Failed" site="Child" start-time="2019-02-21 04:19:07Z" end-time="2019-02-21 04:19:16Z" duration="8.923635" total="1" passed="0" failed="1" warnings="0" inconclusive="0" skipped="0" asserts="4">
              <properties>
                <property name="Description" value="Test Origination API" />
              </properties>
              <failure>
                <message><![CDATA[One or more child tests had errors]]></message>
              </failure>
              <test-case id="0-1001" name="FE_AHA_040_SearchApplicationByApplicationIDThroughOriginationAPI" fullname="TopGearFramework.CFTestCases.PoCTestCases.FeatureFiles.TestOriginationAPIFeature.FE_AHA_040_SearchApplicationByApplicationIDThroughOriginationAPI" methodname="FE_AHA_040_SearchApplicationByApplicationIDThroughOriginationAPI" classname="TopGearFramework.CFTestCases.PoCTestCases.FeatureFiles.TestOriginationAPIFeature" runstate="Runnable" seed="2107869277" result="Failed" start-time="2019-02-21 04:19:07Z" end-time="2019-02-21 04:19:16Z" duration="8.921560" asserts="4">
                <properties>
                  <property name="Description" value="FE_AHA_040_Search Application By Application ID through Origination API" />

                </properties>
                <failure>
                  <message><![CDATA[  Error Occured: 
  Expected: <empty>
  But was:  < "Contract ID 12345 not found." >
]]></message>
                  <stack-trace><![CDATA[   
]]></stack-trace>
                </failure>
                <output><![CDATA[
]]></output>
                <assertions>
                  <assertion result="Failed">
                    <message><![CDATA[  Error Occured: 
  Expected: <empty>
  But was:  < "Contract ID 12345 not found." >
]]></message>
                    <stack-trace><![CDATA[   
]]></stack-trace>
                  </assertion>
                </assertions>
              </test-case>
            </test-suite>
          </test-suite>
        </test-suite>
      </test-suite>
    </test-suite>
  </test-suite>
</test-run>

2 个答案:

答案 0 :(得分:0)

如果您想以XML的任何深度获取所有<test-case>节点,那么XDocument.Descendants("test-case")将为您做到这一点。

如果使用result节点中的节点,则可以使用LINQ从每个<test-case>节点检索属性message,并从<failure>节点检索<test-case>

然后下面的代码为您提供失败消息列表以及结果。

class Program
{
    public static void Main(string[] args)
    {
        XDocument doc = XDocument.Load(@"Path to your xml file");

        var result = (from t in doc.Descendants("test-case")
                      from f in t.Descendants("failure")
                      select new
                      {
                          Result = t.Attribute("result").Value,
                          Failure_Message = f.Element("message") != null ? f.Element("message").Value : ""
                      }).ToList();

        //---------------Print the result------------------

        foreach (var item in result)
        {
            Console.WriteLine("Result: " + item.Result);
            Console.WriteLine("Message: " + item.Failure_Message);
        }

        Console.ReadLine();
    }

输出:

enter image description here

答案 1 :(得分:0)

您需要一个自定义解析器。我用xml linq:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication100
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);
            Testrun testrun = new Testrun();
            testrun.ParseXml(FILENAME);

        }
    }
    public class Testrun
    {
        public string Commandline { get; set; }
        public Testsuite Testsuite { get; set; }

        public void ParseXml(string filename)
        {
            XDocument doc = XDocument.Load(filename);
            XElement Testrun = doc.Root;
            Commandline = (string)Testrun.Element("command-line");
            XElement testsuit = Testrun.Element("test-suite");
            if (testsuit != null)
            {
                Testsuite = new Testsuite(testsuit);
            }

        }
     }

    public class Testsuite
    {
        public Attributes attributes { get; set; }
        public Testsuite testsuite { get; set; }
        public string failure_message { get; set; }
        public string property_name { get; set; }
        public string property_value { get; set; }
        public TestCase TestCase { get; set; }

        public Testsuite(XElement xTestsuite)
        {
            attributes = new Attributes(xTestsuite);
            XElement failure = xTestsuite.Element("failure");
            if (failure != null) failure_message = (string)failure.Element("message");


            XElement properties = xTestsuite.Element("properties");
            if (properties != null)
            {
                XElement property = properties.Element("property");
                property_name = (string)property.Attribute("name");
                property_value = (string)property.Attribute("value");
            }

            XElement testcase = xTestsuite.Element("test-case");
            if (testcase != null)
            {
                TestCase = new TestCase(testcase);
            }



            xTestsuite = xTestsuite.Element("test-suite");
            if (xTestsuite != null)
            {
                testsuite = new Testsuite(xTestsuite);
            }

        }
    }
    public class TestCase
    {
        public string output { get; set; }
        public string property_name { get; set; }
        public string property_value { get; set; }
        public string attachment_filePath { get; set; }
        public string attachment_description { get; set; }

        public TestCase(XElement testCase)
        {
            XElement xOutput = testCase.Element("output");
            if (xOutput != null) output = (string)xOutput;

            XElement properties = testCase.Element("properties");
            if (properties != null)
            {
                XElement property = properties.Element("property");
                property_name = (string)property.Attribute("name");
                property_value = (string)property.Attribute("value");
            }

            XElement attachments = testCase.Element("attachments");
            if (attachments != null)
            {
                XElement attachment = attachments.Element("attachment");
                attachment_filePath = (string)attachment.Element("filePath");
                attachment_description = (string)attachment.Element ("description");
            }
        }

    }
    public class Attributes
    {
        string testtype { get; set; }
        string id { get; set; }
        string name { get; set; }
        string fullname { get; set; }

        string runstate  { get; set; }
        int testcasecount  { get; set; }
        string result  { get; set; }
        string site  { get; set; }
        DateTime start_time  { get; set; }
        DateTime end_time  { get; set; }
        decimal duration  { get; set; }
        int total  { get; set; }
        int passed  { get; set; }
        int failed  { get; set; }
        int warnings  { get; set; }
        int inconclusive  { get; set; }
        int skipped  { get; set; }
        int asserts { get; set; }

        public Attributes(XElement attributes)
        {
            testtype = (string)attributes.Attribute("type");
            id = (string)attributes.Attribute("id");
            name = (string)attributes.Attribute("name");
            fullname  = (string)attributes.Attribute("fullname");

            runstate  = (string)attributes.Attribute("runstate");
            testcasecount  = (int)attributes.Attribute("testcasecount");
            result = (string)attributes.Attribute("result");
            site = (string)attributes.Attribute("site");
            start_time = (DateTime)attributes.Attribute("start-time");
            end_time = (DateTime)attributes.Attribute("end-time");
            duration = (decimal)attributes.Attribute("duration");
            total = (int)attributes.Attribute("total");
            passed = (int)attributes.Attribute("passed");
            failed = (int)attributes.Attribute("failed");
            warnings = (int)attributes.Attribute("warnings");
            inconclusive = (int)attributes.Attribute("inconclusive");
            skipped = (int)attributes.Attribute("skipped");
            asserts = (int)attributes.Attribute("asserts");
        }

    }
}