diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 529b3077ac..c7327adfd6 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -77,6 +77,14 @@ stages: failOnStderr: true showWarnings: true + - task: PowerShell@2 + displayName: 'Install Access Database Engine' + inputs: + targetType: filePath + filePath: ./eng/install-access-database-engine.ps1 + failOnStderr: true + showWarnings: true + - script: eng\common\CIBuild.cmd -configuration $(_BuildConfig) -prepareMachine diff --git a/eng/install-access-database-engine.ps1 b/eng/install-access-database-engine.ps1 new file mode 100644 index 0000000000..3ff7705794 --- /dev/null +++ b/eng/install-access-database-engine.ps1 @@ -0,0 +1,7 @@ +# This is required for DataSourceTests +# Otherwise, the tests will fail with: +# The unit test adapter failed to connect to the data source or to read the data. For more information on troubleshooting this error, see "Troubleshooting Data-Driven Unit Tests" (http://go.microsoft.com/fwlink/?LinkId=62412) in the MSDN Library. Error details: The 'Microsoft.Ace.OLEDB.12.0' provider is not registered on the local machine. +# at Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.TestDataSource.GetData(ITestMethod testMethodInfo, ITestContext testContext) in /_/src/Adapter/MSTestAdapter.PlatformServices/Services/TestDataSource.cs:84 +# The direct download link originates from https://www.microsoft.com/en-us/download/details.aspx?id=54920&msockid=01fa77be234c617f31936293223560aa +Invoke-RestMethod https://download.microsoft.com/download/3/5/C/35C84C36-661A-44E6-9324-8786B8DBE231/accessdatabaseengine_X64.exe -OutFile ./accessdatabaseengine_X64.exe +Start-Process ./accessdatabaseengine_X64.exe -Wait -ArgumentList "/quiet /passive /norestart" diff --git a/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumerator.cs b/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumerator.cs index c820ee0e9c..f2015d0c41 100644 --- a/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumerator.cs +++ b/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumerator.cs @@ -285,10 +285,7 @@ private static bool DynamicDataAttached(UnitTestElement test, Lazy tests, HashSet fixtureTests) @@ -381,7 +386,7 @@ static UnitTestElement GetFixtureTest(string classFullName, string assemblyLocat } } - private static bool TryProcessTestDataSourceTests(UnitTestElement test, TestMethodInfo testMethodInfo, List tests) + private static bool TryProcessITestDataSourceTests(UnitTestElement test, TestMethodInfo testMethodInfo, List tests) { // We don't have a special method to filter attributes that are not derived from Attribute, so we take all // attributes and filter them. We don't have to care if there is one, because this method is only entered when @@ -390,7 +395,7 @@ private static bool TryProcessTestDataSourceTests(UnitTestElement test, TestMeth try { - return ProcessTestDataSourceTests(test, new(testMethodInfo.MethodInfo, test.DisplayName), testDataSources, tests); + return ProcessITestDataSourceTests(test, new(testMethodInfo.MethodInfo, test.DisplayName), testDataSources, tests); } catch (Exception ex) { @@ -400,7 +405,7 @@ private static bool TryProcessTestDataSourceTests(UnitTestElement test, TestMeth } } - private static bool ProcessTestDataSourceTests(UnitTestElement test, ReflectionTestMethodInfo methodInfo, IEnumerable testDataSources, + private static bool ProcessITestDataSourceTests(UnitTestElement test, ReflectionTestMethodInfo methodInfo, IEnumerable testDataSources, List tests) { foreach (ITestDataSource dataSource in testDataSources) diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/DataSourceTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/DataSourceTests.cs new file mode 100644 index 0000000000..375dedad5f --- /dev/null +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/DataSourceTests.cs @@ -0,0 +1,117 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using Microsoft.Testing.Platform.Acceptance.IntegrationTests; +using Microsoft.Testing.Platform.Acceptance.IntegrationTests.Helpers; +using Microsoft.Testing.Platform.Helpers; + +namespace MSTest.Acceptance.IntegrationTests; + +[TestGroup] +public class DataSourceTests : AcceptanceTestBase +{ + private const string SourceCode = """ +#file DataSourceTests.csproj + + + net472 + enable + Exe + preview + true + + + + + + + + PreserveNewest + + + + +#file App.config + + + +
+ + + + + + + + + + + + + + + +#file MyTestClass.cs +using Microsoft.VisualStudio.TestTools.UnitTesting; + +[TestClass] +public class MyTestClass +{ + public TestContext TestContext { get; set; } + + [DataTestMethod] + [DataSource("TestData")] + public void TestSum() + { + int expected = (int)TestContext.DataRow["expectedSum"]; + int num1 = (int)TestContext.DataRow["num1"]; + int num2 = (int)TestContext.DataRow["num2"]; + Assert.AreEqual(expected, num1 + num2); + } + + [TestMethod] + public void MyTest() + { + } +} + +#file TestData.csv +num1,num2,expectedSum +1,1,2 +5,6,11 +10,30,40 +1,1,1 +"""; + + private readonly AcceptanceFixture _acceptanceFixture; + + public DataSourceTests(ITestExecutionContext testExecutionContext, AcceptanceFixture acceptanceFixture) + : base(testExecutionContext) => _acceptanceFixture = acceptanceFixture; + + public async Task TestDataSourceFromAppConfig() + { + if (!OperatingSystem.IsWindows()) + { + // Test is specific to .NET Framework. + return; + } + + using TestAsset generator = await TestAsset.GenerateAssetAsync( + "DataSourceTests", + SourceCode + .PatchCodeWithReplace("$MSTestVersion$", MSTestVersion) + .PatchCodeWithReplace("$MicrosoftNETTestSdkVersion$", MicrosoftNETTestSdkVersion), + addPublicFeeds: true); + + await DotnetCli.RunAsync( + $"build {generator.TargetAssetPath} -c Release", + _acceptanceFixture.NuGetGlobalPackagesFolder.Path, + retryCount: 0); + + var testHost = TestHost.LocateFrom(generator.TargetAssetPath, "DataSourceTests", "net472"); + + TestHostResult result = await testHost.ExecuteAsync(); + result.AssertExitCodeIs(ExitCodes.AtLeastOneTestFailed); + result.AssertOutputContainsSummary(failed: 1, passed: 4, skipped: 0); + } +}