Adding a separate runner for project.json and for assembly.
This commit is contained in:
parent
dddfb6bb45
commit
7e556e37d2
14 changed files with 320 additions and 199 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -151,6 +151,7 @@ _ReSharper*/
|
||||||
*.DotSettings.user
|
*.DotSettings.user
|
||||||
.idea/
|
.idea/
|
||||||
*.iml
|
*.iml
|
||||||
|
*.DotSettings
|
||||||
|
|
||||||
# JustCode is a .NET coding add-in
|
# JustCode is a .NET coding add-in
|
||||||
.JustCode
|
.JustCode
|
||||||
|
|
28
src/dotnet-test-console/AssemblyTestRunner.cs
Normal file
28
src/dotnet-test-console/AssemblyTestRunner.cs
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||||
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using Microsoft.DotNet.Cli.Utils;
|
||||||
|
|
||||||
|
namespace Microsoft.DotNet.Tools.Test
|
||||||
|
{
|
||||||
|
public class AssemblyTestRunner : IDotnetTestRunner
|
||||||
|
{
|
||||||
|
private readonly Func<ICommandFactory, string, IDotnetTestRunner> _nextRunner;
|
||||||
|
|
||||||
|
public AssemblyTestRunner(Func<ICommandFactory, string, IDotnetTestRunner> nextRunner)
|
||||||
|
{
|
||||||
|
_nextRunner = nextRunner;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int RunTests(DotnetTestParams dotnetTestParams)
|
||||||
|
{
|
||||||
|
var commandFactory =
|
||||||
|
new CommandFactory();
|
||||||
|
|
||||||
|
var assemblyUnderTest = dotnetTestParams.ProjectOrAssemblyPath;
|
||||||
|
|
||||||
|
return _nextRunner(commandFactory, assemblyUnderTest).RunTests(dotnetTestParams);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,46 +3,53 @@
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Microsoft.DotNet.Cli.Utils;
|
using Microsoft.DotNet.Cli.Utils;
|
||||||
using Microsoft.DotNet.ProjectModel;
|
using NuGet.Frameworks;
|
||||||
|
|
||||||
namespace Microsoft.DotNet.Tools.Test
|
namespace Microsoft.DotNet.Tools.Test
|
||||||
{
|
{
|
||||||
public class ConsoleTestRunner : BaseDotnetTestRunner
|
public class ConsoleTestRunner : IDotnetTestRunner
|
||||||
{
|
{
|
||||||
internal override int DoRunTests(ProjectContext projectContext, DotnetTestParams dotnetTestParams)
|
private readonly ITestRunnerResolver _testRunnerResolver;
|
||||||
{
|
|
||||||
var commandFactory =
|
|
||||||
new ProjectDependenciesCommandFactory(
|
|
||||||
projectContext.TargetFramework,
|
|
||||||
dotnetTestParams.Config,
|
|
||||||
dotnetTestParams.Output,
|
|
||||||
dotnetTestParams.BuildBasePath,
|
|
||||||
projectContext.ProjectDirectory);
|
|
||||||
|
|
||||||
return commandFactory.Create(
|
private readonly ICommandFactory _commandFactory;
|
||||||
GetCommandName(projectContext.ProjectFile.TestRunner),
|
|
||||||
GetCommandArgs(projectContext, dotnetTestParams),
|
private readonly string _assemblyUnderTest;
|
||||||
projectContext.TargetFramework,
|
|
||||||
|
private readonly NuGetFramework _framework;
|
||||||
|
|
||||||
|
public ConsoleTestRunner(
|
||||||
|
ITestRunnerResolver testRunnerResolver,
|
||||||
|
ICommandFactory commandFactory,
|
||||||
|
string assemblyUnderTest,
|
||||||
|
NuGetFramework framework = null)
|
||||||
|
{
|
||||||
|
_testRunnerResolver = testRunnerResolver;
|
||||||
|
_commandFactory = commandFactory;
|
||||||
|
_assemblyUnderTest = assemblyUnderTest;
|
||||||
|
_framework = framework;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int RunTests(DotnetTestParams dotnetTestParams)
|
||||||
|
{
|
||||||
|
return _commandFactory.Create(
|
||||||
|
_testRunnerResolver.ResolveTestRunner(),
|
||||||
|
GetCommandArgs(dotnetTestParams),
|
||||||
|
_framework,
|
||||||
dotnetTestParams.Config)
|
dotnetTestParams.Config)
|
||||||
.Execute()
|
.Execute()
|
||||||
.ExitCode;
|
.ExitCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerable<string> GetCommandArgs(ProjectContext projectContext, DotnetTestParams dotnetTestParams)
|
private IEnumerable<string> GetCommandArgs(DotnetTestParams dotnetTestParams)
|
||||||
{
|
{
|
||||||
var commandArgs = new List<string>
|
var commandArgs = new List<string>
|
||||||
{
|
{
|
||||||
new AssemblyUnderTest(projectContext, dotnetTestParams).Path
|
_assemblyUnderTest
|
||||||
};
|
};
|
||||||
|
|
||||||
commandArgs.AddRange(dotnetTestParams.RemainingArguments);
|
commandArgs.AddRange(dotnetTestParams.RemainingArguments);
|
||||||
|
|
||||||
return commandArgs;
|
return commandArgs;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetCommandName(string testRunner)
|
|
||||||
{
|
|
||||||
return $"dotnet-test-{testRunner}";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,44 +3,49 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using Microsoft.DotNet.Cli.Utils;
|
using Microsoft.DotNet.Cli.Utils;
|
||||||
using Microsoft.DotNet.ProjectModel;
|
|
||||||
|
|
||||||
namespace Microsoft.DotNet.Tools.Test
|
namespace Microsoft.DotNet.Tools.Test
|
||||||
{
|
{
|
||||||
public class DesignTimeRunner : BaseDotnetTestRunner
|
public class DesignTimeRunner : IDotnetTestRunner
|
||||||
{
|
{
|
||||||
internal override int DoRunTests(ProjectContext projectContext, DotnetTestParams dotnetTestParams)
|
private readonly ITestRunnerResolver _testRunnerResolver;
|
||||||
|
|
||||||
|
private readonly ICommandFactory _commandFactory;
|
||||||
|
|
||||||
|
private readonly string _assemblyUnderTest;
|
||||||
|
|
||||||
|
public DesignTimeRunner(
|
||||||
|
ITestRunnerResolver testRunnerResolver,
|
||||||
|
ICommandFactory commandFactory,
|
||||||
|
string assemblyUnderTest)
|
||||||
|
{
|
||||||
|
_testRunnerResolver = testRunnerResolver;
|
||||||
|
_commandFactory = commandFactory;
|
||||||
|
_assemblyUnderTest = assemblyUnderTest;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int RunTests(DotnetTestParams dotnetTestParams)
|
||||||
{
|
{
|
||||||
Console.WriteLine("Listening on port {0}", dotnetTestParams.Port.Value);
|
Console.WriteLine("Listening on port {0}", dotnetTestParams.Port.Value);
|
||||||
|
|
||||||
HandleDesignTimeMessages(projectContext, dotnetTestParams);
|
HandleDesignTimeMessages(dotnetTestParams);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void HandleDesignTimeMessages(
|
private void HandleDesignTimeMessages(DotnetTestParams dotnetTestParams)
|
||||||
ProjectContext projectContext,
|
|
||||||
DotnetTestParams dotnetTestParams)
|
|
||||||
{
|
{
|
||||||
var reportingChannelFactory = new ReportingChannelFactory();
|
var reportingChannelFactory = new ReportingChannelFactory();
|
||||||
var adapterChannel = reportingChannelFactory.CreateAdapterChannel(dotnetTestParams.Port.Value);
|
var adapterChannel = reportingChannelFactory.CreateAdapterChannel(dotnetTestParams.Port.Value);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var pathToAssemblyUnderTest = new AssemblyUnderTest(projectContext, dotnetTestParams).Path;
|
var pathToAssemblyUnderTest = _assemblyUnderTest;
|
||||||
var messages = new TestMessagesCollection();
|
var messages = new TestMessagesCollection();
|
||||||
using (var dotnetTest = new DotnetTest(messages, pathToAssemblyUnderTest))
|
using (var dotnetTest = new DotnetTest(messages, pathToAssemblyUnderTest))
|
||||||
{
|
{
|
||||||
var commandFactory =
|
|
||||||
new ProjectDependenciesCommandFactory(
|
|
||||||
projectContext.TargetFramework,
|
|
||||||
dotnetTestParams.Config,
|
|
||||||
dotnetTestParams.Output,
|
|
||||||
dotnetTestParams.BuildBasePath,
|
|
||||||
projectContext.ProjectDirectory);
|
|
||||||
|
|
||||||
var testRunnerFactory =
|
var testRunnerFactory =
|
||||||
new TestRunnerFactory(GetCommandName(projectContext.ProjectFile.TestRunner), commandFactory);
|
new TestRunnerFactory(_testRunnerResolver.ResolveTestRunner(), _commandFactory);
|
||||||
|
|
||||||
dotnetTest
|
dotnetTest
|
||||||
.AddNonSpecificMessageHandlers(messages, adapterChannel)
|
.AddNonSpecificMessageHandlers(messages, adapterChannel)
|
||||||
|
@ -60,10 +65,5 @@ namespace Microsoft.DotNet.Tools.Test
|
||||||
adapterChannel.SendError(ex);
|
adapterChannel.SendError(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetCommandName(string testRunner)
|
|
||||||
{
|
|
||||||
return $"dotnet-test-{testRunner}";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,6 +56,8 @@ namespace Microsoft.DotNet.Tools.Test
|
||||||
|
|
||||||
public bool HasTestRunner => !string.IsNullOrWhiteSpace(TestRunner);
|
public bool HasTestRunner => !string.IsNullOrWhiteSpace(TestRunner);
|
||||||
|
|
||||||
|
public bool IsTestingAssembly => ProjectOrAssemblyPath.EndsWith(".dll");
|
||||||
|
|
||||||
public DotnetTestParams()
|
public DotnetTestParams()
|
||||||
{
|
{
|
||||||
_app = new CommandLineApplication(false)
|
_app = new CommandLineApplication(false)
|
||||||
|
@ -108,7 +110,7 @@ namespace Microsoft.DotNet.Tools.Test
|
||||||
|
|
||||||
if (_testRunner.HasValue())
|
if (_testRunner.HasValue())
|
||||||
{
|
{
|
||||||
if (!IsAssembly(ProjectOrAssemblyPath))
|
if (!IsTestingAssembly)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException("You can only specify a test runner with a dll.");
|
throw new InvalidOperationException("You can only specify a test runner with a dll.");
|
||||||
}
|
}
|
||||||
|
@ -138,11 +140,6 @@ namespace Microsoft.DotNet.Tools.Test
|
||||||
_app.Execute(args);
|
_app.Execute(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsAssembly(string projectOrAssemblyPath)
|
|
||||||
{
|
|
||||||
return projectOrAssemblyPath.EndsWith(".dll");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AddDotnetTestParameters()
|
private void AddDotnetTestParameters()
|
||||||
{
|
{
|
||||||
_app.HelpOption("-?|-h|--help");
|
_app.HelpOption("-?|-h|--help");
|
||||||
|
|
|
@ -1,19 +1,56 @@
|
||||||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using Microsoft.DotNet.Cli.Utils;
|
||||||
|
using NuGet.Frameworks;
|
||||||
|
|
||||||
namespace Microsoft.DotNet.Tools.Test
|
namespace Microsoft.DotNet.Tools.Test
|
||||||
{
|
{
|
||||||
public class DotnetTestRunnerFactory : IDotnetTestRunnerFactory
|
public class DotnetTestRunnerFactory : IDotnetTestRunnerFactory
|
||||||
{
|
{
|
||||||
public IDotnetTestRunner Create(int? port)
|
private readonly DotnetTestRunnerResolverFactory _dotnetTestRunnerResolverFactory;
|
||||||
{
|
|
||||||
IDotnetTestRunner dotnetTestRunner = new ConsoleTestRunner();
|
|
||||||
if (port.HasValue)
|
|
||||||
{
|
|
||||||
dotnetTestRunner = new DesignTimeRunner();
|
|
||||||
}
|
|
||||||
|
|
||||||
return dotnetTestRunner;
|
public DotnetTestRunnerFactory(DotnetTestRunnerResolverFactory dotnetTestRunnerResolverFactory)
|
||||||
|
{
|
||||||
|
_dotnetTestRunnerResolverFactory = dotnetTestRunnerResolverFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IDotnetTestRunner Create(DotnetTestParams dotnetTestParams)
|
||||||
|
{
|
||||||
|
Func<ICommandFactory, string, NuGetFramework, IDotnetTestRunner> nextTestRunner =
|
||||||
|
(commandFactory, assemblyUnderTest, framework) =>
|
||||||
|
{
|
||||||
|
var dotnetTestRunnerResolver = _dotnetTestRunnerResolverFactory.Create(dotnetTestParams);
|
||||||
|
|
||||||
|
IDotnetTestRunner testRunner =
|
||||||
|
new ConsoleTestRunner(dotnetTestRunnerResolver, commandFactory, assemblyUnderTest, framework);
|
||||||
|
if (dotnetTestParams.Port.HasValue)
|
||||||
|
{
|
||||||
|
testRunner = new DesignTimeRunner(dotnetTestRunnerResolver, commandFactory, assemblyUnderTest);
|
||||||
|
}
|
||||||
|
|
||||||
|
return testRunner;
|
||||||
|
};
|
||||||
|
|
||||||
|
return dotnetTestParams.IsTestingAssembly
|
||||||
|
? CreateTestRunnerForAssembly(nextTestRunner)
|
||||||
|
: CreateTestRunnerForProjectJson(nextTestRunner);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IDotnetTestRunner CreateTestRunnerForAssembly(
|
||||||
|
Func<ICommandFactory, string, NuGetFramework, IDotnetTestRunner> nextTestRunner)
|
||||||
|
{
|
||||||
|
Func<ICommandFactory, string, IDotnetTestRunner> nextAssemblyTestRunner =
|
||||||
|
(commandFactory, assemblyUnderTest) => nextTestRunner(commandFactory, assemblyUnderTest, null);
|
||||||
|
|
||||||
|
return new AssemblyTestRunner(nextAssemblyTestRunner);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IDotnetTestRunner CreateTestRunnerForProjectJson(
|
||||||
|
Func<ICommandFactory, string, NuGetFramework, IDotnetTestRunner> nextTestRunner)
|
||||||
|
{
|
||||||
|
return new ProjectJsonTestRunner(nextTestRunner);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,10 @@
|
||||||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
|
|
||||||
using Microsoft.DotNet.ProjectModel;
|
|
||||||
using Microsoft.DotNet.Cli.Utils;
|
|
||||||
|
|
||||||
namespace Microsoft.DotNet.Tools.Test
|
namespace Microsoft.DotNet.Tools.Test
|
||||||
{
|
{
|
||||||
public interface IDotnetTestRunner
|
public interface IDotnetTestRunner
|
||||||
{
|
{
|
||||||
int RunTests(ProjectContext projectContext, DotnetTestParams dotnetTestParams, BuildWorkspace workspace);
|
int RunTests(DotnetTestParams dotnetTestParams);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,6 @@ namespace Microsoft.DotNet.Tools.Test
|
||||||
{
|
{
|
||||||
public interface IDotnetTestRunnerFactory
|
public interface IDotnetTestRunnerFactory
|
||||||
{
|
{
|
||||||
IDotnetTestRunner Create(int? port);
|
IDotnetTestRunner Create(DotnetTestParams dotnetTestParams);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,14 @@ namespace Microsoft.DotNet.Tools.Test
|
||||||
{
|
{
|
||||||
private readonly IDotnetTestRunnerFactory _dotnetTestRunnerFactory;
|
private readonly IDotnetTestRunnerFactory _dotnetTestRunnerFactory;
|
||||||
|
|
||||||
|
public static int Run(string[] args)
|
||||||
|
{
|
||||||
|
var dotnetTestRunnerResolverFactory = new DotnetTestRunnerResolverFactory(new ProjectReader());
|
||||||
|
var testCommand = new TestCommand(new DotnetTestRunnerFactory(dotnetTestRunnerResolverFactory));
|
||||||
|
|
||||||
|
return testCommand.DoRun(args);
|
||||||
|
}
|
||||||
|
|
||||||
public TestCommand(IDotnetTestRunnerFactory testRunnerFactory)
|
public TestCommand(IDotnetTestRunnerFactory testRunnerFactory)
|
||||||
{
|
{
|
||||||
_dotnetTestRunnerFactory = testRunnerFactory;
|
_dotnetTestRunnerFactory = testRunnerFactory;
|
||||||
|
@ -41,60 +49,7 @@ namespace Microsoft.DotNet.Tools.Test
|
||||||
RegisterForParentProcessExit(dotnetTestParams.ParentProcessId.Value);
|
RegisterForParentProcessExit(dotnetTestParams.ParentProcessId.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
var projectPath = GetProjectPath(dotnetTestParams.ProjectOrAssemblyPath);
|
return RunTest(dotnetTestParams);
|
||||||
var runtimeIdentifiers = !string.IsNullOrEmpty(dotnetTestParams.Runtime) ?
|
|
||||||
new[] { dotnetTestParams.Runtime } :
|
|
||||||
RuntimeEnvironmentRidExtensions.GetAllCandidateRuntimeIdentifiers();
|
|
||||||
var exitCode = 0;
|
|
||||||
|
|
||||||
// Create a workspace
|
|
||||||
var workspace = new BuildWorkspace(ProjectReaderSettings.ReadFromEnvironment());
|
|
||||||
|
|
||||||
if (dotnetTestParams.Framework != null)
|
|
||||||
{
|
|
||||||
var projectContext = workspace.GetProjectContext(projectPath, dotnetTestParams.Framework);
|
|
||||||
if (projectContext == null)
|
|
||||||
{
|
|
||||||
Reporter.Error.WriteLine($"Project '{projectPath}' does not support framework: {dotnetTestParams.UnparsedFramework}");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
projectContext = workspace.GetRuntimeContext(projectContext, runtimeIdentifiers);
|
|
||||||
|
|
||||||
exitCode = RunTest(projectContext, dotnetTestParams, workspace);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var summary = new Summary();
|
|
||||||
var projectContexts = workspace.GetProjectContextCollection(projectPath)
|
|
||||||
.EnsureValid(projectPath)
|
|
||||||
.FrameworkOnlyContexts
|
|
||||||
.Select(c => workspace.GetRuntimeContext(c, runtimeIdentifiers))
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
// Execute for all TFMs the project targets.
|
|
||||||
foreach (var projectContext in projectContexts)
|
|
||||||
{
|
|
||||||
var result = RunTest(projectContext, dotnetTestParams, workspace);
|
|
||||||
if (result == 0)
|
|
||||||
{
|
|
||||||
summary.Passed++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
summary.Failed++;
|
|
||||||
if (exitCode == 0)
|
|
||||||
{
|
|
||||||
// If tests fail in more than one TFM, we'll have it use the result of the first one
|
|
||||||
// as the exit code.
|
|
||||||
exitCode = result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
summary.Print();
|
|
||||||
}
|
|
||||||
|
|
||||||
return exitCode;
|
|
||||||
}
|
}
|
||||||
catch (InvalidOperationException ex)
|
catch (InvalidOperationException ex)
|
||||||
{
|
{
|
||||||
|
@ -108,13 +63,6 @@ namespace Microsoft.DotNet.Tools.Test
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int Run(string[] args)
|
|
||||||
{
|
|
||||||
var testCommand = new TestCommand(new DotnetTestRunnerFactory());
|
|
||||||
|
|
||||||
return testCommand.DoRun(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void RegisterForParentProcessExit(int id)
|
private static void RegisterForParentProcessExit(int id)
|
||||||
{
|
{
|
||||||
var parentProcess = Process.GetProcesses().FirstOrDefault(p => p.Id == id);
|
var parentProcess = Process.GetProcesses().FirstOrDefault(p => p.Id == id);
|
||||||
|
@ -142,50 +90,10 @@ namespace Microsoft.DotNet.Tools.Test
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private int RunTest(ProjectContext projectContext, DotnetTestParams dotnetTestParams, BuildWorkspace workspace)
|
private int RunTest(DotnetTestParams dotnetTestParams)
|
||||||
{
|
{
|
||||||
var testRunner = projectContext.ProjectFile.TestRunner;
|
var dotnetTestRunner = _dotnetTestRunnerFactory.Create(dotnetTestParams);
|
||||||
var dotnetTestRunner = _dotnetTestRunnerFactory.Create(dotnetTestParams.Port);
|
return dotnetTestRunner.RunTests(dotnetTestParams);
|
||||||
return dotnetTestRunner.RunTests(projectContext, dotnetTestParams, workspace);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string GetProjectPath(string projectPath)
|
|
||||||
{
|
|
||||||
projectPath = projectPath ?? Directory.GetCurrentDirectory();
|
|
||||||
|
|
||||||
if (!projectPath.EndsWith(Project.FileName))
|
|
||||||
{
|
|
||||||
projectPath = Path.Combine(projectPath, Project.FileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!File.Exists(projectPath))
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException($"{projectPath} does not exist.");
|
|
||||||
}
|
|
||||||
|
|
||||||
return projectPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
private class Summary
|
|
||||||
{
|
|
||||||
public int Passed { get; set; }
|
|
||||||
|
|
||||||
public int Failed { get; set; }
|
|
||||||
|
|
||||||
public int Total => Passed + Failed;
|
|
||||||
|
|
||||||
public void Print()
|
|
||||||
{
|
|
||||||
var summaryMessage = $"SUMMARY: Total: {Total} targets, Passed: {Passed}, Failed: {Failed}.";
|
|
||||||
if (Failed > 0)
|
|
||||||
{
|
|
||||||
Reporter.Error.WriteLine(summaryMessage.Red());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Reporter.Output.WriteLine(summaryMessage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -2,46 +2,29 @@
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Runtime.InteropServices.ComTypes;
|
|
||||||
using Microsoft.DotNet.Cli.Utils;
|
using Microsoft.DotNet.Cli.Utils;
|
||||||
using Microsoft.DotNet.ProjectModel;
|
using Microsoft.DotNet.ProjectModel;
|
||||||
|
|
||||||
namespace Microsoft.DotNet.Tools.Test
|
namespace Microsoft.DotNet.Tools.Test
|
||||||
{
|
{
|
||||||
public abstract class BaseDotnetTestRunner : IDotnetTestRunner
|
public class TestProjectBuilder
|
||||||
{
|
{
|
||||||
public int RunTests(ProjectContext projectContext, DotnetTestParams dotnetTestParams, BuildWorkspace workspace)
|
public int BuildTestProject(ProjectContext projectContext, DotnetTestParams dotnetTestParams)
|
||||||
{
|
{
|
||||||
var result = BuildTestProject(projectContext, dotnetTestParams, workspace);
|
return dotnetTestParams.NoBuild ? 0 : DoBuildTestProject(projectContext, dotnetTestParams);
|
||||||
|
|
||||||
return result == 0 ? DoRunTests(projectContext, dotnetTestParams) : result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal abstract int DoRunTests(ProjectContext projectContext, DotnetTestParams dotnetTestParams);
|
private int DoBuildTestProject(ProjectContext projectContext, DotnetTestParams dotnetTestParams)
|
||||||
|
|
||||||
private int BuildTestProject(ProjectContext projectContext, DotnetTestParams dotnetTestParams, BuildWorkspace workspace)
|
|
||||||
{
|
|
||||||
if (dotnetTestParams.NoBuild)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return DoBuildTestProject(projectContext, dotnetTestParams, workspace);
|
|
||||||
}
|
|
||||||
|
|
||||||
private int DoBuildTestProject(ProjectContext projectContext, DotnetTestParams dotnetTestParams, BuildWorkspace workspace)
|
|
||||||
{
|
{
|
||||||
var strings = new List<string>
|
var strings = new List<string>
|
||||||
{
|
{
|
||||||
$"--configuration",
|
$"{dotnetTestParams.ProjectOrAssemblyPath}",
|
||||||
dotnetTestParams.Config,
|
$"--configuration", dotnetTestParams.Config,
|
||||||
$"{dotnetTestParams.ProjectOrAssemblyPath}"
|
"--framework", projectContext.TargetFramework.ToString()
|
||||||
};
|
};
|
||||||
|
|
||||||
// Build the test specifically for the target framework \ rid of the ProjectContext. This avoids building the project
|
// Build the test specifically for the target framework \ rid of the ProjectContext.
|
||||||
// for tfms that the user did not request.
|
// This avoids building the project for tfms that the user did not request.
|
||||||
strings.Add("--framework");
|
|
||||||
strings.Add(projectContext.TargetFramework.ToString());
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(dotnetTestParams.BuildBasePath))
|
if (!string.IsNullOrEmpty(dotnetTestParams.BuildBasePath))
|
||||||
{
|
{
|
||||||
|
@ -66,4 +49,4 @@ namespace Microsoft.DotNet.Tools.Test
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -13,14 +13,14 @@ namespace Microsoft.DotNet.Tools.Test
|
||||||
|
|
||||||
private readonly IDirectory _directory;
|
private readonly IDirectory _directory;
|
||||||
|
|
||||||
public AssemblyTestRunnerResolver(string directoryOfAssemblyUnderTest) :
|
public AssemblyTestRunnerResolver(string assemblyUnderTest) :
|
||||||
this(directoryOfAssemblyUnderTest, FileSystemWrapper.Default.Directory)
|
this(assemblyUnderTest, FileSystemWrapper.Default.Directory)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
internal AssemblyTestRunnerResolver(string directoryOfAssemblyUnderTest, IDirectory directory)
|
internal AssemblyTestRunnerResolver(string assemblyUnderTest, IDirectory directory)
|
||||||
{
|
{
|
||||||
_directoryOfAssemblyUnderTest = Path.GetDirectoryName(directoryOfAssemblyUnderTest);
|
_directoryOfAssemblyUnderTest = new FileInfo(assemblyUnderTest).Directory.FullName;
|
||||||
_directory = directory;
|
_directory = directory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
|
|
||||||
|
using System.IO;
|
||||||
using Microsoft.DotNet.ProjectModel;
|
using Microsoft.DotNet.ProjectModel;
|
||||||
|
|
||||||
namespace Microsoft.DotNet.Tools.Test
|
namespace Microsoft.DotNet.Tools.Test
|
||||||
|
@ -16,7 +17,7 @@ namespace Microsoft.DotNet.Tools.Test
|
||||||
|
|
||||||
public ITestRunnerResolver Create(DotnetTestParams dotnetTestParams)
|
public ITestRunnerResolver Create(DotnetTestParams dotnetTestParams)
|
||||||
{
|
{
|
||||||
var testRunnerResolver = dotnetTestParams.ProjectOrAssemblyPath.EndsWith(".dll") ?
|
var testRunnerResolver = dotnetTestParams.IsTestingAssembly ?
|
||||||
GetAssemblyTestRunnerResolver(dotnetTestParams) :
|
GetAssemblyTestRunnerResolver(dotnetTestParams) :
|
||||||
GetProjectJsonTestRunnerResolver(dotnetTestParams);
|
GetProjectJsonTestRunnerResolver(dotnetTestParams);
|
||||||
|
|
||||||
|
|
148
src/dotnet-test-console/TestRunners/ProjectJsonTestRunner.cs
Normal file
148
src/dotnet-test-console/TestRunners/ProjectJsonTestRunner.cs
Normal file
|
@ -0,0 +1,148 @@
|
||||||
|
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||||
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using Microsoft.DotNet.Cli.Utils;
|
||||||
|
using Microsoft.DotNet.InternalAbstractions;
|
||||||
|
using Microsoft.DotNet.ProjectModel;
|
||||||
|
using System.Linq;
|
||||||
|
using NuGet.Frameworks;
|
||||||
|
|
||||||
|
namespace Microsoft.DotNet.Tools.Test
|
||||||
|
{
|
||||||
|
public class ProjectJsonTestRunner : IDotnetTestRunner
|
||||||
|
{
|
||||||
|
private readonly Func<ICommandFactory, string, NuGetFramework, IDotnetTestRunner> _nextRunner;
|
||||||
|
private readonly TestProjectBuilder _testProjectBuilder;
|
||||||
|
|
||||||
|
public ProjectJsonTestRunner(
|
||||||
|
Func<ICommandFactory, string, NuGetFramework, IDotnetTestRunner> nextRunner)
|
||||||
|
{
|
||||||
|
_nextRunner = nextRunner;
|
||||||
|
_testProjectBuilder = new TestProjectBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int RunTests(DotnetTestParams dotnetTestParams)
|
||||||
|
{
|
||||||
|
var projectPath = GetProjectPath(dotnetTestParams.ProjectOrAssemblyPath);
|
||||||
|
var runtimeIdentifiers = !string.IsNullOrEmpty(dotnetTestParams.Runtime)
|
||||||
|
? new[] {dotnetTestParams.Runtime}
|
||||||
|
: RuntimeEnvironmentRidExtensions.GetAllCandidateRuntimeIdentifiers();
|
||||||
|
var exitCode = 0;
|
||||||
|
|
||||||
|
// Create a workspace
|
||||||
|
var workspace = new BuildWorkspace(ProjectReaderSettings.ReadFromEnvironment());
|
||||||
|
|
||||||
|
if (dotnetTestParams.Framework != null)
|
||||||
|
{
|
||||||
|
var projectContext = workspace.GetProjectContext(projectPath, dotnetTestParams.Framework);
|
||||||
|
if (projectContext == null)
|
||||||
|
{
|
||||||
|
Reporter.Error.WriteLine(
|
||||||
|
$"Project '{projectPath}' does not support framework: {dotnetTestParams.UnparsedFramework}");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
projectContext = workspace.GetRuntimeContext(projectContext, runtimeIdentifiers);
|
||||||
|
|
||||||
|
exitCode = RunTests(projectContext, dotnetTestParams);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var summary = new Summary();
|
||||||
|
var projectContexts = workspace.GetProjectContextCollection(projectPath)
|
||||||
|
.EnsureValid(projectPath)
|
||||||
|
.FrameworkOnlyContexts
|
||||||
|
.Select(c => workspace.GetRuntimeContext(c, runtimeIdentifiers))
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
// Execute for all TFMs the project targets.
|
||||||
|
foreach (var projectContext in projectContexts)
|
||||||
|
{
|
||||||
|
var result = RunTests(projectContext, dotnetTestParams);
|
||||||
|
if (result == 0)
|
||||||
|
{
|
||||||
|
summary.Passed++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
summary.Failed++;
|
||||||
|
if (exitCode == 0)
|
||||||
|
{
|
||||||
|
// If tests fail in more than one TFM, we'll have it use the result of the first one
|
||||||
|
// as the exit code.
|
||||||
|
exitCode = result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
summary.Print();
|
||||||
|
}
|
||||||
|
|
||||||
|
return exitCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int RunTests(ProjectContext projectContext, DotnetTestParams dotnetTestParams)
|
||||||
|
{
|
||||||
|
var result = _testProjectBuilder.BuildTestProject(projectContext, dotnetTestParams);
|
||||||
|
|
||||||
|
if (result == 0)
|
||||||
|
{
|
||||||
|
var commandFactory =
|
||||||
|
new ProjectDependenciesCommandFactory(
|
||||||
|
projectContext.TargetFramework,
|
||||||
|
dotnetTestParams.Config,
|
||||||
|
dotnetTestParams.Output,
|
||||||
|
dotnetTestParams.BuildBasePath,
|
||||||
|
projectContext.ProjectDirectory);
|
||||||
|
|
||||||
|
var assemblyUnderTest = new AssemblyUnderTest(projectContext, dotnetTestParams);
|
||||||
|
|
||||||
|
var framework = projectContext.TargetFramework;
|
||||||
|
|
||||||
|
result = _nextRunner(commandFactory, assemblyUnderTest.Path, framework).RunTests(dotnetTestParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetProjectPath(string projectPath)
|
||||||
|
{
|
||||||
|
projectPath = projectPath ?? Directory.GetCurrentDirectory();
|
||||||
|
|
||||||
|
if (!projectPath.EndsWith(Project.FileName))
|
||||||
|
{
|
||||||
|
projectPath = Path.Combine(projectPath, Project.FileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!File.Exists(projectPath))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException($"{projectPath} does not exist.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return projectPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class Summary
|
||||||
|
{
|
||||||
|
public int Passed { get; set; }
|
||||||
|
|
||||||
|
public int Failed { get; set; }
|
||||||
|
|
||||||
|
private int Total => Passed + Failed;
|
||||||
|
|
||||||
|
public void Print()
|
||||||
|
{
|
||||||
|
var summaryMessage = $"SUMMARY: Total: {Total} targets, Passed: {Passed}, Failed: {Failed}.";
|
||||||
|
if (Failed > 0)
|
||||||
|
{
|
||||||
|
Reporter.Error.WriteLine(summaryMessage.Red());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Reporter.Output.WriteLine(summaryMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -97,6 +97,20 @@ namespace Microsoft.Dotnet.Tools.Test.Tests
|
||||||
result.Should().Pass();
|
result.Should().Pass();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void It_runs_tests_for_an_assembly_passed_as_param()
|
||||||
|
{
|
||||||
|
var buildCommand = new BuildCommand(_projectFilePath);
|
||||||
|
var result = buildCommand.Execute();
|
||||||
|
result.Should().Pass();
|
||||||
|
|
||||||
|
var assemblyUnderTestPath = Path.Combine(_defaultOutputPath, buildCommand.GetPortableOutputName());
|
||||||
|
|
||||||
|
var testCommand = new DotnetTestCommand();
|
||||||
|
result = testCommand.Execute($"{assemblyUnderTestPath}");
|
||||||
|
result.Should().Pass();
|
||||||
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData("ArgumentNames")]
|
[MemberData("ArgumentNames")]
|
||||||
public void It_fails_correctly_with_unspecified_arguments_with_long_form(string argument)
|
public void It_fails_correctly_with_unspecified_arguments_with_long_form(string argument)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue