Skip to content

Commit 5ba2b11

Browse files
authored
dotnet test improvements for MTP (#47395)
2 parents e3fa8c4 + a7e8c22 commit 5ba2b11

File tree

48 files changed

+64
-86
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+64
-86
lines changed

src/Cli/dotnet/commands/dotnet-test/LocalizableStrings.resx

+1-1
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ For MSTest before 2.2.4, the timeout is used for all testcases.</value>
317317
<comment>{0} - test message state</comment>
318318
</data>
319319
<data name="CmdUnsupportedVSTestTestApplicationsDescription" xml:space="preserve">
320-
<value>Test projects that use both VSTest and Microsoft.Testing.Platform in the same solution are not supported.
320+
<value>Test project '{0}' is using VSTest. When opting-in via dotnet.config, all the test projects are expected to be using Microsoft.Testing.Platform.
321321
See https://aka.ms/dotnet-test/mtp for more information.</value>
322322
</data>
323323
<data name="Aborted" xml:space="preserve">

src/Cli/dotnet/commands/dotnet-test/MSBuildHandler.cs

+17-12
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4+
using System;
45
using System.Collections.Concurrent;
6+
using System.IO;
57
using Microsoft.DotNet.Tools.Common;
68
using Microsoft.DotNet.Tools.Test;
9+
using Microsoft.Testing.Platform.OutputDevice;
710
using Microsoft.Testing.Platform.OutputDevice.Terminal;
811

912
namespace Microsoft.DotNet.Cli
@@ -70,7 +73,7 @@ private int RunBuild(string directoryPath, BuildOptions buildOptions)
7073
return ExitCode.GenericFailure;
7174
}
7275

73-
(IEnumerable<Module> projects, bool restored) = GetProjectsProperties(projectOrSolutionFilePath, isSolution, buildOptions);
76+
(IEnumerable<TestModule> projects, bool restored) = GetProjectsProperties(projectOrSolutionFilePath, isSolution, buildOptions);
7477

7578
InitializeTestApplications(projects);
7679

@@ -79,28 +82,30 @@ private int RunBuild(string directoryPath, BuildOptions buildOptions)
7982

8083
private int RunBuild(string filePath, bool isSolution, BuildOptions buildOptions)
8184
{
82-
(IEnumerable<Module> projects, bool restored) = GetProjectsProperties(filePath, isSolution, buildOptions);
85+
(IEnumerable<TestModule> projects, bool restored) = GetProjectsProperties(filePath, isSolution, buildOptions);
8386

8487
InitializeTestApplications(projects);
8588

8689
return restored ? ExitCode.Success : ExitCode.GenericFailure;
8790
}
8891

