如何在VS C#的XML数据源测试中设置DisplayName
解决XML数据源单元测试用例自定义DisplayName的问题
核心思路
通过读取XML中预设的用例名称字段,结合TestContext或自定义特性,动态替换每个测试用例的显示名称,实现和DataRow一样的自定义命名效果。
具体实现方案
方案1:先序列化XML为对象,用DynamicData自定义名称
先把XML数据反序列化为实体集合,通过DynamicData加载数据源时,直接传入用例名称,同时利用TestContext设置显示名。
// 对应XML结构的实体类(需包含用例名字段) public class CalcTestCase { public int NumA { get; set; } public int NumB { get; set; } public int ExpectedSum { get; set; } public string CaseDisplayName { get; set; } } // XML数据加载工具 public static class XmlTestDataHelper { public static IEnumerable<object[]> LoadAddTestCases() { var xmlPath = @"Tests\AddTestData.xml"; var serializer = new XmlSerializer(typeof(List<CalcTestCase>)); using var reader = new StreamReader(xmlPath); var testCases = (List<CalcTestCase>)serializer.Deserialize(reader); return testCases.Select(tc => new object[] { tc.NumA, tc.NumB, tc.ExpectedSum, tc.CaseDisplayName }); } } // 测试类 [TestClass] public class CalculatorTests { [TestMethod] [DynamicData(nameof(XmlTestDataHelper.LoadAddTestCases), DynamicDataSourceType.Method)] public void AddTest(int numA, int numB, int expectedSum, string displayName) { // 给当前测试用例设置自定义名称 TestContext.Properties["DisplayName"] = displayName; // 测试逻辑 var calculator = new Calculator(); var result = calculator.Add(numA, numB); Assert.AreEqual(expectedSum, result); } public TestContext TestContext { get; set; } }
对应的XML示例(需包含CaseDisplayName字段):
<?xml version="1.0" encoding="utf-8" ?> <ArrayOfCalcTestCase> <CalcTestCase> <NumA>1</NumA> <NumB>2</NumB> <ExpectedSum>3</ExpectedSum> <CaseDisplayName>正数相加:1+2</CaseDisplayName> </CalcTestCase> <CalcTestCase> <NumA>-1</NumA> <NumB>-2</NumB> <ExpectedSum>-3</ExpectedSum> <CaseDisplayName>负数相加:(-1)+(-2)</CaseDisplayName> </CalcTestCase> </ArrayOfCalcTestCase>
方案2:基于原生DataSource自定义特性修改名称
如果不想改动数据源加载方式,直接用原生[DataSource]加载XML,可以自定义特性拦截测试启动事件,从DataRow中读取名称并替换显示名。
// 自定义DisplayName修改特性 [AttributeUsage(AttributeTargets.Method)] public class XmlCaseDisplayNameAttribute : Attribute, ITestMethodMessageSink { public bool Send(TestMessage message) { if (message is TestMethodStartingMessage startMsg) { var dataRow = startMsg.TestContext.DataRow; // 从XML的DataRow中读取预设的名称字段 var customName = dataRow["CaseDisplayName"]?.ToString(); if (!string.IsNullOrEmpty(customName)) { startMsg.DisplayName = customName; } } return true; } } // 测试类使用 [TestClass] public class CalculatorTests { [TestMethod] [DataSource("Microsoft.VisualStudio.TestTools.DataSource.XML", @"Tests\AddTestData.xml", "CalcTestCase", DataAccessMethod.Sequential)] [XmlCaseDisplayName] public void AddTest() { int numA = Convert.ToInt32(TestContext.DataRow["NumA"]); int numB = Convert.ToInt32(TestContext.DataRow["NumB"]); int expectedSum = Convert.ToInt32(TestContext.DataRow["ExpectedSum"]); var calculator = new Calculator(); var result = calculator.Add(numA, numB); Assert.AreEqual(expectedSum, result); } public TestContext TestContext { get; set; } }
关键注意点
- 必须在XML数据中为每个测试用例添加专属名称字段(比如
CaseDisplayName),否则无法读取自定义名称。 - 方案1灵活性更高,适合需要提前处理测试数据的场景;方案2更贴近原生
DataSource的使用习惯,无需改动数据源加载逻辑。
内容的提问来源于stack exchange,提问作者מעין אפשטיין
相关产品推荐
相关产品推荐

