Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DataSource draft #4112

Draft
wants to merge 11 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
</PropertyGroup>
<PropertyGroup Label="Product dependencies">
<SystemDataOleDbVersion>8.0.0</SystemDataOleDbVersion>
<AspireHostingTestingVersion>8.2.2</AspireHostingTestingVersion>
<MicrosoftBuildVersion>17.11.4</MicrosoftBuildVersion>
<MicrosoftCodeAnalysisAnalyzersVersion>3.11.0-beta1.24508.2</MicrosoftCodeAnalysisAnalyzersVersion>
Expand Down Expand Up @@ -31,6 +32,7 @@
<PackageVersion Include="StyleCop.Analyzers" Version="1.2.0-beta.556" />
</ItemGroup>
<ItemGroup Label="Product dependencies">
<PackageVersion Include="System.Data.OleDb" Version="$(SystemDataOleDbVersion)" />
<PackageVersion Include="Microsoft.ApplicationInsights" Version="2.22.0" />
<PackageVersion Include="Microsoft.Build.Framework" Version="$(MicrosoftBuildVersion)" />
<PackageVersion Include="Microsoft.Build.Utilities.Core" Version="$(MicrosoftBuildVersion)" />
Expand Down
14 changes: 14 additions & 0 deletions TestFx.sln
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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}
Expand Down
2 changes: 2 additions & 0 deletions eng/verify-nupkgs.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
@@ -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;

