diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TestMethodRunner.cs b/src/Adapter/MSTest.TestAdapter/Execution/TestMethodRunner.cs index b8a8a5cba..37e8f0352 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TestMethodRunner.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TestMethodRunner.cs @@ -354,8 +354,8 @@ internal class TestMethodRunner private TestResult[] ExecuteTestWithDataSource(UTF.ITestDataSource? testDataSource, object?[]? data) { var stopwatch = Stopwatch.StartNew(); - _testMethodInfo.SetArguments(data); + _testContext.SetTestData(data); TestResult[] testResults = ExecuteTest(_testMethodInfo); stopwatch.Stop(); diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITestContext.cs b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITestContext.cs index 01dfd0681..8dd0199c6 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITestContext.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITestContext.cs @@ -42,6 +42,13 @@ public interface ITestContext /// data row. void SetDataRow(object? dataRow); + /// + /// Sets the data that will be provided to the test. + /// For non-parameterized tests, the value will be . + /// + /// The data. + void SetTestData(object?[]? data); + /// /// Set connection for TestContext. /// diff --git a/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/PublicAPI.Unshipped.txt b/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/PublicAPI.Unshipped.txt index ab058de62..1e54e7564 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/PublicAPI.Unshipped.txt +++ b/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/PublicAPI.Unshipped.txt @@ -1 +1,3 @@ #nullable enable +Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ITestContext.SetTestData(object?[]? data) -> void +Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.TestContextImplementation.SetTestData(object?[]? data) -> void diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/TestContextImplementation.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/TestContextImplementation.cs index d890e3b3e..a976f5742 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/TestContextImplementation.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/TestContextImplementation.cs @@ -269,6 +269,9 @@ public class TestContextImplementation : TestContext, ITestContext #endif } + /// + public void SetTestData(object?[]? data) => TestData = data; + /// /// Set connection for TestContext. /// diff --git a/src/TestFramework/TestFramework.Extensions/PublicAPI/PublicAPI.Unshipped.txt b/src/TestFramework/TestFramework.Extensions/PublicAPI/PublicAPI.Unshipped.txt index 91b0e1a43..f57ac19b7 100644 --- a/src/TestFramework/TestFramework.Extensions/PublicAPI/PublicAPI.Unshipped.txt +++ b/src/TestFramework/TestFramework.Extensions/PublicAPI/PublicAPI.Unshipped.txt @@ -1 +1,3 @@ -#nullable enable \ No newline at end of file +#nullable enable +Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestData.get -> object?[]? +Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestData.set -> void \ No newline at end of file diff --git a/src/TestFramework/TestFramework.Extensions/TestContext.cs b/src/TestFramework/TestFramework.Extensions/TestContext.cs index 8e560b463..aafae1685 100644 --- a/src/TestFramework/TestFramework.Extensions/TestContext.cs +++ b/src/TestFramework/TestFramework.Extensions/TestContext.cs @@ -53,6 +53,8 @@ public abstract class TestContext /// public virtual CancellationTokenSource CancellationTokenSource { get; protected set; } = new(); + public object?[]? TestData { get; protected set; } + #if NETFRAMEWORK /// /// Gets the current data row when test is used for data driven testing. diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TestContextTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TestContextTests.cs index 7451b80d8..01738fc86 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TestContextTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TestContextTests.cs @@ -17,13 +17,23 @@ public sealed class TestContextTests : AcceptanceTestBase public async Task TestContextsAreCorrectlySet() { var testHost = TestHost.LocateFrom(_testAssetFixture.ProjectPath, TestAssetFixture.ProjectName, TargetFrameworks.NetCurrent.Arguments); - TestHostResult testHostResult = await testHost.ExecuteAsync(); + TestHostResult testHostResult = await testHost.ExecuteAsync("--filter ClassName~TestContextCtor"); // Assert testHostResult.AssertExitCodeIs(0); testHostResult.AssertOutputContainsSummary(failed: 0, passed: 4, skipped: 0); } + public async Task TestContext_TestData_PropertyContainsExpectedValue() + { + var testHost = TestHost.LocateFrom(_testAssetFixture.ProjectPath, TestAssetFixture.ProjectName, TargetFrameworks.NetCurrent.Arguments); + TestHostResult testHostResult = await testHost.ExecuteAsync("--filter ClassName~TestContextData"); + + // Assert + testHostResult.AssertExitCodeIs(0); + testHostResult.AssertOutputContainsSummary(failed: 0, passed: 3, skipped: 0); + } + [TestFixture(TestFixtureSharingStrategy.PerTestGroup)] public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : TestAssetFixtureBase(acceptanceFixture.NuGetGlobalPackagesFolder) { @@ -56,6 +66,7 @@ public sealed class TestContextTests : AcceptanceTestBase #file UnitTest1.cs +using System.Collections.Generic; using Microsoft.VisualStudio.TestTools.UnitTesting; [TestClass] @@ -126,6 +137,106 @@ public class TestContextCtorDerived : TestContextCtor _testContext.WriteLine("Method TestContextCtorDerived.DerivedTestMethod() was called"); } } + +[TestClass] +public class TestContextDataFromNonParameterizedMethod +{ + public TestContext TestContext { get; set; } + + [TestInitialize] + public void TInit() + { + AssertTestContextData(); + } + + [TestMethod] + public void Test() + { + AssertTestContextData(); + } + + [TestCleanup] + public void TCleanup() + { + AssertTestContextData(); + } + + private void AssertTestContextData() + { + Assert.IsNull(TestContext.TestData); + } +} + +[TestClass] +public class TestContextDataFromDataRow +{ + public TestContext TestContext { get; set; } + + [TestInitialize] + public void TInit() + { + AssertTestContextData(); + } + + [TestMethod] + [DataRow(1, "ok")] + public void Test(int i, string s) + { + AssertTestContextData(); + } + + [TestCleanup] + public void TCleanup() + { + AssertTestContextData(); + } + + private void AssertTestContextData() + { + Assert.IsNotNull(TestContext.TestData); + Assert.AreEqual(2, TestContext.TestData.Length); + Assert.AreEqual(1, TestContext.TestData[0]); + Assert.AreEqual("ok", TestContext.TestData[1]); + } +} + +[TestClass] +public class TestContextDataFromDynamicData +{ + public TestContext TestContext { get; set; } + + [TestInitialize] + public void TInit() + { + AssertTestContextData(); + } + + [TestMethod] + [DynamicData(nameof(GetData), DynamicDataSourceType.Method)] + public void Test(int i, string s) + { + AssertTestContextData(); + } + + [TestCleanup] + public void TCleanup() + { + AssertTestContextData(); + } + + private void AssertTestContextData() + { + Assert.IsNotNull(TestContext.TestData); + Assert.AreEqual(2, TestContext.TestData.Length); + Assert.AreEqual(1, TestContext.TestData[0]); + Assert.AreEqual("ok", TestContext.TestData[1]); + } + + private static IEnumerable GetData() + { + yield return new object[] { 1, "ok" }; + } +} """; } }