0

i am a student, i cant find how i giva a name for each of my tests when i am using xml file. when we use datarow we can use displayname="". and then when i will run the tests evry test will have its own name. how can i do it when i use xml file in my test? im usung vs c# my xml file:

<?xml version="1.0" encoding="utf-8" ?>
<tar>
    <IsEarlier  Name="General" DisplayName="General">
        <hour1>13</hour1>
        <min1>15</min1>
        <hour2>13</hour2>
        <min2>17</min2>
        <res>true</res>
    </IsEarlier>

    <IsEarlier>
        <hour1>13</hour1>
        <min1>15</min1>
        <hour2>13</hour2>
        <min2>15</min2>
        <res>false</res>
    </IsEarlier>
    
    <IsEarlier DisplayName="check_clock">
        <hour1>13</hour1>
        <min1>15</min1>
        <hour2>13</hour2>
        <min2>15</min2>
        <res>false</res>
    </IsEarlier>

</tar>

my test:

[TestClass]
    public class UnitTest1
    {

        private TestContext context;
        public TestContext TestContext
        {
            get { return context; }
            set { context = value; }
        }


        [TestMethod]
        [DataSource("Microsoft.VisualStudio.TestTools.DataSource.XML",
            @"|DataDirectory|\TestDate\Clock.xml",
            "IsEarlier",
            DataAccessMethod.Sequential)]
        public void IsEarlierByXML()
        {
            int h1  = Convert.ToInt32(TestContext.DataRow["hour1"].ToString());
            int m1  = Convert.ToInt32(TestContext.DataRow["min1"].ToString());
            Clock.Clock c1 = new Clock.Clock(h1, m1);

            int h2 = Convert.ToInt32(TestContext.DataRow["hour2"].ToString());
            int m2 = Convert.ToInt32(TestContext.DataRow["min2"].ToString());
            Clock.Clock c2 = new Clock.Clock(h2, m2);


            bool expected = Convert.ToBoolean(TestContext.DataRow["res"].ToString());
            bool actual;

            actual = c1.IsEarlier(c2);

            Assert.IsTrue(expected == actual);
        }

  • Please read [ask] and apply suitable tags to your question (click "Edit tags" to do this). At a minimum you should add the programming language and test framework you are using. This doesn't seem to be a question about XML in the general sense, so you probably don't need that tag. – Quentin Jun 17 '23 at 16:46

2 Answers2

0

(BTW: The same option exists in Visual Studio. Via Edit/Paste Special/Paste XML as Classes)

It will show C# code which can be used to serialize your XML

   /* 
    Licensed under the Apache License, Version 2.0
    
    http://www.apache.org/licenses/LICENSE-2.0
    */
using System;
using System.Xml.Serialization;
using System.Collections.Generic;
namespace Xml2CSharp
{
    [XmlRoot(ElementName="IsEarlier")]
    public class IsEarlier {
        [XmlElement(ElementName="hour1")]
        public string Hour1 { get; set; }
        [XmlElement(ElementName="min1")]
        public string Min1 { get; set; }
        [XmlElement(ElementName="hour2")]
        public string Hour2 { get; set; }
        [XmlElement(ElementName="min2")]
        public string Min2 { get; set; }
        [XmlElement(ElementName="res")]
        public string Res { get; set; }
        [XmlAttribute(AttributeName="Name")]
        public string Name { get; set; }
        [XmlAttribute(AttributeName="DisplayName")]
        public string DisplayName { get; set; }
    }

    [XmlRoot(ElementName="tar")]
    public class Tar {
        [XmlElement(ElementName="IsEarlier")]
        public List<IsEarlier> IsEarlier { get; set; }
    }

}

This class also contains a definition for the attribute DisplayName.

Luuk
  • 12,245
  • 5
  • 22
  • 33
0

The class file(s) would be .cs and best practice is usually one file per class with the class name and the filename matching, like IsEarlier.cs and Tar.cs. If you wanted them in the same file, something like ClockTestData.cs would make sense and maybe the same name instead of "Tar" for the list class.

Once you have the IsEarlier and Tar classes defined (as Luuk helped with), use the XmlSerializer to populate the class with your XML content. https://learn.microsoft.com/en-us/dotnet/standard/serialization/how-to-deserialize-an-object (so, something like this)

var xmlSerializer = new XmlSerializer(typeof(Tar));
using var fileStream = new FileStream("clock.xml", FileMode.Open);
var tar = (Tar)xmlSerializer.Deserialize(fileStream);

(Note in my example, the objects have the same names as the classes except camelCase vs PascalCase).

Then you'd be able to loop through the IsEarlier items in your tar.IsEarlier list and perform each test. E.g., if isEarlier is your object assigned in a foreach or for loop,

Clock.Clock c1 = new Clock.Clock(isEarlier.Hour1, isEarlier.Min1);
GaryGI
  • 46
  • 4
  • Since you are defining the xml structure and the classes to receive the XML data, deserialization is a nice, clean, typesafe way to handle this. If you are interested in other ways to read XML that can be made more robust when you are not the author of the XML, check out the hireDate example for the XmlReader class: https://learn.microsoft.com/en-us/dotnet/api/system.xml.xmlreader?view=net-7.0 – GaryGI Jun 19 '23 at 12:04