diff --git a/src/Adapter/MSTest.TestAdapter/Constants.cs b/src/Adapter/MSTest.TestAdapter/Constants.cs index f110859dc8..af2738fc9e 100644 --- a/src/Adapter/MSTest.TestAdapter/Constants.cs +++ b/src/Adapter/MSTest.TestAdapter/Constants.cs @@ -123,6 +123,8 @@ internal static class Constants internal static readonly TestProperty TestDynamicDataProperty = TestProperty.Register("MSTest.DynamicData", "DynamicData", typeof(string[]), TestPropertyAttributes.Hidden, typeof(TestCase)); internal static readonly TestProperty TestIdGenerationStrategyProperty = TestProperty.Register("MSTest.TestIdGenerationStrategy", "TestIdGenerationStrategy", typeof(int), TestPropertyAttributes.Hidden, typeof(TestCase)); + + internal static readonly TestProperty TestDataSourceIgnoreReasonProperty = TestProperty.Register("MSTest.TestDataSourceIgnoreReasonProperty", "TestDataSourceIgnoreReasonProperty", typeof(string), TestPropertyAttributes.Hidden, typeof(TestCase)); #endregion #region Private Constants diff --git a/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumerator.cs b/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumerator.cs index 1144be3949..21321b9e01 100644 --- a/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumerator.cs +++ b/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumerator.cs @@ -423,7 +423,7 @@ private static bool TryUnfoldITestDataSource(ITestDataSource dataSource, TestDat // This code is to discover tests. To run the tests code is in TestMethodRunner.ExecuteDataSourceBasedTests. // Any change made here should be reflected in TestMethodRunner.ExecuteDataSourceBasedTests as well. data = dataSource.GetData(methodInfo); - string? ignoreReason = (dataSource as ITestDataSourceIgnoreCapability)?.Ignore; + string? testDataSourceIgnoreReason = (dataSource as ITestDataSourceIgnoreCapability)?.Ignore; if (!data.Any()) { @@ -435,6 +435,7 @@ private static bool TryUnfoldITestDataSource(ITestDataSource dataSource, TestDat UnitTestElement discoveredTest = test.Clone(); // Make the test not data driven, because it had no data. discoveredTest.TestMethod.DataType = DynamicDataType.None; + discoveredTest.TestMethod.TestDataSourceIgnoreReason = testDataSourceIgnoreReason; discoveredTest.DisplayName = dataSource.GetDisplayName(methodInfo, null) ?? discoveredTest.DisplayName; tests.Add(discoveredTest); @@ -468,6 +469,7 @@ private static bool TryUnfoldITestDataSource(ITestDataSource dataSource, TestDat try { discoveredTest.TestMethod.SerializedData = DataSerializationHelper.Serialize(d); + discoveredTest.TestMethod.TestDataSourceIgnoreReason = testDataSourceIgnoreReason; discoveredTest.TestMethod.DataType = DynamicDataType.ITestDataSource; } catch (SerializationException ex) diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TestMethodRunner.cs b/src/Adapter/MSTest.TestAdapter/Execution/TestMethodRunner.cs index a3ee59fa98..a3f52e67d9 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TestMethodRunner.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TestMethodRunner.cs @@ -168,6 +168,11 @@ internal UnitTestResult[] RunTestMethod() { if (_test.DataType == DynamicDataType.ITestDataSource) { + if (_test.TestDataSourceIgnoreReason is not null) + { + return [new(UnitTestOutcome.Ignored, _test.TestDataSourceIgnoreReason)]; + } + object?[]? data = DataSerializationHelper.Deserialize(_test.SerializedData); TestResult[] testResults = ExecuteTestWithDataSource(null, data); results.AddRange(testResults); @@ -306,6 +311,20 @@ private bool ExecuteDataSourceBasedTests(List results) foreach (UTF.ITestDataSource testDataSource in testDataSources) { isDataDriven = true; + + if (testDataSource is ITestDataSourceIgnoreCapability { Ignore: { } ignoreReason }) + { + results.Add(new() + { + // This is closest to ignore. This enum doesn't have a value specific to Ignore. + // It may be a better idea to add a value there, but the enum is public and we need to think more carefully before adding the API. + // For now, TestResultExtensions.ToUnitTestResults method will convert this to Ignored value of ObjectModel enum when IgnoreReason is non-null. + Outcome = UTF.UnitTestOutcome.NotRunnable, + IgnoreReason = ignoreReason, + }); + continue; + } + IEnumerable? dataSource; // This code is to execute tests. To discover the tests code is in AssemblyEnumerator.ProcessTestDataSourceTests. diff --git a/src/Adapter/MSTest.TestAdapter/Extensions/TestCaseExtensions.cs b/src/Adapter/MSTest.TestAdapter/Extensions/TestCaseExtensions.cs index c0ed82d9cb..3e8b0207a8 100644 --- a/src/Adapter/MSTest.TestAdapter/Extensions/TestCaseExtensions.cs +++ b/src/Adapter/MSTest.TestAdapter/Extensions/TestCaseExtensions.cs @@ -86,6 +86,7 @@ internal static UnitTestElement ToUnitTestElement(this TestCase testCase, string testMethod.DataType = dataType; testMethod.SerializedData = data; + testMethod.TestDataSourceIgnoreReason = testCase.GetPropertyValue(Constants.TestDataSourceIgnoreReasonProperty) as string; } if (testCase.GetPropertyValue(Constants.DeclaringClassNameProperty) is string declaringClassName && declaringClassName != testClassName) diff --git a/src/Adapter/MSTest.TestAdapter/Extensions/TestResultExtensions.cs b/src/Adapter/MSTest.TestAdapter/Extensions/TestResultExtensions.cs index 301984dbb1..a600eeb218 100644 --- a/src/Adapter/MSTest.TestAdapter/Extensions/TestResultExtensions.cs +++ b/src/Adapter/MSTest.TestAdapter/Extensions/TestResultExtensions.cs @@ -29,7 +29,9 @@ internal static UnitTestResult[] ToUnitTestResults(this IReadOnlyCollection internal string?[]? SerializedData { get; set; } + internal string? TestDataSourceIgnoreReason { get; set; } + /// /// Gets or sets the test group set during discovery. /// diff --git a/src/Adapter/MSTest.TestAdapter/ObjectModel/UnitTestElement.cs b/src/Adapter/MSTest.TestAdapter/ObjectModel/UnitTestElement.cs index e180078f4b..35aab5c9e1 100644 --- a/src/Adapter/MSTest.TestAdapter/ObjectModel/UnitTestElement.cs +++ b/src/Adapter/MSTest.TestAdapter/ObjectModel/UnitTestElement.cs @@ -206,6 +206,7 @@ internal TestCase ToTestCase() testCase.SetPropertyValue(Constants.TestDynamicDataTypeProperty, (int)TestMethod.DataType); testCase.SetPropertyValue(Constants.TestDynamicDataProperty, data); + testCase.SetPropertyValue(Constants.TestDataSourceIgnoreReasonProperty, TestMethod.TestDataSourceIgnoreReason); } SetTestCaseId(testCase, testFullName); diff --git a/src/TestFramework/TestFramework/Attributes/TestMethod/TestResult.cs b/src/TestFramework/TestFramework/Attributes/TestMethod/TestResult.cs index 1b0b35fe7b..0ccf2e316c 100644 --- a/src/TestFramework/TestFramework/Attributes/TestMethod/TestResult.cs +++ b/src/TestFramework/TestFramework/Attributes/TestMethod/TestResult.cs @@ -24,6 +24,8 @@ public class TestResult /// public UnitTestOutcome Outcome { get; set; } + internal string? IgnoreReason { get; set; } + /// /// Gets or sets the exception thrown when test is failed. ///