89-
private void InitializeTestApplications(IEnumerable<Module> modules)
92+
private void InitializeTestApplications(IEnumerable<TestModule> modules)
9093
{
91-
foreach (Module module in modules)
94+
foreach (TestModule module in modules)
9295
{
93-
if (!module.IsTestProject)
96+
if (!module.IsTestProject && !module.IsTestingPlatformApplication)
9497
{
95-
// Non test projects, like the projects that include production code are skipped over, we won't run them.
96-
return;
98+
// This should never happen. We should only ever create Module if it's a test project.
99+
throw new InvalidOperationException();
97100
}
98101

99102
if (!module.IsTestingPlatformApplication)
100103
{
101-
// If one test app has IsTestingPlatformApplication set to false, then we will not run any of the test apps
104+
// If one test app has IsTestingPlatformApplication set to false (VSTest and not MTP), then we will not run any of the test apps
105+
// Note that we still continue the loop here so that we print all projects that are VSTest and not MTP.
102106
_areTestingPlatformApplications = false;
103-
return;
107+
_output.WriteMessage(string.Format(LocalizableStrings.CmdUnsupportedVSTestTestApplicationsDescription, Path.GetFileName(module.ProjectFullPath)), new SystemConsoleColor { ConsoleColor = ConsoleColor.Red });
108+
continue;
104109
}
105110

106111
var testApp = new TestApplication(module, _args);
@@ -122,9 +127,9 @@ public bool EnqueueTestApplications()
122127
return true;
123128
}
124129

125-
private (IEnumerable<Module> Projects, bool Restored) GetProjectsProperties(string solutionOrProjectFilePath, bool isSolution, BuildOptions buildOptions)
130+
private (IEnumerable<TestModule> Projects, bool Restored) GetProjectsProperties(string solutionOrProjectFilePath, bool isSolution, BuildOptions buildOptions)
126131
{
127-
(IEnumerable<Module> projects, bool isBuiltOrRestored) = isSolution ?
132+
(IEnumerable<TestModule> projects, bool isBuiltOrRestored) = isSolution ?
128133
MSBuildUtility.GetProjectsFromSolution(solutionOrProjectFilePath, buildOptions) :
129134
MSBuildUtility.GetProjectsFromProject(solutionOrProjectFilePath, buildOptions);
130135

@@ -133,7 +138,7 @@ public bool EnqueueTestApplications()
133138
return (projects, isBuiltOrRestored);
134139
}
135140

136-
private void LogProjectProperties(IEnumerable<Module> modules)
141+
private void LogProjectProperties(IEnumerable<TestModule> modules)
137142
{
138143
if (!Logger.TraceEnabled)
139144
{

src/Cli/dotnet/commands/dotnet-test/MSBuildUtility.cs

+7-7
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ namespace Microsoft.DotNet.Cli
1313
{
1414
internal static class MSBuildUtility
1515
{
16-
public static (IEnumerable<Module> Projects, bool IsBuiltOrRestored) GetProjectsFromSolution(string solutionFilePath, BuildOptions buildOptions)
16+
public static (IEnumerable<TestModule> Projects, bool IsBuiltOrRestored) GetProjectsFromSolution(string solutionFilePath, BuildOptions buildOptions)
1717
{
1818
SolutionModel solutionModel = SlnFileFactory.CreateFromFileOrDirectory(solutionFilePath, includeSolutionFilterFiles: true, includeSolutionXmlFiles: true);
1919

@@ -23,18 +23,18 @@ public static (IEnumerable<Module> Projects, bool IsBuiltOrRestored) GetProjects
2323
Path.GetDirectoryName(solutionModel.Description) :
2424
SolutionAndProjectUtility.GetRootDirectory(solutionFilePath);
2525

26-
ConcurrentBag<Module> projects = GetProjectsProperties(new ProjectCollection(), solutionModel.SolutionProjects.Select(p => Path.Combine(rootDirectory, p.FilePath)), buildOptions);
26+
ConcurrentBag<TestModule> projects = GetProjectsProperties(new ProjectCollection(), solutionModel.SolutionProjects.Select(p => Path.Combine(rootDirectory, p.FilePath)), buildOptions);
2727

2828
isBuiltOrRestored |= !projects.IsEmpty;
2929

3030
return (projects, isBuiltOrRestored);
3131
}
3232

33-
public static (IEnumerable<Module> Projects, bool IsBuiltOrRestored) GetProjectsFromProject(string projectFilePath, BuildOptions buildOptions)
33+
public static (IEnumerable<TestModule> Projects, bool IsBuiltOrRestored) GetProjectsFromProject(string projectFilePath, BuildOptions buildOptions)
3434
{
3535
bool isBuiltOrRestored = BuildOrRestoreProjectOrSolution(projectFilePath, buildOptions);
3636

37-
IEnumerable<Module> projects = SolutionAndProjectUtility.GetProjectProperties(projectFilePath, GetGlobalProperties(buildOptions.BuildProperties), new ProjectCollection());
37+
IEnumerable<TestModule> projects = SolutionAndProjectUtility.GetProjectProperties(projectFilePath, GetGlobalProperties(buildOptions.BuildProperties), new ProjectCollection());
3838

3939
isBuiltOrRestored |= projects.Any();
4040

@@ -124,16 +124,16 @@ private static bool BuildOrRestoreProjectOrSolution(string filePath, BuildOption
124124
return result == (int)BuildResultCode.Success;
125125
}
126126

127-
private static ConcurrentBag<Module> GetProjectsProperties(ProjectCollection projectCollection, IEnumerable<string> projects, BuildOptions buildOptions)
127+
private static ConcurrentBag<TestModule> GetProjectsProperties(ProjectCollection projectCollection, IEnumerable<string> projects, BuildOptions buildOptions)
128128
{
129-
var allProjects = new ConcurrentBag<Module>();
129+
var allProjects = new ConcurrentBag<TestModule>();
130130

131131
Parallel.ForEach(
132132
projects,
133133
new ParallelOptions { MaxDegreeOfParallelism = buildOptions.DegreeOfParallelism },
134134
(project) =>
135135
{
136-
IEnumerable<Module> projectsMetadata = SolutionAndProjectUtility.GetProjectProperties(project, GetGlobalProperties(buildOptions.BuildProperties), projectCollection);
136+
IEnumerable<TestModule> projectsMetadata = SolutionAndProjectUtility.GetProjectProperties(project, GetGlobalProperties(buildOptions.BuildProperties), projectCollection);
137137
foreach (var projectMetadata in projectsMetadata)
138138
{
139139
allProjects.Add(projectMetadata);

src/Cli/dotnet/commands/dotnet-test/Models.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
namespace Microsoft.DotNet.Cli
55
{
6-
internal sealed record Module(string? TargetPath, string? ProjectFullPath, string? TargetFramework, string? RunSettingsFilePath, bool IsTestingPlatformApplication, bool IsTestProject);
6+
internal sealed record TestModule(string? TargetPath, string? ProjectFullPath, string? TargetFramework, string? RunSettingsFilePath, bool IsTestingPlatformApplication, bool IsTestProject);
77

88
internal sealed record Handshake(Dictionary<byte, string>? Properties);
99

src/Cli/dotnet/commands/dotnet-test/SolutionAndProjectUtility.cs

+6-7
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,9 @@ public static string GetRootDirectory(string solutionOrProjectFilePath)
100100
return string.IsNullOrEmpty(fileDirectory) ? Directory.GetCurrentDirectory() : fileDirectory;
101101
}
102102

103-
public static IEnumerable<Module> GetProjectProperties(string projectFilePath, IDictionary<string, string> globalProperties, ProjectCollection projectCollection)
103+
public static IEnumerable<TestModule> GetProjectProperties(string projectFilePath, IDictionary<string, string> globalProperties, ProjectCollection projectCollection)
104104
{
105-
var projects = new List<Module>();
105+
var projects = new List<TestModule>();
106106

107107
var globalPropertiesWithoutTargetFramework = new Dictionary<string, string>(globalProperties);
108108
globalPropertiesWithoutTargetFramework.Remove(ProjectProperties.TargetFramework);
@@ -164,23 +164,22 @@ private static bool IsValidTargetFramework(Project project, string targetFramewo
164164
return frameworks.Contains(targetFramework);
165165
}
166166

167-
private static Module? GetModuleFromProject(Project project)
167+
private static TestModule? GetModuleFromProject(Project project)
168168
{
169169
_ = bool.TryParse(project.GetPropertyValue(ProjectProperties.IsTestProject), out bool isTestProject);
170+
_ = bool.TryParse(project.GetPropertyValue(ProjectProperties.IsTestingPlatformApplication), out bool isTestingPlatformApplication);
170171

171-
if (!isTestProject)
172+
if (!isTestProject && !isTestingPlatformApplication)
172173
{
173174
return null;
174175
}
175176

176-
_ = bool.TryParse(project.GetPropertyValue(ProjectProperties.IsTestingPlatformApplication), out bool isTestingPlatformApplication);
177-
178177
string targetFramework = project.GetPropertyValue(ProjectProperties.TargetFramework);
179178
string targetPath = project.GetPropertyValue(ProjectProperties.TargetPath);
180179
string projectFullPath = project.GetPropertyValue(ProjectProperties.ProjectFullPath);
181180
string runSettingsFilePath = project.GetPropertyValue(ProjectProperties.RunSettingsFilePath);
182181

183-
return new Module(targetPath, PathUtility.FixFilePath(projectFullPath), targetFramework, runSettingsFilePath, isTestingPlatformApplication, isTestProject);
182+
return new TestModule(targetPath, PathUtility.FixFilePath(projectFullPath), targetFramework, runSettingsFilePath, isTestingPlatformApplication, isTestProject);
184183
}
185184
}
186185
}

src/Cli/dotnet/commands/dotnet-test/TestApplication.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ namespace Microsoft.DotNet.Cli
1111
{
1212
internal sealed class TestApplication : IDisposable
1313
{
14-
private readonly Module _module;
14+
private readonly TestModule _module;
1515
private readonly List<string> _args;
1616

1717
private readonly List<string> _outputData = [];
@@ -33,9 +33,9 @@ internal sealed class TestApplication : IDisposable
3333
public event EventHandler<TestProcessExitEventArgs> TestProcessExited;
3434
public event EventHandler<ExecutionEventArgs> ExecutionIdReceived;
3535

36-
public Module Module => _module;
36+
public TestModule Module => _module;
3737

38-
public TestApplication(Module module, List<string> args)
38+
public TestApplication(TestModule module, List<string> args)
3939
{
4040
_module = module;
4141
_args = args;

src/Cli/dotnet/commands/dotnet-test/TestModulesFilterHandler.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public bool RunWithTestModulesFilter(ParseResult parseResult)
4949

5050
foreach (string testModule in testModulePaths)
5151
{
52-
var testApp = new TestApplication(new Module(testModule, null, null, null, true, true), _args);
52+
var testApp = new TestApplication(new TestModule(testModule, null, null, null, true, true), _args);
5353
// Write the test application to the channel
5454
_actionQueue.Enqueue(testApp);
5555
}

src/Cli/dotnet/commands/dotnet-test/TestingPlatformCommand.cs

-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ public int Run(ParseResult parseResult)
5959

6060
if (!_msBuildHandler.EnqueueTestApplications())
6161
{
62-
_output.WriteMessage(LocalizableStrings.CmdUnsupportedVSTestTestApplicationsDescription, new SystemConsoleColor { ConsoleColor = ConsoleColor.Red });
6362
return ExitCode.GenericFailure;
6463
}
6564
}

src/Cli/dotnet/commands/dotnet-test/xlf/LocalizableStrings.cs.xlf

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Cli/dotnet/commands/dotnet-test/xlf/LocalizableStrings.de.xlf

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Cli/dotnet/commands/dotnet-test/xlf/LocalizableStrings.es.xlf

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Cli/dotnet/commands/dotnet-test/xlf/LocalizableStrings.fr.xlf

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Cli/dotnet/commands/dotnet-test/xlf/LocalizableStrings.it.xlf

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Cli/dotnet/commands/dotnet-test/xlf/LocalizableStrings.ja.xlf

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Cli/dotnet/commands/dotnet-test/xlf/LocalizableStrings.ko.xlf

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)