diff --git a/Directory.Packages.props b/Directory.Packages.props
index 067fb557aa..6cf5f65432 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -4,6 +4,7 @@
true
+ 8.0.0
8.2.2
17.11.4
3.11.0-beta1.24508.2
@@ -31,6 +32,7 @@
+
diff --git a/TestFx.sln b/TestFx.sln
index 5817cde0bc..e1460ab160 100644
--- a/TestFx.sln
+++ b/TestFx.sln
@@ -209,6 +209,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Testing.Platform.
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Testing.Extensions.MSBuild", "src\Platform\Microsoft.Testing.Extensions.MSBuild\Microsoft.Testing.Extensions.MSBuild.csproj", "{8CE782A2-7374-4916-9C69-1F87E51A64A9}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MSTest.DataSource.Csv", "src\TestFramework\TestFramework.Extensions.Csv\MSTest.DataSource.Csv.csproj", "{536A4485-F77F-4617-8449-2DCB387514AB}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MSTest.DataSource.Xml", "src\TestFramework\TestFramework.Extensions.Xml\MSTest.DataSource.Xml.csproj", "{7BF7BE9E-8D46-47ED-B45D-121C2252DF16}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -483,6 +487,14 @@ Global
{8CE782A2-7374-4916-9C69-1F87E51A64A9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8CE782A2-7374-4916-9C69-1F87E51A64A9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8CE782A2-7374-4916-9C69-1F87E51A64A9}.Release|Any CPU.Build.0 = Release|Any CPU
+ {536A4485-F77F-4617-8449-2DCB387514AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {536A4485-F77F-4617-8449-2DCB387514AB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {536A4485-F77F-4617-8449-2DCB387514AB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {536A4485-F77F-4617-8449-2DCB387514AB}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7BF7BE9E-8D46-47ED-B45D-121C2252DF16}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7BF7BE9E-8D46-47ED-B45D-121C2252DF16}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7BF7BE9E-8D46-47ED-B45D-121C2252DF16}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7BF7BE9E-8D46-47ED-B45D-121C2252DF16}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -567,6 +579,8 @@ Global
{573C617F-6BB2-403A-AD87-E00A7FD537F0} = {BB874DF1-44FE-415A-B634-A6B829107890}
{F422398C-72CD-43EA-AC8E-E0DBD08E5563} = {BB874DF1-44FE-415A-B634-A6B829107890}
{8CE782A2-7374-4916-9C69-1F87E51A64A9} = {6AEE1440-FDF0-4729-8196-B24D0E333550}
+ {536A4485-F77F-4617-8449-2DCB387514AB} = {E48AC786-E150-4F41-9A16-32F02E4493D8}
+ {7BF7BE9E-8D46-47ED-B45D-121C2252DF16} = {E48AC786-E150-4F41-9A16-32F02E4493D8}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {31E0F4D5-975A-41CC-933E-545B2201FAF9}
diff --git a/eng/verify-nupkgs.ps1 b/eng/verify-nupkgs.ps1
index d119680355..a025aa042c 100644
--- a/eng/verify-nupkgs.ps1
+++ b/eng/verify-nupkgs.ps1
@@ -22,6 +22,8 @@ function Confirm-NugetPackages {
"MSTest.Sdk" = 15;
"MSTest.Internal.TestFx.Documentation" = 10;
"MSTest.TestFramework" = 130;
+ "MSTest.DataSource.Csv" = 7;
+ "MSTest.DataSource.Xml" = 7;
"MSTest.TestAdapter" = 76;
"MSTest" = 6;
"MSTest.Analyzers" = 10;
diff --git a/src/TestFramework/TestFramework.Extensions.Csv/CsvDataSourceAttribute.cs b/src/TestFramework/TestFramework.Extensions.Csv/CsvDataSourceAttribute.cs
new file mode 100644
index 0000000000..69ef54d2d7
--- /dev/null
+++ b/src/TestFramework/TestFramework.Extensions.Csv/CsvDataSourceAttribute.cs
@@ -0,0 +1,88 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System.Data;
+using System.Data.OleDb;
+using System.Globalization;
+using System.Reflection;
+
+using Microsoft.VisualStudio.TestTools.UnitTesting.Internal;
+
+namespace Microsoft.VisualStudio.TestTools.UnitTesting;
+
+///
+/// Attribute to define dynamic data from a CSV file for a test method.
+///
+[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
+public sealed class CsvDataSourceAttribute : Attribute, ITestDataSource
+{
+ // Template used to map from a filename to a DB connection string
+ private const string CsvConnectionTemplate = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Persist Security Info=False;Extended Properties=\"text;HDR=YES;FMT=Delimited\"";
+ private const string CsvConnectionTemplate64 = "Provider=Microsoft.Ace.OLEDB.12.0;Data Source={0};Persist Security Info=False;Extended Properties=\"text;HDR=YES;FMT=Delimited\"";
+
+ public CsvDataSourceAttribute(string fileName)
+ => FileName = fileName;
+
+ internal string FileName { get; }
+
+ IEnumerable
@@ -52,6 +57,7 @@ public class DataSourceTests : AcceptanceTestBase
#file MyTestClass.cs
+using System.Data;
using Microsoft.VisualStudio.TestTools.UnitTesting;
[TestClass]
@@ -61,7 +67,7 @@ public class MyTestClass
[DataTestMethod]
[DataSource("TestData")]
- public void TestSum()
+ public void TestSumDataSource()
{
int expected = (int)TestContext.DataRow["expectedSum"];
int num1 = (int)TestContext.DataRow["num1"];
@@ -69,6 +75,26 @@ public void TestSum()
Assert.AreEqual(expected, num1 + num2);
}
+ [TestMethod]
+ [CsvDataSource("TestData.csv")]
+ public void TestSumCsv(DataRow dataRow)
+ {
+ int expected = (int)dataRow["expectedSum"];
+ int num1 = (int)dataRow["num1"];
+ int num2 = (int)dataRow["num2"];
+ Assert.AreEqual(expected, num1 + num2);
+ }
+
+ [TestMethod]
+ [XmlDataSource("TestData.xml", "MyTable")]
+ public void TestSumXml(DataRow dataRow)
+ {
+ int expected = (int)dataRow["ExpectedSum"];
+ int num1 = (int)dataRow["Num1"];
+ int num2 = (int)dataRow["Num2"];
+ Assert.AreEqual(expected, num1 + num2);
+ }
+
[TestMethod]
public void MyTest()
{
@@ -81,6 +107,31 @@ public void MyTest()
5,6,11
10,30,40
1,1,1
+
+#file TestData.xml
+
+
+
+ 1
+ 1
+ 2
+
+
+ 5
+ 6
+ 11
+
+
+ 10
+ 30
+ 40
+
+
+ 1
+ 1
+ 1
+
+
""";
private readonly AcceptanceFixture _acceptanceFixture;
@@ -112,6 +163,6 @@ await DotnetCli.RunAsync(
TestHostResult result = await testHost.ExecuteAsync();
result.AssertExitCodeIs(ExitCodes.AtLeastOneTestFailed);
- result.AssertOutputContainsSummary(failed: 1, passed: 4, skipped: 0);
+ result.AssertOutputContainsSummary(failed: 3, passed: 10, skipped: 0);
}
}