locked
Data Driven test - embedded XML RRS feed

  • Question

  • Hello,

    can someone tell me how to work with xml files in data driven tests?

    My test processes XML nodes with a certain xml schema. So I thought: wouldn't it be nice if I could stack up all nodes and execute them as data driven test? So I wrote an XML file that looks like that:

    <root>
       <Test>
         <SubData Name="x">
           <SubItem/>
           <SubItem/>
         </SubData>
       </Test>
       <Test>
         <SubData Name="y">
           <SubItem/>
         </SubData>
       </Test>
    
    </root>

    My Data driven Test is configured to use the "Test" node as data table. So, when I execute the Test, I access the DataRow from the TestContext, and I'd like to retrieve the sub-xml structure as it is, so I can forward it to my test method. But how do I do that?

    var row = TestContext.DataRow;
    var xmlContent = row.Get_Field<string>("???");

    Sunday, September 9, 2012 7:21 PM

Answers

  • Hello Goppeltm,

    If you bind a data source which is an xml file to unit tests, the xml file must be like this:

    <Tablename>
    <Year>2011</Year>
    <Month>4</Month>
    <Day>22</Day>
    <Result>true</Result>
    < / Tablename >

    According to the example above, there is one table is in the xml file and one row and three columns are in the table. As far as I know we can’t define more than two levels in it like this if we make it as a data source for unit test:

    <Tablename>
         <Year>

             <SubItem>

              </SubItem>

         </Year>

    < / Tablename >

    Best regards,


    Amanda Zhu [MSFT]
    MSDN Community Support | Feedback to us

    • Marked as answer by Amanda Zhu Friday, September 14, 2012 12:46 AM
    Wednesday, September 12, 2012 8:42 AM
  • Well... the thing I learned from this lesson is, that I need to rethink how I store my test data for data driven tests. We have a lot of quite complex test data here, and multiple tests that share the same info.

    My feeling is, that this is quite a weak point from MS Test currently. Without proper queries, I have to split up my test data into a lot of files.

    So, my current solution looks like that: I return the sub- (and sub-sub) DataRows of each test row, like:

    var SubRows = TestContext.DataRow.GetChildRows("Test_SubData");

    and recreate my test data from it by reading each data field and storing. Not perfect, because I basically do exactly in reverse what the data adapter just did, but altogether less code than I imagined, I can keep my unescaped XML file, and it works well.

    • Marked as answer by Amanda Zhu Sunday, September 16, 2012 11:52 PM
    Friday, September 14, 2012 12:24 PM