/// <summary>
/// Attribute to define dynamic data from a CSV file for a test method.
/// </summary>
[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<object?[]> ITestDataSource.GetData(MethodInfo methodInfo)
{
// TODO: Avoid using OleDb and instead parse Csv directly. Maybe use https://www.nuget.org/packages/CsvHelper? Write our own?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would definitely avoid writing our own. 😁

// When that happens, the OleDb dependency in the csproj should be
// removed, and relevant tests for CsvDataSource should run on Linux.

// We better work with a full path, if nothing else, errors become easier to report
string fullPath = Path.GetFullPath(FileName);
if (!File.Exists(fullPath))
{
// TODO: Localize.
throw new FileNotFoundException($"Csv file '{fullPath}' cannot be found.", fullPath);
}

using OleDbConnection connection = new();

// We have to use the name of the folder which contains the CSV file in the connection string
// If target platform is x64, then use CsvConnectionTemplate64 connection string.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will this work also on arm64?

connection.ConnectionString = IntPtr.Size == 8
? string.Format(CultureInfo.InvariantCulture, CsvConnectionTemplate64, Path.GetDirectoryName(fullPath))
: string.Format(CultureInfo.InvariantCulture, CsvConnectionTemplate, Path.GetDirectoryName(fullPath));

// We have to open the connection now, before we try to quote
// the table name, otherwise QuoteIdentifier fails (for OleDb, go figure!)
// The connection will get closed when we dispose of it
connection.Open();

using OleDbCommandBuilder commandBuilder = new();
string tableName = Path.GetFileName(fullPath).Replace('.', '#');
string quotedTableName = commandBuilder.QuoteIdentifier(tableName, connection);

using OleDbCommand command = new()
{
Connection = connection,
CommandText = $"SELECT * FROM {quotedTableName}",
};

using OleDbDataAdapter dataAdapter = new()
{
SelectCommand = command,
};

DataTable table = new()
{
Locale = CultureInfo.InvariantCulture,
};

dataAdapter.Fill(table);

object?[][] dataRows = new object?[table.Rows.Count][];
for (int i = 0; i < dataRows.Length; i++)
{
dataRows[i] = [table.Rows[i]];
}

return dataRows;
}

string? ITestDataSource.GetDisplayName(MethodInfo methodInfo, object?[]? data)
Youssef1313 marked this conversation as resolved.
Show resolved Hide resolved
=> TestDataSourceUtilities.ComputeDefaultDisplayName(methodInfo, data, DynamicDataAttribute.TestIdGenerationStrategy);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<!-- TODO: (before merge) Is this hack relevant for a new project? -->
<UseAssemblyVersion14>true</UseAssemblyVersion14>
</PropertyGroup>

<PropertyGroup>
<IsPackable>true</IsPackable>
<PackageId>MSTest.DataSource.Csv</PackageId>
<PackageTags>MSTest TestFramework Unittest MSTestV2 Microsoft Test Testing TDD Framework</PackageTags>
<PackageDescription>
MSTest is Microsoft supported Test Framework.

This package includes the functionality needed for writing Csv-based data source unit tests.

Supported platforms:
- .NET Standard 2.0
</PackageDescription>
</PropertyGroup>

<PropertyGroup>
<RootNamespace>Microsoft.VisualStudio.TestTools.UnitTesting</RootNamespace>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="$(RepoRoot)src\TestFramework\TestFramework.Extensions\TestFramework.Extensions.csproj" />

<PackageReference Include="System.Data.OleDb" />
</ItemGroup>

<ItemGroup>
<!-- API that is common to all frameworks that we build for. -->
<AdditionalFiles Include="PublicAPI\PublicAPI.Shipped.txt" />
<AdditionalFiles Include="PublicAPI\PublicAPI.Unshipped.txt" />
</ItemGroup>

</Project>
9 changes: 9 additions & 0 deletions src/TestFramework/TestFramework.Extensions.Csv/PACKAGE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# MSTest.TestFramework

MSTest is Microsoft supported Test Framework.

This package includes the functionality needed for writing Csv-based data source unit tests.

Supported platforms:

- .NET Standard 2.0
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#nullable enable
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#nullable enable
Microsoft.VisualStudio.TestTools.UnitTesting.CsvDataSourceAttribute
Microsoft.VisualStudio.TestTools.UnitTesting.CsvDataSourceAttribute.CsvDataSourceAttribute(string! fileName) -> void
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<!-- TODO: (before merge) Is this hack relevant for a new project? -->
<UseAssemblyVersion14>true</UseAssemblyVersion14>
</PropertyGroup>

<PropertyGroup>
<IsPackable>true</IsPackable>
<PackageId>MSTest.DataSource.Xml</PackageId>
<PackageTags>MSTest TestFramework Unittest MSTestV2 Microsoft Test Testing TDD Framework</PackageTags>
<PackageDescription>
MSTest is Microsoft supported Test Framework.

This package includes the functionality needed for writing Xml-based data source unit tests.

Supported platforms:
- .NET Standard 2.0
</PackageDescription>
</PropertyGroup>

<PropertyGroup>
<RootNamespace>Microsoft.VisualStudio.TestTools.UnitTesting</RootNamespace>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="$(RepoRoot)src\TestFramework\TestFramework.Extensions\TestFramework.Extensions.csproj" />
</ItemGroup>

<ItemGroup>
<!-- API that is common to all frameworks that we build for. -->
<AdditionalFiles Include="PublicAPI\PublicAPI.Shipped.txt" />
<AdditionalFiles Include="PublicAPI\PublicAPI.Unshipped.txt" />
</ItemGroup>

</Project>
9 changes: 9 additions & 0 deletions src/TestFramework/TestFramework.Extensions.Xml/PACKAGE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# MSTest.TestFramework

MSTest is Microsoft supported Test Framework.

This package includes the functionality needed for writing Csv-based data source unit tests.

Supported platforms:

- .NET Standard 2.0
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#nullable enable
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#nullable enable
Microsoft.VisualStudio.TestTools.UnitTesting.XmlDataSourceAttribute
Microsoft.VisualStudio.TestTools.UnitTesting.XmlDataSourceAttribute.XmlDataSourceAttribute(string! fileName, string! tableName) -> void
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// 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.Globalization;
using System.Reflection;
using System.Xml;

using Microsoft.VisualStudio.TestTools.UnitTesting.Internal;

namespace Microsoft.VisualStudio.TestTools.UnitTesting;

/// <summary>
/// Attribute to define dynamic data from an XML file for a test method.
/// </summary>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public sealed class XmlDataSourceAttribute : Attribute, ITestDataSource
{
public XmlDataSourceAttribute(string fileName, string tableName)
{
FileName = fileName;
TableName = tableName;
}

internal string FileName { get; }

internal string TableName { get; }

IEnumerable<object?[]> ITestDataSource.GetData(MethodInfo methodInfo)
{
string fullPath = Path.GetFullPath(FileName);
if (!File.Exists(fullPath))
{
// TODO: Localize.
throw new FileNotFoundException($"Xml file '{fullPath}' cannot be found.", fullPath);
}

DataSet dataSet = new()
{
Locale = CultureInfo.CurrentCulture,
};

// ReadXml should use the overload with XmlReader to avoid DTD processing
dataSet.ReadXml(new XmlTextReader(fullPath));

DataTable table = dataSet.Tables[TableName];

object?[][] dataRows = new object?[table.Rows.Count][];
for (int i = 0; i < dataRows.Length; i++)
{
dataRows[i] = [table.Rows[i]];
}

return dataRows;
}

string? ITestDataSource.GetDisplayName(MethodInfo methodInfo, object?[]? data)
=> TestDataSourceUtilities.ComputeDefaultDisplayName(methodInfo, data, DynamicDataAttribute.TestIdGenerationStrategy);
}
2 changes: 2 additions & 0 deletions src/TestFramework/TestFramework/TestFramework.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@

<ItemGroup>
<InternalsVisibleTo Include="MSTest.TestAdapter" Key="$(VsPublicKey)" />
<InternalsVisibleTo Include="MSTest.DataSource.Csv" Key="$(VsPublicKey)" />
<InternalsVisibleTo Include="MSTest.DataSource.Xml" Key="$(VsPublicKey)" />
<InternalsVisibleTo Include="Microsoft.VisualStudio.TestPlatform.MSTestAdapter.UnitTests" Key="$(VsPublicKey)" />
</ItemGroup>

Expand Down
Loading
Loading