All replies

  • Hello Goppeltm,

    Thank you for posting in the MSDN forum.

    Based on your description, I would like to know what the meaning of the embedded XML is.

    We can make an xml file as a data source for data-driven unit test.

    This is a good example for an xml file as a data source: http://myramserialize.blogspot.com/2008/07/visual-studio-and-data-driven-unit.html

    When you create the data driven unit test successfully, the following code is automatically added into the unit test file.

    [DataSource("Microsoft.VisualStudio.TestTools.DataSource.XML","|DataDirectory|\\Store.xml", "MyStore", DataAccessMethod.Sequential),DeploymentItem("TestProject2\\test.xml"),TestMethod()]

    In addition, you can refer to the following links about an example xml file including tables:

    http://social.msdn.microsoft.com/Forums/en-US/vststest/thread/059a98e6-2994-4da9-b03a-a8f0a8ef3448

    http://blogs.msdn.com/b/andyphilpotts/archive/2007/06/20/easily-bind-to-csv-or-xml-data-sources.aspx

    In addition, here is a help link about how to create a data-driven unit test:

    http://msdn.microsoft.com/en-us/library/ms182527(v=vs.100).aspx

    I hope it can help you.

    Best regards,


    Amanda Zhu [MSFT]
    MSDN Community Support | Feedback to us

    Monday, September 10, 2012 5:25 AM

  • Hello Amanda Zhu,

    thanks for your reply. I am already able to create and run a data driven test, so that's okay.

    About the embedded XML: for the sake of simplicity, let's say that I want to import data into my application, so my Application's "Import" method requires an XElement as parameter. So, my import requires an XML structure like: 

         <SubData Name="x">
           <SubItem/>
           <SubItem/>
         </SubData>

    So I thought: why not wrap this test data into a data driven test?

    <Test Name="Alpha">
         <SubData Name="x">
           <SubItem/>
           <SubItem/>
         </SubData>
    </Test>

    Unfortunately, the XML Data adapter seems to resolve ALL xml subnodes, no matter if they are part of the test data or not. I can actually see the Sub-Datarows, but the original xml structure seems lost. My current workaround is to escape the SubData with the CData attribute, and parse the contained string again as xml. But this is ugly, of course, and makes it difficult to query specific parts of the xml structure.


    • Edited by goppeltm Monday, September 10, 2012 7:30 AM clarification
    Monday, September 10, 2012 7:30 AM
  • Hello Goppeltm,

    Based on your description, it sounds like that it is very hard to query specific parts of xml structure and get test data if you create an xml file as a data source like the second xml schema that you posted.

    So I advise that you create an xml file like those examples in the links in my previous reply and bind it to the unit test as a data source. It is a feasible approach if you want to do a data-driven unit test and make an xml file as a data source.

    Best regards,


    Amanda Zhu [MSFT]
    MSDN Community Support | Feedback to us

    Monday, September 10, 2012 8:58 AM
  • Hm, maybe there is a misunderstanding. I don't want to query specific parts. My test signature looks like this:

    [DataSource("Microsoft.VisualStudio.TestTools.DataSource.XML","|DataDirectory|\\Testdata.xml", "Test", DataAccessMethod.Sequential) ,TestMethod()]

    So every "Test" node is processed as data driven test. So far, so good. But now I want the content of the current row.

    And my test logic basically says:

    string Testname = TestContext.DataRow.Field<String>["Name"];

    var testdata = TestContext.DataRow.Field<String>["???"];

    How do I retrieve the XML content of the current DataRow? If my test content was arbitrary text, it would just work fine, because the data driver won't try to pluck it apart and create sub-Datarows for it. Actually, if I escape my "SubData", it works perfectly fine, except I have to parse the content as XElement again.

    Monday, September 10, 2012 9:20 AM
  • Hello Goppeltm,

    Sorry for misunderstanding anything.

    Based on your description, the “SubData” node represents the test data.

    Now you don’t know how to retrieve the data in a SubData node . Am I right?

    As far as I know, when using an xml file as a data source for unit test, we usually create the xml file like a data table. We define a table in the xml file and set data rows and columns in the table like this:

    <Tablename>
    <
    Year>2011</Year>
    <
    Month>4</Month>
    <
    Day>22</Day>
    <
    Result>true</Result>
    </
    Tablename >
    <
    Tablename >
    <
    Year>2011</Year>
    <
    Month>12</Month>
    <
    Day>20</Day>
    <
    Result>false</Result>
    </
    Tablename >

    Then we can use TestContext.DataRow[NameOfColumn] to access the data of each row.  And we can select the access order.

    So I would like to know what the purpose that you set a sub data is. Does the “Test” node represent the unit test name?  And is the name different in different Test node?

    I advise that you can create a table in an xml file and set some columns which can be accessed directly.

    Best regards,


    Amanda Zhu [MSFT]
    MSDN Community Support | Feedback to us

    Monday, September 10, 2012 10:24 AM
  • Yes, correct: "Test" basically represents a single test, and the "Name" property is used to configure the test. All Test names are distinct. The Name property is not THAT important, I could live without it.

    The SubData is important. I can't flatten out or rearrange the SubData node, because my application requires a specific XML schema when importing. I could of course flatten the xml, and create a new XML structure on the fly which is compatible with my application... but this defeats my purpose that I can just copy & paste real test data as XML, and use it as-is.

    Monday, September 10, 2012 10:49 AM
  • Hello Gopoeltm,

    Based on all your description, I think you don’t create an xml file including a data table. In your situation, you get data from a pure xml file rather than from a table in the xml file.

    Actually it is not a feasible data source for unit test even though you bind it to unit test as a data source. TestContext.DataRow.Field<String>["Name"] statement can’t be used correctly in unit test method. DataRow Class represents a row of data in a DataTable. But what you define in the xml file is not a table and the data is not a row data. Even you can’t retrieve data through the TestContext.DataRow[columnname] statement which used to gets the current data row.

    If we want to do data-driven unit test which has an xml file as data source, normally we wrap data we need to use in unit test to a table and create this table in the xml file. Then we can retrieve the data through TestContext.DataRow[columnname] .

    Best regards,


    Amanda Zhu [MSFT]
    MSDN Community Support | Feedback to us

    Tuesday, September 11, 2012 4:49 AM
  • Hello Gopoeltm,

    Any update? Could you get useful information from our reply?

    Would you mind letting us know the result of the suggestion?

    Best regards,


    Amanda Zhu [MSFT]
    MSDN Community Support | Feedback to us

    Wednesday, September 12, 2012 5:48 AM
  • Hello Amanda Zhu,

    sorry, but I'm no step further. Yes, right, my SubData is no data table. Actually, I don't want it to be interpreted as such. What I want is a table with one or two columns, and one of the columns contains XML data.

    One possible, but ugly, solution is to escape my XML data:

    <root>
       <Test Name="Alpha">
         <![CDATA[
         <SubData Name="x">
           <SubItem/>
           <SubItem/>
         </SubData>
         ]]>
       </Test>
       <Test Name="Beta">
         <![CDATA[
         <SubData Name="y">
           <SubItem/>
         </SubData>
         ]]>
       </Test>
    </root>

    This way, the xml content is interpreted as String, i can access it via the column "Test_Text", and parse it as XML. Still: ugly. Because my plan was to use the same test data for multiple tests, and then it would have been beneficial to access the XML actually as XML, without the trouble of unescaping it first.

    Wednesday, September 12, 2012 8:04 AM
  • Hello Goppeltm,

    If you bind a data source which is an xml file to unit tests, the xml file must be like this:

    <Tablename>
    <Year>2011</Year>
    <Month>4</Month>
    <Day>22</Day>
    <Result>true</Result>
    < / Tablename >

    According to the example above, there is one table is in the xml file and one row and three columns are in the table. As far as I know we can’t define more than two levels in it like this if we make it as a data source for unit test:

    <Tablename>
         <Year>

             <SubItem>

              </SubItem>

         </Year>

    < / Tablename >

    Best regards,


    Amanda Zhu [MSFT]
    MSDN Community Support | Feedback to us

    • Marked as answer by Amanda Zhu Friday, September 14, 2012 12:46 AM
    Wednesday, September 12, 2012 8:42 AM
  • Well... the thing I learned from this lesson is, that I need to rethink how I store my test data for data driven tests. We have a lot of quite complex test data here, and multiple tests that share the same info.

    My feeling is, that this is quite a weak point from MS Test currently. Without proper queries, I have to split up my test data into a lot of files.

    So, my current solution looks like that: I return the sub- (and sub-sub) DataRows of each test row, like:

    var SubRows = TestContext.DataRow.GetChildRows("Test_SubData");

    and recreate my test data from it by reading each data field and storing. Not perfect, because I basically do exactly in reverse what the data adapter just did, but altogether less code than I imagined, I can keep my unescaped XML file, and it works well.

    • Marked as answer by Amanda Zhu Sunday, September 16, 2012 11:52 PM
    Friday, September 14, 2012 12:24 PM
  • For those who discover this years later, you can access the subnode data in test as follows (I'm using VS2015, perhaps this is a new feature ) :

    DataRow[] subdata = TestContext.DataRow.GetChildRows( "Test_SubData" );

    foreach( DataRow subdatum in subdata ) {

        DataRow[] details = subdatum.GetChildRows("SubData_SubItem");

        foreach( DataRow detail in details )

                System.Diagnostics.Debug.WriteLine( detail["SomeAttributeName"] ) );

      }

    Friday, October 30, 2015 3:33 PM