diff --git a/src/Directory.Build.props b/src/Directory.Build.props
index 2e86a1fa..ab0483da 100644
--- a/src/Directory.Build.props
+++ b/src/Directory.Build.props
@@ -6,6 +6,7 @@
..\NUnitAdapter.snk
..\..\Osiris.Extended.ruleset
true
+ true
diff --git a/src/NUnit.TestAdapter.Tests.Acceptance/AcceptanceTests.cs b/src/NUnit.TestAdapter.Tests.Acceptance/AcceptanceTests.cs
index daccadc8..c8167de1 100644
--- a/src/NUnit.TestAdapter.Tests.Acceptance/AcceptanceTests.cs
+++ b/src/NUnit.TestAdapter.Tests.Acceptance/AcceptanceTests.cs
@@ -9,276 +9,275 @@
using NUnit.Framework.Interfaces;
using NUnit.VisualStudio.TestAdapter.Tests.Acceptance.WorkspaceTools;
-namespace NUnit.VisualStudio.TestAdapter.Tests.Acceptance
+namespace NUnit.VisualStudio.TestAdapter.Tests.Acceptance;
+
+public class Frameworks
+{
+ public const string NetCoreApp31 = "netcoreapp3.1";
+ public const string Net50 = "net5.0";
+ public const string Net60 = "net6.0";
+ public const string Net70 = "net7.0";
+ public const string Net80 = "net8.0";
+}
+
+[Category("Acceptance")]
+public abstract class AcceptanceTests
{
- public class Frameworks
+ public static string NuGetPackageId => "NUnit3TestAdapter";
+
+ public static string NuGetPackageVersion => Initialization.Value.NupkgVersion;
+
+ public const string LowestNetfxTarget = "net462";
+ public const string LegacyProjectTargetFrameworkVersion = "v4.6.2";
+
+ protected static IEnumerable TargetFrameworks => new[]
{
- public const string NetCoreApp31 = "netcoreapp3.1";
- public const string Net50 = "net5.0";
- public const string Net60 = "net6.0";
- public const string Net70 = "net7.0";
- public const string Net80 = "net8.0";
- }
+ LowestNetfxTarget,
+ Frameworks.NetCoreApp31
+ };
- [Category("Acceptance")]
- public abstract class AcceptanceTests
+ protected static IEnumerable DotNetCliTargetFrameworks => new[]
{
- public static string NuGetPackageId => "NUnit3TestAdapter";
+ Frameworks.NetCoreApp31,
+ Frameworks.Net50,
+ Frameworks.Net60,
+ Frameworks.Net70
+ };
- public static string NuGetPackageVersion => Initialization.Value.NupkgVersion;
+ protected static IEnumerable ModernDotNetCliTargetFrameworks => new[]
+ {
+ Frameworks.Net60,
+ Frameworks.Net70,
+ Frameworks.Net80
+ };
- public const string LowestNetfxTarget = "net462";
- public const string LegacyProjectTargetFrameworkVersion = "v4.6.2";
+ protected static string NUnit3 => "3.*";
+ protected static string NUnit4 => "4.*";
- protected static IEnumerable TargetFrameworks => new[]
- {
- LowestNetfxTarget,
- Frameworks.NetCoreApp31
- };
+ public class MultiFrameworkSource
+ {
+ public IEnumerable Frameworks { get; set; } = DotNetCliTargetFrameworks;
+ public string NUnitVersion { get; set; } = NUnit3;
- protected static IEnumerable DotNetCliTargetFrameworks => new[]
+ public static IEnumerable LegacyDotNetFrameworks => new List { new() };
+
+ public static IEnumerable ModernDotNetFrameworks => new List
{
- Frameworks.NetCoreApp31,
- Frameworks.Net50,
- Frameworks.Net60,
- Frameworks.Net70
+ new ()
+ {
+ Frameworks = ModernDotNetCliTargetFrameworks,
+ NUnitVersion = NUnit4
+ }
};
- protected static IEnumerable ModernDotNetCliTargetFrameworks => new[]
+ public static IEnumerable NetFxFrameworks => new List
{
- Frameworks.Net60,
- Frameworks.Net70,
- Frameworks.Net80
+ new ()
+ {
+ Frameworks = new List { LowestNetfxTarget },
+ NUnitVersion = NUnit4
+ }
};
- protected static string NUnit3 => "3.*";
- protected static string NUnit4 => "4.*";
+ public static IEnumerable AllFrameworks => LegacyDotNetFrameworks.Concat(ModernDotNetFrameworks).Concat(NetFxFrameworks);
+ }
- public class MultiFrameworkSource
- {
- public IEnumerable Frameworks { get; set; } = DotNetCliTargetFrameworks;
- public string NUnitVersion { get; set; } = NUnit3;
+ public class SingleFrameworkSource
+ {
+ public string Framework { get; set; } = LowestNetfxTarget;
+ public string NUnitVersion { get; set; } = NUnit4;
- public static IEnumerable LegacyDotNetFrameworks => new List { new() };
+ public static IEnumerable NetFxFramework => new List { new() };
- public static IEnumerable ModernDotNetFrameworks => new List
+ public static IEnumerable LegacyDotNetFramework => new List
+ {
+ new ()
{
- new ()
- {
- Frameworks = ModernDotNetCliTargetFrameworks,
- NUnitVersion = NUnit4
- }
- };
+ Framework = Frameworks.NetCoreApp31,
+ NUnitVersion = NUnit3
+ },
+ new ()
+ {
+ Framework = Frameworks.Net50,
+ NUnitVersion = NUnit3
+ }
+ };
- public static IEnumerable NetFxFrameworks => new List
+ public static IEnumerable ModernDotNetFramework => new List
+ {
+ new ()
{
- new ()
- {
- Frameworks = new List { LowestNetfxTarget },
- NUnitVersion = NUnit4
- }
- };
+ Framework = Frameworks.Net60,
+ NUnitVersion = NUnit4
+ },
+ new ()
+ {
+ Framework = Frameworks.Net70,
+ NUnitVersion = NUnit4
+ },
+ new ()
+ {
+ Framework = Frameworks.Net80,
+ NUnitVersion = NUnit4
+ }
+ };
- public static IEnumerable AllFrameworks => LegacyDotNetFrameworks.Concat(ModernDotNetFrameworks).Concat(NetFxFrameworks);
- }
+ public static IEnumerable AllFrameworks => NetFxFramework.Concat(LegacyDotNetFramework).Concat(ModernDotNetFramework);
+ public static IEnumerable AllFrameworksExceptNetFx => LegacyDotNetFramework.Concat(ModernDotNetFramework);
+ }
- public class SingleFrameworkSource
+ protected string NUnitVersion(string targetFramework) =>
+ targetFramework switch
{
- public string Framework { get; set; } = LowestNetfxTarget;
- public string NUnitVersion { get; set; } = NUnit4;
-
- public static IEnumerable NetFxFramework => new List { new() };
+ Frameworks.NetCoreApp31
+ or Frameworks.Net50 => NUnit3,
+ _ => NUnit4,
+ };
- public static IEnumerable LegacyDotNetFramework => new List
- {
- new ()
- {
- Framework = Frameworks.NetCoreApp31,
- NUnitVersion = NUnit3
- },
- new ()
- {
- Framework = Frameworks.Net50,
- NUnitVersion = NUnit3
- }
- };
+ private static readonly Lazy<(IsolatedWorkspaceManager Manager, string NupkgVersion, bool KeepWorkspaces)> Initialization = new(() =>
+ {
+ var directory = TestContext.Parameters["ProjectWorkspaceDirectory"]
+ ?? TryAutoDetectProjectWorkspaceDirectory()
+ ?? throw new InvalidOperationException("The test parameter ProjectWorkspaceDirectory must be set in order to run this test.");
+
+ var nupkgDirectory = TestContext.Parameters["TestNupkgDirectory"]
+ ?? TryAutoDetectTestNupkgDirectory(NuGetPackageId)
+ ?? throw new InvalidOperationException("The test parameter TestNupkgDirectory must be set in order to run this test.");
+
+ var nupkgVersion = TryGetTestNupkgVersion(nupkgDirectory, packageId: NuGetPackageId)
+ ?? throw new InvalidOperationException($"No NuGet package with the ID {NuGetPackageId} was found in {nupkgDirectory}.");
+
+ var keepWorkspaces = TestContext.Parameters.Get("KeepWorkspaces", defaultValue: false);
+
+ var packageCachePath = Path.Combine(directory, ".isolatednugetcache");
+ ClearCachedTestNupkgs(packageCachePath);
+
+ var manager = new IsolatedWorkspaceManager(
+ reason: string.Join(
+ Environment.NewLine,
+ "Test assembly: " + typeof(AcceptanceTests).Assembly.Location,
+ "Runner process: " + Process.GetCurrentProcess().MainModule.FileName),
+ directory,
+ nupkgDirectory,
+ packageCachePath,
+ downloadCachePath: Path.Combine(directory, ".toolcache"));
+
+ if (keepWorkspaces) manager.PreserveDirectory("The KeepWorkspaces test parameter was set to true.");
+ TestContext.WriteLine($"Directory: {directory}, NugetPackageDirectory {nupkgDirectory},NugetPackageVersion: {nupkgVersion}");
+ return (manager, nupkgVersion, keepWorkspaces);
+ });
+
+ private static void ClearCachedTestNupkgs(string packageCachePath)
+ {
+ Utils.DeleteDirectoryRobust(Path.Combine(packageCachePath, NuGetPackageId));
+ }
- public static IEnumerable ModernDotNetFramework => new List
- {
- new ()
- {
- Framework = Frameworks.Net60,
- NUnitVersion = NUnit4
- },
- new ()
- {
- Framework = Frameworks.Net70,
- NUnitVersion = NUnit4
- },
- new ()
- {
- Framework = Frameworks.Net80,
- NUnitVersion = NUnit4
- }
- };
+ private static readonly Dictionary> WorkspacesByTestId = [];
- public static IEnumerable AllFrameworks => NetFxFramework.Concat(LegacyDotNetFramework).Concat(ModernDotNetFramework);
- public static IEnumerable AllFrameworksExceptNetFx => LegacyDotNetFramework.Concat(ModernDotNetFramework);
- }
+ protected static IsolatedWorkspace CreateWorkspace()
+ {
+ var test = TestContext.CurrentContext?.Test ?? throw new InvalidOperationException("There is no current test.");
+ const string chars = "=()!,~-";
+ string name = chars.Aggregate(test.Name, (current, ch) => current.Replace(ch, '_'));
+ var workspace = Initialization.Value.Manager.CreateWorkspace(name);
- protected string NUnitVersion(string targetFramework) =>
- targetFramework switch
- {
- Frameworks.NetCoreApp31
- or Frameworks.Net50 => NUnit3,
- _ => NUnit4,
- };
-
- private static readonly Lazy<(IsolatedWorkspaceManager Manager, string NupkgVersion, bool KeepWorkspaces)> Initialization = new(() =>
- {
- var directory = TestContext.Parameters["ProjectWorkspaceDirectory"]
- ?? TryAutoDetectProjectWorkspaceDirectory()
- ?? throw new InvalidOperationException("The test parameter ProjectWorkspaceDirectory must be set in order to run this test.");
-
- var nupkgDirectory = TestContext.Parameters["TestNupkgDirectory"]
- ?? TryAutoDetectTestNupkgDirectory(NuGetPackageId)
- ?? throw new InvalidOperationException("The test parameter TestNupkgDirectory must be set in order to run this test.");
-
- var nupkgVersion = TryGetTestNupkgVersion(nupkgDirectory, packageId: NuGetPackageId)
- ?? throw new InvalidOperationException($"No NuGet package with the ID {NuGetPackageId} was found in {nupkgDirectory}.");
-
- var keepWorkspaces = TestContext.Parameters.Get("KeepWorkspaces", defaultValue: false);
-
- var packageCachePath = Path.Combine(directory, ".isolatednugetcache");
- ClearCachedTestNupkgs(packageCachePath);
-
- var manager = new IsolatedWorkspaceManager(
- reason: string.Join(
- Environment.NewLine,
- "Test assembly: " + typeof(AcceptanceTests).Assembly.Location,
- "Runner process: " + Process.GetCurrentProcess().MainModule.FileName),
- directory,
- nupkgDirectory,
- packageCachePath,
- downloadCachePath: Path.Combine(directory, ".toolcache"));
-
- if (keepWorkspaces) manager.PreserveDirectory("The KeepWorkspaces test parameter was set to true.");
- TestContext.WriteLine($"Directory: {directory}, NugetPackageDirectory {nupkgDirectory},NugetPackageVersion: {nupkgVersion}");
- return (manager, nupkgVersion, keepWorkspaces);
- });
-
- private static void ClearCachedTestNupkgs(string packageCachePath)
+ lock (WorkspacesByTestId)
{
- Utils.DeleteDirectoryRobust(Path.Combine(packageCachePath, NuGetPackageId));
+ if (!WorkspacesByTestId.TryGetValue(test.ID, out var workspaces))
+ WorkspacesByTestId.Add(test.ID, workspaces = []);
+ workspaces.Add(workspace);
}
+ return workspace;
+ }
- private static readonly Dictionary> WorkspacesByTestId = new();
+ protected static void InconclusiveOnException(Action action)
+ {
+ Assume.That(action.Invoke, Throws.Nothing);
+ }
+
+ [TearDown]
+ public static void TearDown()
+ {
+ var test = TestContext.CurrentContext?.Test ?? throw new InvalidOperationException("There is no current test.");
- protected static IsolatedWorkspace CreateWorkspace()
+ List workspaces;
+ lock (WorkspacesByTestId)
{
- var test = TestContext.CurrentContext?.Test ?? throw new InvalidOperationException("There is no current test.");
- const string chars = "=()!,~-";
- string name = chars.Aggregate(test.Name, (current, ch) => current.Replace(ch, '_'));
- var workspace = Initialization.Value.Manager.CreateWorkspace(name);
+ if (!WorkspacesByTestId.TryGetValue(test.ID, out workspaces))
+ return;
- lock (WorkspacesByTestId)
- {
- if (!WorkspacesByTestId.TryGetValue(test.ID, out var workspaces))
- WorkspacesByTestId.Add(test.ID, workspaces = new List());
- workspaces.Add(workspace);
- }
- return workspace;
+ WorkspacesByTestId.Remove(test.ID);
}
- protected static void InconclusiveOnException(Action action)
+ foreach (var workspace in workspaces)
+ workspace.Dispose();
+
+ if (TestContext.CurrentContext.Result.Outcome.Status == TestStatus.Failed)
{
- Assume.That(action.Invoke, Throws.Nothing);
+ Initialization.Value.Manager.PreserveDirectory(
+ test.FullName + " failed:" + Environment.NewLine
+ + TestContext.CurrentContext.Result.Message.TrimEnd() + Environment.NewLine);
}
-
- [TearDown]
- public static void TearDown()
+ else if (!Initialization.Value.KeepWorkspaces)
{
- var test = TestContext.CurrentContext?.Test ?? throw new InvalidOperationException("There is no current test.");
-
- List workspaces;
- lock (WorkspacesByTestId)
- {
- if (!WorkspacesByTestId.TryGetValue(test.ID, out workspaces))
- return;
-
- WorkspacesByTestId.Remove(test.ID);
- }
-
foreach (var workspace in workspaces)
- workspace.Dispose();
-
- if (TestContext.CurrentContext.Result.Outcome.Status == TestStatus.Failed)
- {
- Initialization.Value.Manager.PreserveDirectory(
- test.FullName + " failed:" + Environment.NewLine
- + TestContext.CurrentContext.Result.Message.TrimEnd() + Environment.NewLine);
- }
- else if (!Initialization.Value.KeepWorkspaces)
- {
- foreach (var workspace in workspaces)
- Utils.DeleteDirectoryRobust(workspace.Directory);
- }
+ Utils.DeleteDirectoryRobust(workspace.Directory);
}
+ }
- internal static void OnGlobalTeardown()
- {
- if (!Initialization.IsValueCreated) return;
+ internal static void OnGlobalTeardown()
+ {
+ if (!Initialization.IsValueCreated) return;
- Initialization.Value.Manager.Dispose();
- }
+ Initialization.Value.Manager.Dispose();
+ }
- private static string TryAutoDetectProjectWorkspaceDirectory()
+ private static string TryAutoDetectProjectWorkspaceDirectory()
+ {
+ for (var directory = TestContext.CurrentContext.TestDirectory; directory != null; directory = Path.GetDirectoryName(directory))
{
- for (var directory = TestContext.CurrentContext.TestDirectory; directory != null; directory = Path.GetDirectoryName(directory))
+ if (File.Exists(Path.Combine(directory, "build.cake")))
{
- if (File.Exists(Path.Combine(directory, "build.cake")))
- {
- return Path.Combine(directory, ".acceptance");
- }
+ return Path.Combine(directory, ".acceptance");
}
-
- return null;
}
- private static string TryAutoDetectTestNupkgDirectory(string packageId)
+ return null;
+ }
+
+ private static string TryAutoDetectTestNupkgDirectory(string packageId)
+ {
+ // Keep in sync with build.cake.
+
+ // Search for it
+ for (var directory = TestContext.CurrentContext.TestDirectory; directory != null; directory = Path.GetDirectoryName(directory))
{
- // Keep in sync with build.cake.
+ var packagePath = Path.Combine(directory, "package");
- // Search for it
- for (var directory = TestContext.CurrentContext.TestDirectory; directory != null; directory = Path.GetDirectoryName(directory))
+ try
{
- var packagePath = Path.Combine(directory, "package");
-
- try
- {
- if (Directory.EnumerateFiles(Path.Combine(directory, "package"), packageId + ".*.nupkg").Any())
- {
- return packagePath;
- }
- }
- catch (DirectoryNotFoundException)
+ if (Directory.EnumerateFiles(Path.Combine(directory, "package"), packageId + ".*.nupkg").Any())
{
+ return packagePath;
}
}
-
- return null;
+ catch (DirectoryNotFoundException)
+ {
+ }
}
- private static string TryGetTestNupkgVersion(string directory, string packageId)
- {
- var dir = new DirectoryInfo(directory);
- var packages = dir.EnumerateFiles(packageId + ".*.nupkg").ToList();
- var selected = packages.Count > 1 ? packages.OrderByDescending(f => f.LastWriteTime).First() : packages.SingleOrDefault();
+ return null;
+ }
+
+ private static string TryGetTestNupkgVersion(string directory, string packageId)
+ {
+ var dir = new DirectoryInfo(directory);
+ var packages = dir.EnumerateFiles(packageId + ".*.nupkg").ToList();
+ var selected = packages.Count > 1 ? packages.OrderByDescending(f => f.LastWriteTime).First() : packages.SingleOrDefault();
- var path = selected?.FullName;
+ var path = selected?.FullName;
- return path is null ? null :
- Path.GetFileNameWithoutExtension(path).Substring(packageId.Length + 1);
- }
+ return path is null ? null :
+ Path.GetFileNameWithoutExtension(path).Substring(packageId.Length + 1);
}
-}
+}
\ No newline at end of file
diff --git a/src/NUnit.TestAdapter.Tests.Acceptance/AcceptanceTestsTeardownFixture.cs b/src/NUnit.TestAdapter.Tests.Acceptance/AcceptanceTestsTeardownFixture.cs
index 7c97a49e..1c8dc83a 100644
--- a/src/NUnit.TestAdapter.Tests.Acceptance/AcceptanceTestsTeardownFixture.cs
+++ b/src/NUnit.TestAdapter.Tests.Acceptance/AcceptanceTestsTeardownFixture.cs
@@ -1,15 +1,14 @@
using NUnit.Framework;
-namespace NUnit.VisualStudio.TestAdapter.Tests.Acceptance
+namespace NUnit.VisualStudio.TestAdapter.Tests.Acceptance;
+
+// https://github.com/nunit/nunit/issues/3166
+[SetUpFixture]
+public sealed class AcceptanceTestsTeardownFixture
{
- // https://github.com/nunit/nunit/issues/3166
- [SetUpFixture]
- public sealed class AcceptanceTestsTeardownFixture
+ [OneTimeTearDown]
+ public static void OneTimeTearDown()
{
- [OneTimeTearDown]
- public static void OneTimeTearDown()
- {
- AcceptanceTests.OnGlobalTeardown();
- }
+ AcceptanceTests.OnGlobalTeardown();
}
-}
+}
\ No newline at end of file
diff --git a/src/NUnit.TestAdapter.Tests.Acceptance/BundledDependencyTests.cs b/src/NUnit.TestAdapter.Tests.Acceptance/BundledDependencyTests.cs
index d2b94421..968c07eb 100644
--- a/src/NUnit.TestAdapter.Tests.Acceptance/BundledDependencyTests.cs
+++ b/src/NUnit.TestAdapter.Tests.Acceptance/BundledDependencyTests.cs
@@ -1,15 +1,15 @@
using NUnit.Framework;
using NUnit.VisualStudio.TestAdapter.Tests.Acceptance.WorkspaceTools;
-namespace NUnit.VisualStudio.TestAdapter.Tests.Acceptance
+namespace NUnit.VisualStudio.TestAdapter.Tests.Acceptance;
+
+public sealed class BundledDependencyTests : AcceptanceTests
{
- public sealed class BundledDependencyTests : AcceptanceTests
+ [Test, Platform("Win")]
+ public static void User_tests_get_the_version_of_Mono_Cecil_referenced_from_the_test_project()
{
- [Test, Platform("Win")]
- public static void User_tests_get_the_version_of_Mono_Cecil_referenced_from_the_test_project()
- {
- var workspace = CreateWorkspace()
- .AddProject("Test.csproj", $@"
+ var workspace = CreateWorkspace()
+ .AddProject("Test.csproj", $@"
@@ -28,7 +28,7 @@ public static void User_tests_get_the_version_of_Mono_Cecil_referenced_from_the_
")
- .AddFile("BundledDependencyTests.cs", @"
+ .AddFile("BundledDependencyTests.cs", @"
using System.Diagnostics;
using System.Reflection;
using NUnit.Framework;
@@ -50,19 +50,19 @@ public static void User_tests_get_the_version_of_Mono_Cecil_referenced_from_the_
}
}");
- workspace.MsBuild(restore: true);
+ workspace.MsBuild(restore: true);
- foreach (var targetFramework in TargetFrameworks)
- {
- workspace.VSTest($@"bin\Debug\{targetFramework}\Test.dll", VsTestFilter.NoFilter);
- }
+ foreach (var targetFramework in TargetFrameworks)
+ {
+ workspace.VSTest($@"bin\Debug\{targetFramework}\Test.dll", VsTestFilter.NoFilter);
}
+ }
- [Test, Platform("Win")]
- public static void Engine_uses_its_bundled_version_of_Mono_Cecil_instead_of_the_version_referenced_by_the_test_project()
- {
- var workspace = CreateWorkspace()
- .AddProject("Test.csproj", $@"
+ [Test, Platform("Win")]
+ public static void Engine_uses_its_bundled_version_of_Mono_Cecil_instead_of_the_version_referenced_by_the_test_project()
+ {
+ var workspace = CreateWorkspace()
+ .AddProject("Test.csproj", $@"
@@ -89,7 +89,7 @@ public static void Engine_uses_its_bundled_version_of_Mono_Cecil_instead_of_the_
")
- .AddFile("BundledDependencyTests.cs", @"
+ .AddFile("BundledDependencyTests.cs", @"
using System.Diagnostics;
using System.Reflection;
using NUnit.Framework;
@@ -110,7 +110,7 @@ public void Engine_uses_its_bundled_version_of_Mono_Cecil_instead_of_the_version
Assert.That(versionBlock.ProductVersion, Is.EqualTo(""0.10.0.0""));
}
}")
- .AddFile("TestNUnitEngineExtension.cs", @"
+ .AddFile("TestNUnitEngineExtension.cs", @"
using NUnit.Engine;
using NUnit.Engine.Extensibility;
@@ -125,15 +125,14 @@ public void OnTestEvent(string report)
{
}
}")
- .AddFile("test.addins", @"
+ .AddFile("test.addins", @"
Test.dll");
- workspace.MsBuild(restore: true);
+ workspace.MsBuild(restore: true);
- foreach (var targetFramework in TargetFrameworks)
- {
- workspace.VSTest($@"bin\Debug\{targetFramework}\Test.dll", VsTestFilter.NoFilter);
- }
+ foreach (var targetFramework in TargetFrameworks)
+ {
+ workspace.VSTest($@"bin\Debug\{targetFramework}\Test.dll", VsTestFilter.NoFilter);
}
}
-}
+}
\ No newline at end of file
diff --git a/src/NUnit.TestAdapter.Tests.Acceptance/ConsoleOutTests.cs b/src/NUnit.TestAdapter.Tests.Acceptance/ConsoleOutTests.cs
index 33090440..dcece252 100644
--- a/src/NUnit.TestAdapter.Tests.Acceptance/ConsoleOutTests.cs
+++ b/src/NUnit.TestAdapter.Tests.Acceptance/ConsoleOutTests.cs
@@ -1,12 +1,12 @@
using NUnit.Framework;
using NUnit.VisualStudio.TestAdapter.Tests.Acceptance.WorkspaceTools;
-namespace NUnit.VisualStudio.TestAdapter.Tests.Acceptance
+namespace NUnit.VisualStudio.TestAdapter.Tests.Acceptance;
+
+public sealed class ConsoleOutTests : CsProjAcceptanceTests
{
- public sealed class ConsoleOutTests : CsProjAcceptanceTests
+ protected override void AddTestsCs(IsolatedWorkspace workspace)
{
- protected override void AddTestsCs(IsolatedWorkspace workspace)
- {
workspace.AddFile("Issue774.cs", @"
using System;
using NUnit.Framework;
@@ -32,22 +32,21 @@ public void Test2()
}");
}
- protected override string Framework => Frameworks.NetCoreApp31;
+ protected override string Framework => Frameworks.NetCoreApp31;
- [Test, Platform("Win")]
- public void DotNetTest()
- {
+ [Test, Platform("Win")]
+ public void DotNetTest()
+ {
var workspace = Build();
var results = workspace.DotNetTest("", true, true, TestContext.WriteLine);
Verify(2, 2, results);
}
- [Test, Platform("Win")]
- public void VsTest()
- {
+ [Test, Platform("Win")]
+ public void VsTest()
+ {
var workspace = Build();
var results = workspace.VSTest($@"bin\Debug\{Framework}\Test.dll", VsTestFilter.NoFilter);
Verify(2, 2, results);
}
- }
}
\ No newline at end of file
diff --git a/src/NUnit.TestAdapter.Tests.Acceptance/CsProjAcceptanceTests.cs b/src/NUnit.TestAdapter.Tests.Acceptance/CsProjAcceptanceTests.cs
index c8103052..d3c1af7b 100644
--- a/src/NUnit.TestAdapter.Tests.Acceptance/CsProjAcceptanceTests.cs
+++ b/src/NUnit.TestAdapter.Tests.Acceptance/CsProjAcceptanceTests.cs
@@ -1,18 +1,18 @@
using NUnit.Framework;
using NUnit.VisualStudio.TestAdapter.Tests.Acceptance.WorkspaceTools;
-namespace NUnit.VisualStudio.TestAdapter.Tests.Acceptance
+namespace NUnit.VisualStudio.TestAdapter.Tests.Acceptance;
+
+public abstract class CsProjAcceptanceTests : AcceptanceTests
{
- public abstract class CsProjAcceptanceTests : AcceptanceTests
- {
- protected abstract void AddTestsCs(IsolatedWorkspace workspace);
+ protected abstract void AddTestsCs(IsolatedWorkspace workspace);
- protected abstract string Framework { get; }
- protected const string NoFilter = "";
- protected IsolatedWorkspace CreateTestWorkspace(string framework)
- {
- var workspace = CreateWorkspace()
- .AddProject("Test.csproj", $@"
+ protected abstract string Framework { get; }
+ protected const string NoFilter = "";
+ protected IsolatedWorkspace CreateTestWorkspace(string framework)
+ {
+ var workspace = CreateWorkspace()
+ .AddProject("Test.csproj", $@"
@@ -26,30 +26,29 @@ protected IsolatedWorkspace CreateTestWorkspace(string framework)
");
- return workspace;
- }
+ return workspace;
+ }
- protected IsolatedWorkspace Build()
- {
- var workspace = CreateTestWorkspace(Framework);
- AddTestsCs(workspace);
- workspace.MsBuild(restore: true);
- return workspace;
- }
+ protected IsolatedWorkspace Build()
+ {
+ var workspace = CreateTestWorkspace(Framework);
+ AddTestsCs(workspace);
+ workspace.MsBuild(restore: true);
+ return workspace;
+ }
- protected void Verify(int executed, int total, VSTestResult results)
+ protected void Verify(int executed, int total, VSTestResult results)
+ {
+ TestContext.WriteLine(" ");
+ foreach (var error in results.RunErrors)
+ TestContext.WriteLine(error);
+ Assert.Multiple(() =>
{
- TestContext.WriteLine(" ");
- foreach (var error in results.RunErrors)
- TestContext.WriteLine(error);
- Assert.Multiple(() =>
- {
- Assert.That(results.Counters.Total, Is.EqualTo(total),
- $"Total tests counter did not match expectation\n{results.ProcessRunResult.StdOut}");
- Assert.That(results.Counters.Executed, Is.EqualTo(executed),
- "Executed tests counter did not match expectation");
- Assert.That(results.Counters.Passed, Is.EqualTo(executed), "Passed tests counter did not match expectation");
- });
- }
+ Assert.That(results.Counters.Total, Is.EqualTo(total),
+ $"Total tests counter did not match expectation\n{results.ProcessRunResult.StdOut}");
+ Assert.That(results.Counters.Executed, Is.EqualTo(executed),
+ "Executed tests counter did not match expectation");
+ Assert.That(results.Counters.Passed, Is.EqualTo(executed), "Passed tests counter did not match expectation");
+ });
}
-}
+}
\ No newline at end of file
diff --git a/src/NUnit.TestAdapter.Tests.Acceptance/DirectoryMutex.cs b/src/NUnit.TestAdapter.Tests.Acceptance/DirectoryMutex.cs
index bbd87735..7fa37656 100644
--- a/src/NUnit.TestAdapter.Tests.Acceptance/DirectoryMutex.cs
+++ b/src/NUnit.TestAdapter.Tests.Acceptance/DirectoryMutex.cs
@@ -1,37 +1,36 @@
using System;
using System.IO;
-namespace NUnit.VisualStudio.TestAdapter.Tests.Acceptance
+namespace NUnit.VisualStudio.TestAdapter.Tests.Acceptance;
+
+public sealed class DirectoryMutex : IDisposable
{
- public sealed class DirectoryMutex : IDisposable
+ private readonly FileStream mutexFile;
+
+ public static DirectoryMutex TryAcquire(string directoryPath)
{
- private readonly FileStream mutexFile;
+ var mutexFilePath = Path.Combine(directoryPath, ".mutex");
- public static DirectoryMutex TryAcquire(string directoryPath)
+ FileStream stream;
+ try
{
- var mutexFilePath = Path.Combine(directoryPath, ".mutex");
-
- FileStream stream;
- try
- {
- stream = new FileStream(mutexFilePath, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize: 1, FileOptions.DeleteOnClose);
- }
- catch (IOException) // On Windows, (ushort)ex.HResult will be ERROR_SHARING_VIOLATION
- {
- return null;
- }
-
- return new DirectoryMutex(stream, directoryPath);
+ stream = new FileStream(mutexFilePath, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize: 1, FileOptions.DeleteOnClose);
}
-
- private DirectoryMutex(FileStream mutexFile, string directoryPath)
+ catch (IOException) // On Windows, (ushort)ex.HResult will be ERROR_SHARING_VIOLATION
{
- this.mutexFile = mutexFile ?? throw new ArgumentNullException(nameof(mutexFile));
- DirectoryPath = directoryPath ?? throw new ArgumentNullException(nameof(directoryPath));
+ return null;
}
- public string DirectoryPath { get; }
+ return new DirectoryMutex(stream, directoryPath);
+ }
- public void Dispose() => mutexFile.Dispose();
+ private DirectoryMutex(FileStream mutexFile, string directoryPath)
+ {
+ this.mutexFile = mutexFile ?? throw new ArgumentNullException(nameof(mutexFile));
+ DirectoryPath = directoryPath ?? throw new ArgumentNullException(nameof(directoryPath));
}
-}
+
+ public string DirectoryPath { get; }
+
+ public void Dispose() => mutexFile.Dispose();
+}
\ No newline at end of file
diff --git a/src/NUnit.TestAdapter.Tests.Acceptance/FilterTests.cs b/src/NUnit.TestAdapter.Tests.Acceptance/FilterTests.cs
index 7a4a1c81..b7129265 100644
--- a/src/NUnit.TestAdapter.Tests.Acceptance/FilterTests.cs
+++ b/src/NUnit.TestAdapter.Tests.Acceptance/FilterTests.cs
@@ -1,12 +1,12 @@
using NUnit.Framework;
using NUnit.VisualStudio.TestAdapter.Tests.Acceptance.WorkspaceTools;
-namespace NUnit.VisualStudio.TestAdapter.Tests.Acceptance
+namespace NUnit.VisualStudio.TestAdapter.Tests.Acceptance;
+
+public sealed class FilterTests : CsProjAcceptanceTests
{
- public sealed class FilterTests : CsProjAcceptanceTests
+ protected override void AddTestsCs(IsolatedWorkspace workspace)
{
- protected override void AddTestsCs(IsolatedWorkspace workspace)
- {
workspace.AddFile("Tests.cs", @"
using NUnit.Framework;
@@ -36,57 +36,56 @@ public void Bar()
}");
}
- protected override string Framework => Frameworks.NetCoreApp31;
+ protected override string Framework => Frameworks.NetCoreApp31;
- [Test, Platform("Win")]
- [TestCase(NoFilter, 2, 3)]
- [TestCase(@"TestCategory=FooGroup", 1, 2)]
- [TestCase(@"TestCategory!=BarGroup", 1, 2)]
- [TestCase(@"TestCategory=IsExplicit", 1, 1)]
- [TestCase(@"FullyQualifiedName=Filter.Tests.Foo", 1, 1)]
- [TestCase(@"FullyQualifiedName!=Filter.Tests.Foo", 1, 1)]
- [TestCase(@"TestCategory!=AllGroup", 0, 0)]
- // [TestCase(@"TestThatDontExistHere", 0, 0)]
- // [TestCase(@"FullyQualifiedName~Filter.Tests.Foo", 1, 1)]
- // [TestCase(@"FullyQualifiedName~Foo", 1, 1)]
- public void Filter_DotNetTest(string filter, int executed, int total)
- {
+ [Test, Platform("Win")]
+ [TestCase(NoFilter, 2, 3)]
+ [TestCase(@"TestCategory=FooGroup", 1, 2)]
+ [TestCase(@"TestCategory!=BarGroup", 1, 2)]
+ [TestCase(@"TestCategory=IsExplicit", 1, 1)]
+ [TestCase(@"FullyQualifiedName=Filter.Tests.Foo", 1, 1)]
+ [TestCase(@"FullyQualifiedName!=Filter.Tests.Foo", 1, 1)]
+ [TestCase(@"TestCategory!=AllGroup", 0, 0)]
+ // [TestCase(@"TestThatDontExistHere", 0, 0)]
+ // [TestCase(@"FullyQualifiedName~Filter.Tests.Foo", 1, 1)]
+ // [TestCase(@"FullyQualifiedName~Foo", 1, 1)]
+ public void Filter_DotNetTest(string filter, int executed, int total)
+ {
var workspace = Build();
var results = workspace.DotNetTest(filter, true, true, TestContext.WriteLine);
Verify(executed, total, results);
}
- [Test, Platform("Win")]
- [TestCase(NoFilter, 2, 3)]
- [TestCase(@"TestCategory=FooGroup", 1, 2)]
- [TestCase(@"TestCategory!=BarGroup", 1, 2)]
- [TestCase(@"TestCategory=IsExplicit", 1, 1)]
- [TestCase(@"FullyQualifiedName=Filter.Tests.Foo", 1, 1)]
- [TestCase(@"TestCategory=XXXX", 0, 0)]
- public void Filter_VSTest(string filter, int executed, int total)
- {
+ [Test, Platform("Win")]
+ [TestCase(NoFilter, 2, 3)]
+ [TestCase(@"TestCategory=FooGroup", 1, 2)]
+ [TestCase(@"TestCategory!=BarGroup", 1, 2)]
+ [TestCase(@"TestCategory=IsExplicit", 1, 1)]
+ [TestCase(@"FullyQualifiedName=Filter.Tests.Foo", 1, 1)]
+ [TestCase(@"TestCategory=XXXX", 0, 0)]
+ public void Filter_VSTest(string filter, int executed, int total)
+ {
var workspace = Build();
var results = workspace.VSTest($@"bin\Debug\{Framework}\Test.dll", new VsTestTestCaseFilter(filter));
Verify(executed, total, results);
}
- [Test, Platform("Win")]
- [TestCase(NoFilter, 2, 3)]
- [TestCase("Category=FooGroup", 1, 1)]
- [TestCase("cat==FooGroup", 1, 2)]
- [TestCase("cat!=FooGroup", 1, 1)]
- [TestCase("Category!=BarGroup", 1, 1)]
- [TestCase("Category=IsExplicit", 1, 1)]
- [TestCase("test==Filter.Tests.Foo", 1, 1)]
- [TestCase("name==Foo", 1, 1)]
- [TestCase("name!=Bar", 1, 1)]
- // [TestCase("test=~Foo", 1, 1)]
- public void Filter_DotNetTest_NUnitWhere(string filter, int executed, int total)
- {
+ [Test, Platform("Win")]
+ [TestCase(NoFilter, 2, 3)]
+ [TestCase("Category=FooGroup", 1, 1)]
+ [TestCase("cat==FooGroup", 1, 2)]
+ [TestCase("cat!=FooGroup", 1, 1)]
+ [TestCase("Category!=BarGroup", 1, 1)]
+ [TestCase("Category=IsExplicit", 1, 1)]
+ [TestCase("test==Filter.Tests.Foo", 1, 1)]
+ [TestCase("name==Foo", 1, 1)]
+ [TestCase("name!=Bar", 1, 1)]
+ // [TestCase("test=~Foo", 1, 1)]
+ public void Filter_DotNetTest_NUnitWhere(string filter, int executed, int total)
+ {
var workspace = Build();
var nunitWhere = $@"NUnit.Where={filter}";
var results = workspace.DotNetTest(nunitWhere, true, true, TestContext.WriteLine);
Verify(executed, total, results);
}
- }
-}
+}
\ No newline at end of file
diff --git a/src/NUnit.TestAdapter.Tests.Acceptance/FixtureTests.cs b/src/NUnit.TestAdapter.Tests.Acceptance/FixtureTests.cs
index 0b894760..3b47ee7b 100644
--- a/src/NUnit.TestAdapter.Tests.Acceptance/FixtureTests.cs
+++ b/src/NUnit.TestAdapter.Tests.Acceptance/FixtureTests.cs
@@ -1,12 +1,12 @@
using NUnit.Framework;
using NUnit.VisualStudio.TestAdapter.Tests.Acceptance.WorkspaceTools;
-namespace NUnit.VisualStudio.TestAdapter.Tests.Acceptance
+namespace NUnit.VisualStudio.TestAdapter.Tests.Acceptance;
+
+public sealed class FixtureTests : CsProjAcceptanceTests
{
- public sealed class FixtureTests : CsProjAcceptanceTests
+ protected override void AddTestsCs(IsolatedWorkspace workspace)
{
- protected override void AddTestsCs(IsolatedWorkspace workspace)
- {
workspace.AddFile("Issue918.cs", @"
using System;
using NUnit.Framework;
@@ -107,28 +107,27 @@ public void Test()
}");
}
- protected override string Framework => Frameworks.NetCoreApp31;
+ protected override string Framework => Frameworks.NetCoreApp31;
- [Test, Platform("Win")]
- [TestCase("TestCategory=869", 2, 2)]
- [TestCase("TestCategory=884", 3, 3)]
- [TestCase("TestCategory=918", 1, 1)]
- public void DotNetTest(string filter, int executed, int total)
- {
+ [Test, Platform("Win")]
+ [TestCase("TestCategory=869", 2, 2)]
+ [TestCase("TestCategory=884", 3, 3)]
+ [TestCase("TestCategory=918", 1, 1)]
+ public void DotNetTest(string filter, int executed, int total)
+ {
var workspace = Build();
var results = workspace.DotNetTest(filter, true, true, TestContext.WriteLine);
Verify(executed, total, results);
}
- [Test, Platform("Win")]
- [TestCase("TestCategory=869", 2, 2)]
- [TestCase("TestCategory=884", 3, 3)]
- [TestCase("TestCategory=918", 1, 1)]
- public void VsTest(string filter, int executed, int total)
- {
+ [Test, Platform("Win")]
+ [TestCase("TestCategory=869", 2, 2)]
+ [TestCase("TestCategory=884", 3, 3)]
+ [TestCase("TestCategory=918", 1, 1)]
+ public void VsTest(string filter, int executed, int total)
+ {
var workspace = Build();
var results = workspace.VSTest($@"bin\Debug\{Framework}\Test.dll", new VsTestTestCaseFilter(filter));
Verify(executed, total, results);
}
- }
-}
+}
\ No newline at end of file
diff --git a/src/NUnit.TestAdapter.Tests.Acceptance/NUnit.TestAdapter.Tests.Acceptance.csproj b/src/NUnit.TestAdapter.Tests.Acceptance/NUnit.TestAdapter.Tests.Acceptance.csproj
index da229795..e003b512 100644
--- a/src/NUnit.TestAdapter.Tests.Acceptance/NUnit.TestAdapter.Tests.Acceptance.csproj
+++ b/src/NUnit.TestAdapter.Tests.Acceptance/NUnit.TestAdapter.Tests.Acceptance.csproj
@@ -10,10 +10,10 @@
-
+
-
-
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
@@ -24,6 +24,7 @@
all
runtime; build; native; contentfiles; analyzers; buildtransitive
+
diff --git a/src/NUnit.TestAdapter.Tests.Acceptance/ParanthesisTests.cs b/src/NUnit.TestAdapter.Tests.Acceptance/ParanthesisTests.cs
index 232646b2..e16fac7d 100644
--- a/src/NUnit.TestAdapter.Tests.Acceptance/ParanthesisTests.cs
+++ b/src/NUnit.TestAdapter.Tests.Acceptance/ParanthesisTests.cs
@@ -1,13 +1,13 @@
using NUnit.Framework;
using NUnit.VisualStudio.TestAdapter.Tests.Acceptance.WorkspaceTools;
-namespace NUnit.VisualStudio.TestAdapter.Tests.Acceptance
+namespace NUnit.VisualStudio.TestAdapter.Tests.Acceptance;
+
+public sealed class ParanthesisTests : CsProjAcceptanceTests
{
- public sealed class ParanthesisTests : CsProjAcceptanceTests
+ protected override void AddTestsCs(IsolatedWorkspace workspace)
{
- protected override void AddTestsCs(IsolatedWorkspace workspace)
- {
- workspace.AddFile("Issue919.cs", @"
+ workspace.AddFile("Issue919.cs", @"
using System;
using NUnit.Framework;
@@ -28,59 +28,58 @@ public void Bzzt()
}
}
}");
- }
+ }
- protected override string Framework => Frameworks.NetCoreApp31;
+ protected override string Framework => Frameworks.NetCoreApp31;
- [Test, Platform("Win")]
- [TestCase]
- public void VsTestNoFilter()
- {
- var workspace = Build();
- var results = workspace.VSTest($@"bin\Debug\{Framework}\Test.dll", VsTestFilter.NoFilter);
- Verify(2, 2, results);
- }
+ [Test, Platform("Win")]
+ [TestCase]
+ public void VsTestNoFilter()
+ {
+ var workspace = Build();
+ var results = workspace.VSTest($@"bin\Debug\{Framework}\Test.dll", VsTestFilter.NoFilter);
+ Verify(2, 2, results);
+ }
- [Test, Platform("Win")]
- [TestCase(@"FullyQualifiedName=Issue919.Foo.Bzzt", 1, 1)] // Sanity check
- [TestCase(@"FullyQualifiedName=Issue919.Foo.Bar\(1\)", 0, 0)]
- [TestCase(@"FullyQualifiedName=Issue919.Foo.Baz\(1\)", 1, 1)]
- [TestCase(@"Name=Bzzt", 1, 1)] // Sanity check
- [TestCase(@"Name=Bar\(1\)", 0, 0)]
- [TestCase(@"Name=Baz\(1\)", 1, 1)]
- [TestCase(@"", 2, 2)]
- public void VsTestTestCases(string filter, int executed, int total)
- {
- var workspace = Build();
- workspace.DumpTestExecution = true;
- var results = workspace.VSTest($@"bin\Debug\{Framework}\Test.dll", new VsTestTestCaseFilter(filter));
- Verify(executed, total, results);
- }
+ [Test, Platform("Win")]
+ [TestCase(@"FullyQualifiedName=Issue919.Foo.Bzzt", 1, 1)] // Sanity check
+ [TestCase(@"FullyQualifiedName=Issue919.Foo.Bar\(1\)", 0, 0)]
+ [TestCase(@"FullyQualifiedName=Issue919.Foo.Baz\(1\)", 1, 1)]
+ [TestCase(@"Name=Bzzt", 1, 1)] // Sanity check
+ [TestCase(@"Name=Bar\(1\)", 0, 0)]
+ [TestCase(@"Name=Baz\(1\)", 1, 1)]
+ [TestCase(@"", 2, 2)]
+ public void VsTestTestCases(string filter, int executed, int total)
+ {
+ var workspace = Build();
+ workspace.DumpTestExecution = true;
+ var results = workspace.VSTest($@"bin\Debug\{Framework}\Test.dll", new VsTestTestCaseFilter(filter));
+ Verify(executed, total, results);
+ }
- [Test, Platform("Win")]
- [TestCase(@"Bzzt", 1, 1)] // Sanity check
- [TestCase(@"Bar\(1\)", 0, 0)]
- [TestCase(@"Baz\(1\)", 1, 1)]
- public void VsTestTests(string filter, int executed, int total)
- {
- var workspace = Build();
- var results = workspace.VSTest($@"bin\Debug\{Framework}\Test.dll", new VsTestTestsFilter(filter));
- Verify(executed, total, results);
- }
+ [Test, Platform("Win")]
+ [TestCase(@"Bzzt", 1, 1)] // Sanity check
+ [TestCase(@"Bar\(1\)", 0, 0)]
+ [TestCase(@"Baz\(1\)", 1, 1)]
+ public void VsTestTests(string filter, int executed, int total)
+ {
+ var workspace = Build();
+ var results = workspace.VSTest($@"bin\Debug\{Framework}\Test.dll", new VsTestTestsFilter(filter));
+ Verify(executed, total, results);
+ }
- [Test, Platform("Win")]
- [TestCase(@"FullyQualifiedName=Issue919.Foo.Bzzt", 1, 1)] // Sanity check
- [TestCase(@"FullyQualifiedName=Issue919.Foo.Bar\(1\)", 0, 0)]
- [TestCase(@"FullyQualifiedName=Issue919.Foo.Baz\(1\)", 1, 1)]
- [TestCase(@"Name=Bzzt", 1, 1)] // Sanity check
- [TestCase(@"Name=Bar\(1\)", 0, 0)]
- [TestCase(@"Name=Baz\(1\)", 1, 1)]
- [TestCase(@"", 2, 2)]
- public void DotnetTestCases(string filter, int executed, int total)
- {
- var workspace = Build();
- var results = workspace.DotNetTest(filter, true, true, TestContext.WriteLine);
- Verify(executed, total, results);
- }
+ [Test, Platform("Win")]
+ [TestCase(@"FullyQualifiedName=Issue919.Foo.Bzzt", 1, 1)] // Sanity check
+ [TestCase(@"FullyQualifiedName=Issue919.Foo.Bar\(1\)", 0, 0)]
+ [TestCase(@"FullyQualifiedName=Issue919.Foo.Baz\(1\)", 1, 1)]
+ [TestCase(@"Name=Bzzt", 1, 1)] // Sanity check
+ [TestCase(@"Name=Bar\(1\)", 0, 0)]
+ [TestCase(@"Name=Baz\(1\)", 1, 1)]
+ [TestCase(@"", 2, 2)]
+ public void DotnetTestCases(string filter, int executed, int total)
+ {
+ var workspace = Build();
+ var results = workspace.DotNetTest(filter, true, true, TestContext.WriteLine);
+ Verify(executed, total, results);
}
}
\ No newline at end of file
diff --git a/src/NUnit.TestAdapter.Tests.Acceptance/PropertyTests.cs b/src/NUnit.TestAdapter.Tests.Acceptance/PropertyTests.cs
index 95afad49..7f29363e 100644
--- a/src/NUnit.TestAdapter.Tests.Acceptance/PropertyTests.cs
+++ b/src/NUnit.TestAdapter.Tests.Acceptance/PropertyTests.cs
@@ -1,13 +1,13 @@
using NUnit.Framework;
using NUnit.VisualStudio.TestAdapter.Tests.Acceptance.WorkspaceTools;
-namespace NUnit.VisualStudio.TestAdapter.Tests.Acceptance
+namespace NUnit.VisualStudio.TestAdapter.Tests.Acceptance;
+
+public sealed class PropertyTests : CsProjAcceptanceTests
{
- public sealed class PropertyTests : CsProjAcceptanceTests
+ protected override void AddTestsCs(IsolatedWorkspace workspace)
{
- protected override void AddTestsCs(IsolatedWorkspace workspace)
- {
- workspace.AddFile("Issue779.cs", @"
+ workspace.AddFile("Issue779.cs", @"
using System;
using NUnit.Framework;
@@ -29,30 +29,29 @@ public void Test2()
}
}
}");
- }
+ }
- protected override string Framework => Frameworks.NetCoreApp31;
+ protected override string Framework => Frameworks.NetCoreApp31;
- [Test, Platform("Win")]
- [TestCase("Bug=99999", 0, 0)]
- [TestCase("Bug=12345", 1, 1)]
- [TestCase("Bug!=12345", 1, 1)]
- public void DotNetTest(string filter, int executed, int total)
- {
- var workspace = Build();
- var results = workspace.DotNetTest(filter, true, true, TestContext.WriteLine);
- Verify(executed, total, results);
- }
+ [Test, Platform("Win")]
+ [TestCase("Bug=99999", 0, 0)]
+ [TestCase("Bug=12345", 1, 1)]
+ [TestCase("Bug!=12345", 1, 1)]
+ public void DotNetTest(string filter, int executed, int total)
+ {
+ var workspace = Build();
+ var results = workspace.DotNetTest(filter, true, true, TestContext.WriteLine);
+ Verify(executed, total, results);
+ }
- [Test, Platform("Win")]
- [TestCase("Bug=99999", 0, 0)]
- [TestCase("Bug=12345", 1, 1)]
- [TestCase("Bug!=12345", 1, 1)]
- public void VsTest(string filter, int executed, int total)
- {
- var workspace = Build();
- var results = workspace.VSTest($@"bin\Debug\{Framework}\Test.dll", new VsTestTestCaseFilter(filter));
- Verify(executed, total, results);
- }
+ [Test, Platform("Win")]
+ [TestCase("Bug=99999", 0, 0)]
+ [TestCase("Bug=12345", 1, 1)]
+ [TestCase("Bug!=12345", 1, 1)]
+ public void VsTest(string filter, int executed, int total)
+ {
+ var workspace = Build();
+ var results = workspace.VSTest($@"bin\Debug\{Framework}\Test.dll", new VsTestTestCaseFilter(filter));
+ Verify(executed, total, results);
}
}
\ No newline at end of file
diff --git a/src/NUnit.TestAdapter.Tests.Acceptance/SinglePassingTestResultTests.cs b/src/NUnit.TestAdapter.Tests.Acceptance/SinglePassingTestResultTests.cs
index 744021b1..6e79061d 100644
--- a/src/NUnit.TestAdapter.Tests.Acceptance/SinglePassingTestResultTests.cs
+++ b/src/NUnit.TestAdapter.Tests.Acceptance/SinglePassingTestResultTests.cs
@@ -1,13 +1,13 @@
using NUnit.Framework;
using NUnit.VisualStudio.TestAdapter.Tests.Acceptance.WorkspaceTools;
-namespace NUnit.VisualStudio.TestAdapter.Tests.Acceptance
+namespace NUnit.VisualStudio.TestAdapter.Tests.Acceptance;
+
+public sealed class SinglePassingTestResultTests : AcceptanceTests
{
- public sealed class SinglePassingTestResultTests : AcceptanceTests
+ private void AddTestsCs(IsolatedWorkspace workspace)
{
- private void AddTestsCs(IsolatedWorkspace workspace)
- {
- workspace.AddFile("Tests.cs", @"
+ workspace.AddFile("Tests.cs", @"
using NUnit.Framework;
namespace Test
@@ -21,11 +21,11 @@ public void PassingTest()
}
}
}");
- }
+ }
- private void AddTestsVb(IsolatedWorkspace workspace)
- {
- workspace.AddFile("Tests.vb", @"
+ private void AddTestsVb(IsolatedWorkspace workspace)
+ {
+ workspace.AddFile("Tests.vb", @"
Imports NUnit.Framework
Namespace Test
@@ -38,11 +38,11 @@ End Sub
End Class
End Namespace");
- }
+ }
- private IsolatedWorkspace CreateSingleTargetWorkspace(string fileName, SingleFrameworkSource source) =>
- CreateWorkspace()
- .AddProject(fileName, $@"
+ private IsolatedWorkspace CreateSingleTargetWorkspace(string fileName, SingleFrameworkSource source) =>
+ CreateWorkspace()
+ .AddProject(fileName, $@"
@@ -58,49 +58,49 @@ private IsolatedWorkspace CreateSingleTargetWorkspace(string fileName, SingleFra
");
- [TestCaseSource(typeof(SingleFrameworkSource), nameof(SingleFrameworkSource.AllFrameworks))]
- [Platform("Win")]
- public void Single_target_csproj(SingleFrameworkSource source)
- {
- var workspace = CreateSingleTargetWorkspace("Test.csproj", source);
- AddTestsCs(workspace);
- workspace.MsBuild(restore: true);
- workspace.VSTest($@"bin\Debug\{source.Framework}\Test.dll", VsTestFilter.NoFilter)
- .AssertSinglePassingTest();
- }
+ [TestCaseSource(typeof(SingleFrameworkSource), nameof(SingleFrameworkSource.AllFrameworks))]
+ [Platform("Win")]
+ public void Single_target_csproj(SingleFrameworkSource source)
+ {
+ var workspace = CreateSingleTargetWorkspace("Test.csproj", source);
+ AddTestsCs(workspace);
+ workspace.MsBuild(restore: true);
+ workspace.VSTest($@"bin\Debug\{source.Framework}\Test.dll", VsTestFilter.NoFilter)
+ .AssertSinglePassingTest();
+ }
- [TestCaseSource(typeof(SingleFrameworkSource), nameof(SingleFrameworkSource.AllFrameworksExceptNetFx))]
- [Platform("Win")]
- public void Single_target_csproj_dotnet_CLI(SingleFrameworkSource source)
- {
- var workspace = CreateSingleTargetWorkspace("Test.csproj", source);
- AddTestsCs(workspace);
- workspace.DotNetTest().AssertSinglePassingTest();
- }
+ [TestCaseSource(typeof(SingleFrameworkSource), nameof(SingleFrameworkSource.AllFrameworksExceptNetFx))]
+ [Platform("Win")]
+ public void Single_target_csproj_dotnet_CLI(SingleFrameworkSource source)
+ {
+ var workspace = CreateSingleTargetWorkspace("Test.csproj", source);
+ AddTestsCs(workspace);
+ workspace.DotNetTest().AssertSinglePassingTest();
+ }
- [TestCaseSource(typeof(SingleFrameworkSource), nameof(SingleFrameworkSource.AllFrameworks))]
- [Platform("Win")]
- public void Single_target_vbproj(SingleFrameworkSource source)
- {
- var workspace = CreateSingleTargetWorkspace("Test.vbproj", source);
- AddTestsVb(workspace);
- workspace.MsBuild(restore: true);
- workspace.VSTest($@"bin\Debug\{source.Framework}\Test.dll", VsTestFilter.NoFilter)
- .AssertSinglePassingTest();
- }
+ [TestCaseSource(typeof(SingleFrameworkSource), nameof(SingleFrameworkSource.AllFrameworks))]
+ [Platform("Win")]
+ public void Single_target_vbproj(SingleFrameworkSource source)
+ {
+ var workspace = CreateSingleTargetWorkspace("Test.vbproj", source);
+ AddTestsVb(workspace);
+ workspace.MsBuild(restore: true);
+ workspace.VSTest($@"bin\Debug\{source.Framework}\Test.dll", VsTestFilter.NoFilter)
+ .AssertSinglePassingTest();
+ }
- [TestCaseSource(typeof(SingleFrameworkSource), nameof(SingleFrameworkSource.AllFrameworksExceptNetFx))]
- [Platform("Win")]
- public void Single_target_vbproj_dotnet_CLI(SingleFrameworkSource source)
- {
- var workspace = CreateSingleTargetWorkspace("Test.vbproj", source);
- AddTestsVb(workspace);
- workspace.DotNetTest().AssertSinglePassingTest();
- }
+ [TestCaseSource(typeof(SingleFrameworkSource), nameof(SingleFrameworkSource.AllFrameworksExceptNetFx))]
+ [Platform("Win")]
+ public void Single_target_vbproj_dotnet_CLI(SingleFrameworkSource source)
+ {
+ var workspace = CreateSingleTargetWorkspace("Test.vbproj", source);
+ AddTestsVb(workspace);
+ workspace.DotNetTest().AssertSinglePassingTest();
+ }
- private IsolatedWorkspace CreateMultiTargetWorkspace(string fileName, MultiFrameworkSource source) =>
- CreateWorkspace()
- .AddProject(fileName, $@"
+ private IsolatedWorkspace CreateMultiTargetWorkspace(string fileName, MultiFrameworkSource source) =>
+ CreateWorkspace()
+ .AddProject(fileName, $@"
@@ -115,58 +115,58 @@ private IsolatedWorkspace CreateMultiTargetWorkspace(string fileName, MultiFrame
");
- [TestCaseSource(typeof(MultiFrameworkSource), nameof(MultiFrameworkSource.AllFrameworks))]
- [Platform("Win")]
- public void Multi_target_csproj(MultiFrameworkSource source)
- {
- var workspace = CreateMultiTargetWorkspace("Test.csproj", source);
- AddTestsCs(workspace);
- workspace.MsBuild(restore: true);
-
- foreach (var targetFramework in source.Frameworks)
- {
- workspace.VSTest($@"bin\Debug\{targetFramework}\Test.dll", VsTestFilter.NoFilter)
- .AssertSinglePassingTest();
- }
- }
+ [TestCaseSource(typeof(MultiFrameworkSource), nameof(MultiFrameworkSource.AllFrameworks))]
+ [Platform("Win")]
+ public void Multi_target_csproj(MultiFrameworkSource source)
+ {
+ var workspace = CreateMultiTargetWorkspace("Test.csproj", source);
+ AddTestsCs(workspace);
+ workspace.MsBuild(restore: true);
- [TestCaseSource(typeof(MultiFrameworkSource), nameof(MultiFrameworkSource.AllFrameworks))]
- public void Multi_target_csproj_dotnet_CLI(MultiFrameworkSource source)
+ foreach (var targetFramework in source.Frameworks)
{
- var workspace = CreateMultiTargetWorkspace("Test.csproj", source);
- AddTestsCs(workspace);
- workspace.DotNetTest().AssertSinglePassingTest();
+ workspace.VSTest($@"bin\Debug\{targetFramework}\Test.dll", VsTestFilter.NoFilter)
+ .AssertSinglePassingTest();
}
+ }
- [TestCaseSource(typeof(MultiFrameworkSource), nameof(MultiFrameworkSource.AllFrameworks))]
- [Platform("Win")]
- public void Multi_target_vbproj(MultiFrameworkSource source)
- {
- var workspace = CreateMultiTargetWorkspace("Test.vbproj", source);
- AddTestsVb(workspace);
- workspace.MsBuild(restore: true);
-
- foreach (var targetFramework in source.Frameworks)
- {
- workspace.VSTest($@"bin\Debug\{targetFramework}\Test.dll", VsTestFilter.NoFilter)
- .AssertSinglePassingTest();
- }
- }
+ [TestCaseSource(typeof(MultiFrameworkSource), nameof(MultiFrameworkSource.AllFrameworks))]
+ public void Multi_target_csproj_dotnet_CLI(MultiFrameworkSource source)
+ {
+ var workspace = CreateMultiTargetWorkspace("Test.csproj", source);
+ AddTestsCs(workspace);
+ workspace.DotNetTest().AssertSinglePassingTest();
+ }
+
+ [TestCaseSource(typeof(MultiFrameworkSource), nameof(MultiFrameworkSource.AllFrameworks))]
+ [Platform("Win")]
+ public void Multi_target_vbproj(MultiFrameworkSource source)
+ {
+ var workspace = CreateMultiTargetWorkspace("Test.vbproj", source);
+ AddTestsVb(workspace);
+ workspace.MsBuild(restore: true);
- [TestCaseSource(typeof(MultiFrameworkSource), nameof(MultiFrameworkSource.AllFrameworks))]
- public void Multi_target_vbproj_dotnet_CLI(MultiFrameworkSource source)
+ foreach (var targetFramework in source.Frameworks)
{
- var workspace = CreateMultiTargetWorkspace("Test.vbproj", source);
- AddTestsVb(workspace);
- workspace.DotNetTest().AssertSinglePassingTest();
+ workspace.VSTest($@"bin\Debug\{targetFramework}\Test.dll", VsTestFilter.NoFilter)
+ .AssertSinglePassingTest();
}
+ }
- [Test, Platform("Win")]
- public void Legacy_csproj_with_PackageReference()
- {
- var workspace = CreateWorkspace();
- var nuvers = NuGetPackageVersion;
- workspace.AddProject("Test.csproj", $@"
+ [TestCaseSource(typeof(MultiFrameworkSource), nameof(MultiFrameworkSource.AllFrameworks))]
+ public void Multi_target_vbproj_dotnet_CLI(MultiFrameworkSource source)
+ {
+ var workspace = CreateMultiTargetWorkspace("Test.vbproj", source);
+ AddTestsVb(workspace);
+ workspace.DotNetTest().AssertSinglePassingTest();
+ }
+
+ [Test, Platform("Win")]
+ public void Legacy_csproj_with_PackageReference()
+ {
+ var workspace = CreateWorkspace();
+ var nuvers = NuGetPackageVersion;
+ workspace.AddProject("Test.csproj", $@"
@@ -224,19 +224,19 @@ public void Legacy_csproj_with_PackageReference()
");
- AddTestsCs(workspace);
+ AddTestsCs(workspace);
- workspace.MsBuild(restore: true);
+ workspace.MsBuild(restore: true);
- var result = workspace.VSTest(@"bin\Debug\Test.dll", VsTestFilter.NoFilter);
- result.AssertSinglePassingTest();
- }
+ var result = workspace.VSTest(@"bin\Debug\Test.dll", VsTestFilter.NoFilter);
+ result.AssertSinglePassingTest();
+ }
- [Test, Platform("Win")]
- public void Legacy_vbproj_with_PackageReference()
- {
- var workspace = CreateWorkspace()
- .AddProject("Test.vbproj", $@"
+ [Test, Platform("Win")]
+ public void Legacy_vbproj_with_PackageReference()
+ {
+ var workspace = CreateWorkspace()
+ .AddProject("Test.vbproj", $@"
@@ -317,17 +317,17 @@ public void Legacy_vbproj_with_PackageReference()
");
- AddTestsVb(workspace);
+ AddTestsVb(workspace);
- workspace.MsBuild(restore: true);
+ workspace.MsBuild(restore: true);
- workspace.VSTest(@"bin\Debug\Test.dll", VsTestFilter.NoFilter)
- .AssertSinglePassingTest();
- }
+ workspace.VSTest(@"bin\Debug\Test.dll", VsTestFilter.NoFilter)
+ .AssertSinglePassingTest();
+ }
- private static void AddPackagesConfig(IsolatedWorkspace workspace)
- {
- workspace.AddFile("packages.config", $@"
+ private static void AddPackagesConfig(IsolatedWorkspace workspace)
+ {
+ workspace.AddFile("packages.config", $@"
@@ -335,13 +335,13 @@ private static void AddPackagesConfig(IsolatedWorkspace workspace)
");
- }
+ }
- [Test, Platform("Win")]
- public void Legacy_csproj_with_packages_config()
- {
- var workspace = CreateWorkspace()
- .AddProject("Test.csproj", $@"
+ [Test, Platform("Win")]
+ public void Legacy_csproj_with_packages_config()
+ {
+ var workspace = CreateWorkspace()
+ .AddProject("Test.csproj", $@"
@@ -416,22 +416,22 @@ public void Legacy_csproj_with_packages_config()
");
- AddPackagesConfig(workspace);
- AddTestsCs(workspace);
+ AddPackagesConfig(workspace);
+ AddTestsCs(workspace);
- workspace.NuGetRestore(packagesDirectory: "packages");
+ workspace.NuGetRestore(packagesDirectory: "packages");
- workspace.MsBuild();
+ workspace.MsBuild();
- workspace.VSTest(@"bin\Debug\Test.dll", VsTestFilter.NoFilter)
- .AssertSinglePassingTest();
- }
+ workspace.VSTest(@"bin\Debug\Test.dll", VsTestFilter.NoFilter)
+ .AssertSinglePassingTest();
+ }
- [Test, Platform("Win")]
- public void Legacy_vbproj_with_packages_config()
- {
- var workspace = CreateWorkspace()
- .AddProject("Test.vbproj", $@"
+ [Test, Platform("Win")]
+ public void Legacy_vbproj_with_packages_config()
+ {
+ var workspace = CreateWorkspace()
+ .AddProject("Test.vbproj", $@"
@@ -529,13 +529,12 @@ public void Legacy_vbproj_with_packages_config()
");
- AddPackagesConfig(workspace);
- AddTestsVb(workspace);
+ AddPackagesConfig(workspace);
+ AddTestsVb(workspace);
- workspace.NuGetRestore(packagesDirectory: "packages");
- workspace.MsBuild();
- workspace.VSTest(@"bin\Debug\Test.dll", VsTestFilter.NoFilter)
- .AssertSinglePassingTest();
- }
+ workspace.NuGetRestore(packagesDirectory: "packages");
+ workspace.MsBuild();
+ workspace.VSTest(@"bin\Debug\Test.dll", VsTestFilter.NoFilter)
+ .AssertSinglePassingTest();
}
-}
+}
\ No newline at end of file
diff --git a/src/NUnit.TestAdapter.Tests.Acceptance/TestSourceWithCustomNames.cs b/src/NUnit.TestAdapter.Tests.Acceptance/TestSourceWithCustomNames.cs
index 23350df8..6caf161a 100644
--- a/src/NUnit.TestAdapter.Tests.Acceptance/TestSourceWithCustomNames.cs
+++ b/src/NUnit.TestAdapter.Tests.Acceptance/TestSourceWithCustomNames.cs
@@ -1,13 +1,13 @@
using NUnit.Framework;
using NUnit.VisualStudio.TestAdapter.Tests.Acceptance.WorkspaceTools;
-namespace NUnit.VisualStudio.TestAdapter.Tests.Acceptance
+namespace NUnit.VisualStudio.TestAdapter.Tests.Acceptance;
+
+public sealed class TestSourceWithCustomNames : AcceptanceTests
{
- public sealed class TestSourceWithCustomNames : AcceptanceTests
+ private static void AddTestsCs(IsolatedWorkspace workspace)
{
- private static void AddTestsCs(IsolatedWorkspace workspace)
- {
- workspace.AddFile("Tests.cs", @"
+ workspace.AddFile("Tests.cs", @"
using System;
using System.Collections;
using System.Collections.Generic;
@@ -79,19 +79,19 @@ public class Case
}
}");
- }
+ }
- [Test, Platform("Win")]
- [TestCaseSource(typeof(SingleFrameworkSource), nameof(SingleFrameworkSource.AllFrameworks))]
- public static void Single_target_csproj(SingleFrameworkSource source)
- {
- var valuetupleItemgroup = source.Framework is "netcoreapp3.1" or "net5.0" ? @"
+ [Test, Platform("Win")]
+ [TestCaseSource(typeof(SingleFrameworkSource), nameof(SingleFrameworkSource.AllFrameworks))]
+ public static void Single_target_csproj(SingleFrameworkSource source)
+ {
+ var valuetupleItemgroup = source.Framework is "netcoreapp3.1" or "net5.0" ? @"
" : "";
- TestContext.WriteLine($"Testing {source.Framework}");
- var workspace = CreateWorkspace()
- .AddProject("Test.csproj", $@"
+ TestContext.WriteLine($"Testing {source.Framework}");
+ var workspace = CreateWorkspace()
+ .AddProject("Test.csproj", $@"
@@ -109,27 +109,26 @@ public static void Single_target_csproj(SingleFrameworkSource source)
");
- AddTestsCs(workspace);
+ AddTestsCs(workspace);
- workspace.MsBuild(restore: true);
+ workspace.MsBuild(restore: true);
- var results = workspace.VSTest($@"bin\Debug\{source.Framework}\Test.dll", VsTestFilter.NoFilter);
+ var results = workspace.VSTest($@"bin\Debug\{source.Framework}\Test.dll", VsTestFilter.NoFilter);
- // Total Tests =
- // 3 from PassingTestStr/TestCaseSourceMethod
- // 1 from UnitTest_TestCaseWithTuple_TestIsNotExecuted
- // 1 from TestA/SourceA
- // 1 from TestB/SourceB
- // 1 from TestC/SourceC
- // 2 from EqualsTest/EqualsData
- //-------------------
- // 9 Total Tests
+ // Total Tests =
+ // 3 from PassingTestStr/TestCaseSourceMethod
+ // 1 from UnitTest_TestCaseWithTuple_TestIsNotExecuted
+ // 1 from TestA/SourceA
+ // 1 from TestB/SourceB
+ // 1 from TestC/SourceC
+ // 2 from EqualsTest/EqualsData
+ //-------------------
+ // 9 Total Tests
- Assert.That(results.Counters.Total, Is.EqualTo(9), "Total tests counter did not match expectation");
- Assert.That(results.Counters.Executed, Is.EqualTo(9), "Executed tests counter did not match expectation");
- Assert.That(results.Counters.Passed, Is.EqualTo(9), "Passed tests counter did not match expectation");
- }
+ Assert.That(results.Counters.Total, Is.EqualTo(9), "Total tests counter did not match expectation");
+ Assert.That(results.Counters.Executed, Is.EqualTo(9), "Executed tests counter did not match expectation");
+ Assert.That(results.Counters.Passed, Is.EqualTo(9), "Passed tests counter did not match expectation");
}
-}
+}
\ No newline at end of file
diff --git a/src/NUnit.TestAdapter.Tests.Acceptance/Utils.cs b/src/NUnit.TestAdapter.Tests.Acceptance/Utils.cs
index c14b7535..ab9e1dc0 100644
--- a/src/NUnit.TestAdapter.Tests.Acceptance/Utils.cs
+++ b/src/NUnit.TestAdapter.Tests.Acceptance/Utils.cs
@@ -4,222 +4,221 @@
using System.Text;
using NUnit.Framework;
-namespace NUnit.VisualStudio.TestAdapter.Tests.Acceptance
+namespace NUnit.VisualStudio.TestAdapter.Tests.Acceptance;
+
+internal static class Utils
{
- internal static class Utils
+ private static readonly char[] InvalidFileNameChars = Path.GetInvalidFileNameChars()
+ .Concat(new[] { '"' }) // VSTest strips quotes from the test assembly path and fails to locate the .deps.json in the same directory
+ .Distinct().ToArray();
+
+ public static string GetSafeFilename(string arbitraryString, bool allowDirectorySeparators = false)
{
- private static readonly char[] InvalidFileNameChars = Path.GetInvalidFileNameChars()
- .Concat(new[] { '"' }) // VSTest strips quotes from the test assembly path and fails to locate the .deps.json in the same directory
- .Distinct().ToArray();
+ var replaceIndex = arbitraryString.IndexOfAny(InvalidFileNameChars, 0);
+ if (replaceIndex == -1) return arbitraryString;
- public static string GetSafeFilename(string arbitraryString, bool allowDirectorySeparators = false)
- {
- var replaceIndex = arbitraryString.IndexOfAny(InvalidFileNameChars, 0);
- if (replaceIndex == -1) return arbitraryString;
+ var r = new StringBuilder();
+ var i = 0;
- var r = new StringBuilder();
- var i = 0;
+ do
+ {
+ r.Append(arbitraryString, i, replaceIndex - i);
- do
+ switch (arbitraryString[replaceIndex])
{
- r.Append(arbitraryString, i, replaceIndex - i);
+ case '<':
+ case '>':
+ case '|':
+ case ':':
+ case '*':
+ case '\\':
+ case '/':
+ r.Append(allowDirectorySeparators ? Path.DirectorySeparatorChar : '-');
+ break;
+ case '\0':
+ case '\f':
+ case '?':
+ case '"':
+ break;
+ case '\t':
+ case '\n':
+ case '\r':
+ case '\v':
+ r.Append(' ');
+ break;
+ default:
+ r.Append('_');
+ break;
+ }
- switch (arbitraryString[replaceIndex])
- {
- case '<':
- case '>':
- case '|':
- case ':':
- case '*':
- case '\\':
- case '/':
- r.Append(allowDirectorySeparators ? Path.DirectorySeparatorChar : '-');
- break;
- case '\0':
- case '\f':
- case '?':
- case '"':
- break;
- case '\t':
- case '\n':
- case '\r':
- case '\v':
- r.Append(' ');
- break;
- default:
- r.Append('_');
- break;
- }
+ i = replaceIndex + 1;
+ replaceIndex = arbitraryString.IndexOfAny(InvalidFileNameChars, i);
+ }
+ while (replaceIndex != -1);
- i = replaceIndex + 1;
- replaceIndex = arbitraryString.IndexOfAny(InvalidFileNameChars, i);
- }
- while (replaceIndex != -1);
+ r.Append(arbitraryString, i, arbitraryString.Length - i);
- r.Append(arbitraryString, i, arbitraryString.Length - i);
+ return r.ToString();
+ }
- return r.ToString();
- }
+ public static DirectoryMutex CreateMutexDirectory(string parentDirectory, string name = null)
+ {
+ parentDirectory = Path.GetFullPath(parentDirectory);
- public static DirectoryMutex CreateMutexDirectory(string parentDirectory, string name = null)
- {
- parentDirectory = Path.GetFullPath(parentDirectory);
+ var safeName = name is null ? null : GetSafeFilename(name);
- var safeName = name is null ? null : GetSafeFilename(name);
+ for (var id = 1; ; id++)
+ {
+ var path = Path.Combine(
+ parentDirectory,
+ safeName is null ? id.ToString() :
+ id == 1 ? safeName :
+ safeName + "_" + id);
- for (var id = 1; ; id++)
+ if (!Directory.Exists(path))
{
- var path = Path.Combine(
- parentDirectory,
- safeName is null ? id.ToString() :
- id == 1 ? safeName :
- safeName + "_" + id);
-
- if (!Directory.Exists(path))
+ Directory.CreateDirectory(path);
+ if (DirectoryMutex.TryAcquire(path) is { } mutex)
{
- Directory.CreateDirectory(path);
- if (DirectoryMutex.TryAcquire(path) is { } mutex)
- {
- // Make sure that the directory is still empty (besides the mutex file) at this point so that a
- // non-empty directory is not used.
- if (Directory.GetFileSystemEntries(path).Length == 1)
- return mutex;
- }
+ // Make sure that the directory is still empty (besides the mutex file) at this point so that a
+ // non-empty directory is not used.
+ if (Directory.GetFileSystemEntries(path).Length == 1)
+ return mutex;
}
}
}
+ }
- public static void DeleteDirectoryRobust(string directory)
+ public static void DeleteDirectoryRobust(string directory)
+ {
+ for (var attempt = 1; ; attempt++)
{
- for (var attempt = 1; ; attempt++)
+ try
{
- try
- {
- Directory.Delete(directory, recursive: true);
- break;
- }
- catch (DirectoryNotFoundException)
- {
- break;
- }
- catch (IOException ex) when (attempt < 3 && (WinErrorCode)ex.HResult == WinErrorCode.DirNotEmpty)
- {
- TestContext.WriteLine("Another process added files to the directory while its contents were being deleted. Retrying...");
- }
+ Directory.Delete(directory, recursive: true);
+ break;
+ }
+ catch (DirectoryNotFoundException)
+ {
+ break;
+ }
+ catch (IOException ex) when (attempt < 3 && (WinErrorCode)ex.HResult == WinErrorCode.DirNotEmpty)
+ {
+ TestContext.WriteLine("Another process added files to the directory while its contents were being deleted. Retrying...");
}
}
+ }
- private enum WinErrorCode : ushort
- {
- DirNotEmpty = 145
- }
+ private enum WinErrorCode : ushort
+ {
+ DirNotEmpty = 145
+ }
- ///
- /// Removes any indentation that is common to all lines. If the first line has no indentation,
- /// indentation common to all other lines is removed. If the first line is empty, it is removed.
- /// Empty lines are not considered when calculating indentation.
- ///
- public static string RemoveIndent(string indented)
- {
- if (indented is null) return null;
+ ///
+ /// Removes any indentation that is common to all lines. If the first line has no indentation,
+ /// indentation common to all other lines is removed. If the first line is empty, it is removed.
+ /// Empty lines are not considered when calculating indentation.
+ ///
+ public static string RemoveIndent(string indented)
+ {
+ if (indented is null) return null;
- var reader = new StringReader(indented);
- var firstLine = reader.ReadLine();
+ var reader = new StringReader(indented);
+ var firstLine = reader.ReadLine();
- var firstLineStartsWithoutIndent = firstLine.Length != 0 && firstLine[0] != ' ';
+ var firstLineStartsWithoutIndent = firstLine.Length != 0 && firstLine[0] != ' ';
- var readerForCountingPass = new StringReader(indented);
+ var readerForCountingPass = new StringReader(indented);
- // Skip the first line when determining common indentation if it has no indentation
- if (firstLineStartsWithoutIndent)
- _ = readerForCountingPass.ReadLine();
+ // Skip the first line when determining common indentation if it has no indentation
+ if (firstLineStartsWithoutIndent)
+ _ = readerForCountingPass.ReadLine();
- var indentationCharCount = CountCommonIndentationChars(readerForCountingPass);
+ var indentationCharCount = CountCommonIndentationChars(readerForCountingPass);
- var builder = new StringBuilder();
+ var builder = new StringBuilder();
- var previousLineHasEnded = true;
+ var previousLineHasEnded = true;
- if (firstLine.Length != 0)
+ if (firstLine.Length != 0)
+ {
+ if (firstLineStartsWithoutIndent)
{
- if (firstLineStartsWithoutIndent)
- {
- builder.Append(firstLine);
- previousLineHasEnded = false;
- }
- else
- {
- // Start at beginning
- reader = new StringReader(indented);
- }
+ builder.Append(firstLine);
+ previousLineHasEnded = false;
+ }
+ else
+ {
+ // Start at beginning
+ reader = new StringReader(indented);
}
+ }
- var remainingIndentationChars = indentationCharCount;
+ var remainingIndentationChars = indentationCharCount;
- while (reader.Read() is var next && next != -1)
+ while (reader.Read() is var next && next != -1)
+ {
+ if (next == ' ' && remainingIndentationChars > 0)
{
- if (next == ' ' && remainingIndentationChars > 0)
- {
- remainingIndentationChars--;
- continue;
- }
+ remainingIndentationChars--;
+ continue;
+ }
- if (!previousLineHasEnded) builder.AppendLine();
+ if (!previousLineHasEnded) builder.AppendLine();
- if (next == '\r')
- {
- next = reader.Read();
- if (next != '\n') throw new NotImplementedException("Carriage return without line feed");
- }
-
- if (next != '\n')
- {
- builder.Append((char)next).Append(reader.ReadLine());
- }
+ if (next == '\r')
+ {
+ next = reader.Read();
+ if (next != '\n') throw new NotImplementedException("Carriage return without line feed");
+ }
- previousLineHasEnded = false;
- remainingIndentationChars = indentationCharCount;
+ if (next != '\n')
+ {
+ builder.Append((char)next).Append(reader.ReadLine());
}
- return builder.ToString();
+ previousLineHasEnded = false;
+ remainingIndentationChars = indentationCharCount;
}
- private static int CountCommonIndentationChars(StringReader reader)
- {
- var maxCount = 0;
- var currentLineCount = 0;
+ return builder.ToString();
+ }
+
+ private static int CountCommonIndentationChars(StringReader reader)
+ {
+ var maxCount = 0;
+ var currentLineCount = 0;
- while (true)
+ while (true)
+ {
+ switch (reader.Read())
{
- switch (reader.Read())
- {
- case -1:
- return maxCount;
+ case -1:
+ return maxCount;
- case ' ':
- currentLineCount++;
- break;
+ case ' ':
+ currentLineCount++;
+ break;
- case '\t':
- throw new NotImplementedException("Tabs");
+ case '\t':
+ throw new NotImplementedException("Tabs");
- case '\r':
- case '\n':
- currentLineCount = 0;
- break;
+ case '\r':
+ case '\n':
+ currentLineCount = 0;
+ break;
- default:
- if (currentLineCount == 0) return 0;
+ default:
+ if (currentLineCount == 0) return 0;
- if (maxCount == 0 || maxCount > currentLineCount)
- maxCount = currentLineCount;
+ if (maxCount == 0 || maxCount > currentLineCount)
+ maxCount = currentLineCount;
- currentLineCount = 0;
+ currentLineCount = 0;
- _ = reader.ReadLine();
- break;
- }
+ _ = reader.ReadLine();
+ break;
}
}
}
-}
+}
\ No newline at end of file
diff --git a/src/NUnit.TestAdapter.Tests.Acceptance/UtilsTests.cs b/src/NUnit.TestAdapter.Tests.Acceptance/UtilsTests.cs
index 9b462b16..74c5a6f4 100644
--- a/src/NUnit.TestAdapter.Tests.Acceptance/UtilsTests.cs
+++ b/src/NUnit.TestAdapter.Tests.Acceptance/UtilsTests.cs
@@ -1,67 +1,66 @@
using System;
using NUnit.Framework;
-namespace NUnit.VisualStudio.TestAdapter.Tests.Acceptance
+namespace NUnit.VisualStudio.TestAdapter.Tests.Acceptance;
+
+public static class UtilsTests
{
- public static class UtilsTests
+ [Test]
+ public static void RemoveIndent_removes_indentation_of_line_with_least_indentation_from_all_lines()
{
- [Test]
- public static void RemoveIndent_removes_indentation_of_line_with_least_indentation_from_all_lines()
- {
- var result = Utils.RemoveIndent(string.Join(
- Environment.NewLine,
- " First line",
- " Second line",
- " "));
+ var result = Utils.RemoveIndent(string.Join(
+ Environment.NewLine,
+ " First line",
+ " Second line",
+ " "));
- Assert.That(result, Is.EqualTo(string.Join(
- Environment.NewLine,
- " First line",
- "Second line",
- " ")));
- }
+ Assert.That(result, Is.EqualTo(string.Join(
+ Environment.NewLine,
+ " First line",
+ "Second line",
+ " ")));
+ }
- [Test]
- public static void RemoveIndent_ignores_whitespace_lines()
- {
- var result = Utils.RemoveIndent(string.Join(
- Environment.NewLine,
- " First line",
- " ",
- " Second line"));
+ [Test]
+ public static void RemoveIndent_ignores_whitespace_lines()
+ {
+ var result = Utils.RemoveIndent(string.Join(
+ Environment.NewLine,
+ " First line",
+ " ",
+ " Second line"));
- Assert.That(result, Is.EqualTo(string.Join(
- Environment.NewLine,
- "First line",
- "",
- "Second line")));
- }
+ Assert.That(result, Is.EqualTo(string.Join(
+ Environment.NewLine,
+ "First line",
+ "",
+ "Second line")));
+ }
- [Test]
- public static void RemoveIndent_ignores_first_line_if_it_begins_without_indent()
- {
- var result = Utils.RemoveIndent(string.Join(
- Environment.NewLine,
- "First line",
- " Second line"));
+ [Test]
+ public static void RemoveIndent_ignores_first_line_if_it_begins_without_indent()
+ {
+ var result = Utils.RemoveIndent(string.Join(
+ Environment.NewLine,
+ "First line",
+ " Second line"));
- Assert.That(result, Is.EqualTo(string.Join(
- Environment.NewLine,
- "First line",
- "Second line")));
- }
+ Assert.That(result, Is.EqualTo(string.Join(
+ Environment.NewLine,
+ "First line",
+ "Second line")));
+ }
- [Test]
- public static void RemoveIndent_removes_first_line_if_is_empty()
- {
- var result = Utils.RemoveIndent(string.Join(
- Environment.NewLine,
- "",
- " Second line"));
+ [Test]
+ public static void RemoveIndent_removes_first_line_if_is_empty()
+ {
+ var result = Utils.RemoveIndent(string.Join(
+ Environment.NewLine,
+ "",
+ " Second line"));
- Assert.That(result, Is.EqualTo(string.Join(
- Environment.NewLine,
- "Second line")));
- }
+ Assert.That(result, Is.EqualTo(string.Join(
+ Environment.NewLine,
+ "Second line")));
}
-}
+}
\ No newline at end of file
diff --git a/src/NUnit.TestAdapter.Tests.Acceptance/WorkspaceTools/IsolatedWorkspace.RunSettings.cs b/src/NUnit.TestAdapter.Tests.Acceptance/WorkspaceTools/IsolatedWorkspace.RunSettings.cs
index a0e0eba2..e489bbb0 100644
--- a/src/NUnit.TestAdapter.Tests.Acceptance/WorkspaceTools/IsolatedWorkspace.RunSettings.cs
+++ b/src/NUnit.TestAdapter.Tests.Acceptance/WorkspaceTools/IsolatedWorkspace.RunSettings.cs
@@ -1,57 +1,56 @@
using System;
using System.Collections.Generic;
-namespace NUnit.VisualStudio.TestAdapter.Tests.Acceptance.WorkspaceTools
+namespace NUnit.VisualStudio.TestAdapter.Tests.Acceptance.WorkspaceTools;
+
+partial class IsolatedWorkspace
{
- partial class IsolatedWorkspace
+ private sealed class RunSettings
{
- private sealed class RunSettings
+ private List Arguments { get; } = [];
+
+ public string WorkingDirectory { get; }
+ public string FileName { get; }
+
+ public string ArgumentsAsEscapedString => ProcessUtils.EscapeProcessArguments(Arguments);
+
+ public RunSettings(string workingDirectory, string fileName)
+ {
+ WorkingDirectory = workingDirectory;
+ FileName = fileName;
+ }
+
+ public ProcessRunResult Run(bool throwOnError = true)
+ {
+ var result = ProcessUtils.Run(WorkingDirectory, FileName, Arguments);
+ if (throwOnError) result.ThrowIfError();
+ return result;
+ }
+
+ public RunSettings Add(string argument)
+ {
+ Arguments.Add(argument);
+ return this;
+ }
+
+ public RunSettings AddRange(IEnumerable arguments)
+ {
+ if (arguments is null) throw new ArgumentNullException(nameof(arguments));
+ Arguments.AddRange(arguments);
+ return this;
+ }
+
+ public RunSettings AddIf(bool condition, string argument)
+ {
+ if (condition) Arguments.Add(argument);
+ return this;
+ }
+
+ public RunSettings AddRangeIf(bool condition, IEnumerable arguments)
{
- private List Arguments { get; } = new();
-
- public string WorkingDirectory { get; }
- public string FileName { get; }
-
- public string ArgumentsAsEscapedString => ProcessUtils.EscapeProcessArguments(Arguments);
-
- public RunSettings(string workingDirectory, string fileName)
- {
- WorkingDirectory = workingDirectory;
- FileName = fileName;
- }
-
- public ProcessRunResult Run(bool throwOnError = true)
- {
- var result = ProcessUtils.Run(WorkingDirectory, FileName, Arguments);
- if (throwOnError) result.ThrowIfError();
- return result;
- }
-
- public RunSettings Add(string argument)
- {
- Arguments.Add(argument);
- return this;
- }
-
- public RunSettings AddRange(IEnumerable arguments)
- {
- if (arguments is null) throw new ArgumentNullException(nameof(arguments));
- Arguments.AddRange(arguments);
- return this;
- }
-
- public RunSettings AddIf(bool condition, string argument)
- {
- if (condition) Arguments.Add(argument);
- return this;
- }
-
- public RunSettings AddRangeIf(bool condition, IEnumerable arguments)
- {
- if (arguments is null) throw new ArgumentNullException(nameof(arguments));
- if (condition) Arguments.AddRange(arguments);
- return this;
- }
+ if (arguments is null) throw new ArgumentNullException(nameof(arguments));
+ if (condition) Arguments.AddRange(arguments);
+ return this;
}
}
-}
+}
\ No newline at end of file
diff --git a/src/NUnit.TestAdapter.Tests.Acceptance/WorkspaceTools/IsolatedWorkspace.cs b/src/NUnit.TestAdapter.Tests.Acceptance/WorkspaceTools/IsolatedWorkspace.cs
index 2a193897..1722dabe 100644
--- a/src/NUnit.TestAdapter.Tests.Acceptance/WorkspaceTools/IsolatedWorkspace.cs
+++ b/src/NUnit.TestAdapter.Tests.Acceptance/WorkspaceTools/IsolatedWorkspace.cs
@@ -3,154 +3,148 @@
using System.Diagnostics;
using System.IO;
-namespace NUnit.VisualStudio.TestAdapter.Tests.Acceptance.WorkspaceTools
+namespace NUnit.VisualStudio.TestAdapter.Tests.Acceptance.WorkspaceTools;
+
+[DebuggerDisplay("{Directory,nq}")]
+public sealed partial class IsolatedWorkspace(DirectoryMutex directoryMutex, ToolResolver toolResolver)
+ : IDisposable
{
- [DebuggerDisplay("{Directory,nq}")]
- public sealed partial class IsolatedWorkspace : IDisposable
+ private readonly List projectPaths = [];
+ private readonly ToolResolver toolResolver = toolResolver ?? throw new ArgumentNullException(nameof(toolResolver));
+ private readonly DirectoryMutex directoryMutex = directoryMutex ?? throw new ArgumentNullException(nameof(toolResolver));
+
+ public bool DumpTestExecution { get; set; } = false;
+
+ public string Directory => directoryMutex.DirectoryPath;
+
+ public void Dispose() => directoryMutex.Dispose();
+
+ public IsolatedWorkspace AddProject(string path, string contents)
{
- private readonly List projectPaths = new();
- private readonly ToolResolver toolResolver;
- private readonly DirectoryMutex directoryMutex;
+ AddFile(path, contents);
+ projectPaths.Add(path);
+ return this;
+ }
- public bool DumpTestExecution { get; set; } = false;
+ public IsolatedWorkspace AddFile(string path, string contents)
+ {
+ if (string.IsNullOrWhiteSpace(path))
+ throw new ArgumentException("File path must be specified.", nameof(path));
- public string Directory => directoryMutex.DirectoryPath;
+ if (Path.IsPathRooted(path))
+ throw new ArgumentException("File path must not be rooted.", nameof(path));
- public IsolatedWorkspace(DirectoryMutex directoryMutex, ToolResolver toolResolver)
- {
- this.directoryMutex = directoryMutex ?? throw new ArgumentNullException(nameof(toolResolver));
- this.toolResolver = toolResolver ?? throw new ArgumentNullException(nameof(toolResolver));
- }
+ File.WriteAllText(Path.Combine(Directory, path), Utils.RemoveIndent(contents));
+ return this;
+ }
- public void Dispose() => directoryMutex.Dispose();
+ public void DotNetRestore()
+ {
+ ConfigureRun("dotnet")
+ .Add("restore")
+ .Run();
+ }
- public IsolatedWorkspace AddProject(string path, string contents)
- {
- AddFile(path, contents);
- projectPaths.Add(path);
- return this;
- }
+ public void DotNetBuild(bool noRestore = false)
+ {
+ ConfigureRun("dotnet")
+ .Add("build")
+ .AddIf(noRestore, "--no-restore")
+ .Run();
+ }
- public IsolatedWorkspace AddFile(string path, string contents)
- {
- if (string.IsNullOrWhiteSpace(path))
- throw new ArgumentException("File path must be specified.", nameof(path));
+ ///
+ /// Runs dotnet test.
+ ///
+ /// Possible filter statement.
+ /// if you run MSBuild or dotnet build first, set to false.
+ /// Set NUnit verbosity to 5, enables seing more info from the run in StdOut.
+ /// VSTestResults.
+ public VSTestResult DotNetTest(string filterArgument = "", bool noBuild = false, bool verbose = false, Action log = null)
+ {
+ using var tempTrxFile = new TempFile();
- if (Path.IsPathRooted(path))
- throw new ArgumentException("File path must not be rooted.", nameof(path));
+ var dotnettest = ConfigureRun("dotnet")
+ .Add("test")
+ .AddIf(noBuild, "--no-build")
+ .Add("-v:n")
+ .Add("--logger").Add("trx;LogFileName=" + tempTrxFile);
- File.WriteAllText(Path.Combine(Directory, path), Utils.RemoveIndent(contents));
- return this;
- }
+ bool hasNUnitWhere = filterArgument.StartsWith("NUnit.Where");
- public void DotNetRestore()
+ if (filterArgument.Length > 0 && !hasNUnitWhere)
{
- ConfigureRun("dotnet")
- .Add("restore")
- .Run();
+ dotnettest.Add("--filter").Add($"{filterArgument}");
}
-
- public void DotNetBuild(bool noRestore = false)
+ else if (hasNUnitWhere)
{
- ConfigureRun("dotnet")
- .Add("build")
- .AddIf(noRestore, "--no-restore")
- .Run();
+ dotnettest.Add("--").Add(filterArgument);
}
-
- ///
- /// Runs dotnet test.
- ///
- /// Possible filter statement.
- /// if you run MSBuild or dotnet build first, set to false.
- /// Set NUnit verbosity to 5, enables seing more info from the run in StdOut.
- /// VSTestResults.
- public VSTestResult DotNetTest(string filterArgument = "", bool noBuild = false, bool verbose = false, Action log = null)
+ if (verbose)
{
- using var tempTrxFile = new TempFile();
-
- var dotnettest = ConfigureRun("dotnet")
- .Add("test")
- .AddIf(noBuild, "--no-build")
- .Add("-v:n")
- .Add("--logger").Add("trx;LogFileName=" + tempTrxFile);
-
- bool hasNUnitWhere = filterArgument.StartsWith("NUnit.Where");
-
- if (filterArgument.Length > 0 && !hasNUnitWhere)
- {
- dotnettest.Add("--filter").Add($"{filterArgument}");
- }
- else if (hasNUnitWhere)
- {
- dotnettest.Add("--").Add(filterArgument);
- }
- if (verbose)
- {
- if (!hasNUnitWhere)
- dotnettest.Add("--");
- dotnettest.Add("NUnit.Verbosity=5");
- }
- log?.Invoke($"\n{dotnettest.ArgumentsAsEscapedString}");
- var result = dotnettest.Run(throwOnError: false);
-
- if (new FileInfo(tempTrxFile).Length == 0)
- result.ThrowIfError();
-
- return VSTestResult.Load(result, tempTrxFile);
+ if (!hasNUnitWhere)
+ dotnettest.Add("--");
+ dotnettest.Add("NUnit.Verbosity=5");
}
+ log?.Invoke($"\n{dotnettest.ArgumentsAsEscapedString}");
+ var result = dotnettest.Run(throwOnError: false);
- public void DotNetVSTest(IEnumerable testAssemblyPaths)
- {
- ConfigureRun("dotnet")
- .Add("vstest")
- .AddRange(testAssemblyPaths)
- .Run();
- }
+ if (new FileInfo(tempTrxFile).Length == 0)
+ result.ThrowIfError();
- public void NuGetRestore(string packagesDirectory = null)
- {
- ConfigureRun(toolResolver.NuGet)
- .Add("restore")
- .AddRangeIf(packagesDirectory != null, new[] { "-PackagesDirectory", packagesDirectory })
- .Run();
- }
+ return VSTestResult.Load(result, tempTrxFile);
+ }
- public void MsBuild(string target = null, bool restore = false)
- {
- ConfigureRun(toolResolver.MSBuild)
- .AddIf(target != null, "/t:" + target)
- .AddIf(restore, "/restore")
- .Run();
- }
+ public void DotNetVSTest(IEnumerable testAssemblyPaths)
+ {
+ ConfigureRun("dotnet")
+ .Add("vstest")
+ .AddRange(testAssemblyPaths)
+ .Run();
+ }
- public VSTestResult VSTest(string testAssemblyPath, IFilterArgument filter)
- {
- using var tempTrxFile = new TempFile();
+ public void NuGetRestore(string packagesDirectory = null)
+ {
+ ConfigureRun(toolResolver.NuGet)
+ .Add("restore")
+ .AddRangeIf(packagesDirectory != null, new[] { "-PackagesDirectory", packagesDirectory })
+ .Run();
+ }
+
+ public void MsBuild(string target = null, bool restore = false)
+ {
+ ConfigureRun(toolResolver.MSBuild)
+ .AddIf(target != null, "/t:" + target)
+ .AddIf(restore, "/restore")
+ .Run();
+ }
- var vstest = ConfigureRun(toolResolver.VSTest)
- .Add(testAssemblyPath)
- .Add("/logger:trx;LogFileName=" + tempTrxFile);
+ public VSTestResult VSTest(string testAssemblyPath, IFilterArgument filter)
+ {
+ using var tempTrxFile = new TempFile();
- if (filter.HasArguments)
- {
- vstest.Add(filter.CompletedArgument());
- }
+ var vstest = ConfigureRun(toolResolver.VSTest)
+ .Add(testAssemblyPath)
+ .Add("/logger:trx;LogFileName=" + tempTrxFile);
- if (DumpTestExecution)
- vstest.Add("--").Add("NUnit.DumpXmlTestResults=true");
+ if (filter.HasArguments)
+ {
+ vstest.Add(filter.CompletedArgument());
+ }
- var result = vstest.Run(throwOnError: false);
+ if (DumpTestExecution)
+ vstest.Add("--").Add("NUnit.DumpXmlTestResults=true");
- if (new FileInfo(tempTrxFile).Length == 0)
- {
- result.ThrowIfError();
- return new VSTestResult(result);
- }
+ var result = vstest.Run(throwOnError: false);
- return VSTestResult.Load(result, tempTrxFile);
+ if (new FileInfo(tempTrxFile).Length == 0)
+ {
+ result.ThrowIfError();
+ return new VSTestResult(result);
}
- private RunSettings ConfigureRun(string filename) => new(Directory, filename);
+ return VSTestResult.Load(result, tempTrxFile);
}
-}
+
+ private RunSettings ConfigureRun(string filename) => new(Directory, filename);
+}
\ No newline at end of file
diff --git a/src/NUnit.TestAdapter.Tests.Acceptance/WorkspaceTools/IsolatedWorkspaceManager.cs b/src/NUnit.TestAdapter.Tests.Acceptance/WorkspaceTools/IsolatedWorkspaceManager.cs
index d46fae6a..7c2263f5 100644
--- a/src/NUnit.TestAdapter.Tests.Acceptance/WorkspaceTools/IsolatedWorkspaceManager.cs
+++ b/src/NUnit.TestAdapter.Tests.Acceptance/WorkspaceTools/IsolatedWorkspaceManager.cs
@@ -2,101 +2,100 @@
using System.IO;
using System.Xml;
-namespace NUnit.VisualStudio.TestAdapter.Tests.Acceptance.WorkspaceTools
+namespace NUnit.VisualStudio.TestAdapter.Tests.Acceptance.WorkspaceTools;
+
+public sealed class IsolatedWorkspaceManager : IDisposable
{
- public sealed class IsolatedWorkspaceManager : IDisposable
+ private readonly DirectoryMutex workspaceDirectory;
+ private readonly ToolResolver toolResolver;
+ private readonly StreamWriter reasonFile;
+ private bool keep;
+
+ public IsolatedWorkspaceManager(string reason, string baseDirectory, string testNupkgDirectory, string packageCachePath, string downloadCachePath)
{
- private readonly DirectoryMutex workspaceDirectory;
- private readonly ToolResolver toolResolver;
- private readonly StreamWriter reasonFile;
- private bool keep;
+ baseDirectory = Path.GetFullPath(baseDirectory);
+ testNupkgDirectory = Path.GetFullPath(testNupkgDirectory);
+ packageCachePath = Path.GetFullPath(packageCachePath);
+ downloadCachePath = Path.GetFullPath(downloadCachePath);
- public IsolatedWorkspaceManager(string reason, string baseDirectory, string testNupkgDirectory, string packageCachePath, string downloadCachePath)
- {
- baseDirectory = Path.GetFullPath(baseDirectory);
- testNupkgDirectory = Path.GetFullPath(testNupkgDirectory);
- packageCachePath = Path.GetFullPath(packageCachePath);
- downloadCachePath = Path.GetFullPath(downloadCachePath);
+ Directory.CreateDirectory(baseDirectory);
- Directory.CreateDirectory(baseDirectory);
+ workspaceDirectory = Utils.CreateMutexDirectory(baseDirectory);
- workspaceDirectory = Utils.CreateMutexDirectory(baseDirectory);
+ toolResolver = new ToolResolver(downloadCachePath);
- toolResolver = new ToolResolver(downloadCachePath);
+ reasonFile = File.CreateText(Path.Combine(workspaceDirectory.DirectoryPath, "Reason.txt"));
+ reasonFile.WriteLine(reason);
+ reasonFile.WriteLine();
+ reasonFile.Flush();
- reasonFile = File.CreateText(Path.Combine(workspaceDirectory.DirectoryPath, "Reason.txt"));
- reasonFile.WriteLine(reason);
- reasonFile.WriteLine();
- reasonFile.Flush();
+ WriteNuGetConfig(baseDirectory, testNupkgDirectory, packageCachePath);
- WriteNuGetConfig(baseDirectory, testNupkgDirectory, packageCachePath);
+ File.WriteAllText(Path.Combine(baseDirectory, "Directory.Build.props"), "");
+ File.WriteAllText(Path.Combine(baseDirectory, "Directory.Build.targets"), "");
+ }
- File.WriteAllText(Path.Combine(baseDirectory, "Directory.Build.props"), "");
- File.WriteAllText(Path.Combine(baseDirectory, "Directory.Build.targets"), "");
- }
+ public void Dispose()
+ {
+ workspaceDirectory.Dispose();
+ reasonFile.Dispose();
+ if (!keep) Utils.DeleteDirectoryRobust(workspaceDirectory.DirectoryPath);
+ }
- public void Dispose()
- {
- workspaceDirectory.Dispose();
- reasonFile.Dispose();
- if (!keep) Utils.DeleteDirectoryRobust(workspaceDirectory.DirectoryPath);
- }
+ public IsolatedWorkspace CreateWorkspace(string name)
+ {
+ return new (
+ Utils.CreateMutexDirectory(workspaceDirectory.DirectoryPath, name),
+ toolResolver);
+ }
- public IsolatedWorkspace CreateWorkspace(string name)
+ ///
+ /// Prevents the workspace directory from being deleted when is called.
+ ///
+ public void PreserveDirectory(string reason)
+ {
+ if (!keep)
{
- return new (
- Utils.CreateMutexDirectory(workspaceDirectory.DirectoryPath, name),
- toolResolver);
+ keep = true;
+ reasonFile.WriteLine("Preserving workspace after cleanup, due to:");
+ reasonFile.WriteLine();
}
- ///
- /// Prevents the workspace directory from being deleted when is called.
- ///
- public void PreserveDirectory(string reason)
- {
- if (!keep)
- {
- keep = true;
- reasonFile.WriteLine("Preserving workspace after cleanup, due to:");
- reasonFile.WriteLine();
- }
-
- reasonFile.WriteLine(reason);
- reasonFile.Flush();
- }
+ reasonFile.WriteLine(reason);
+ reasonFile.Flush();
+ }
- private static void WriteNuGetConfig(string directory, string testNupkgDirectory, string packageCachePath)
- {
- using var file = File.CreateText(Path.Combine(directory, "nuget.config"));
- using var writer = XmlWriter.Create(file, new XmlWriterSettings { Indent = true });
- writer.WriteComment(string.Join(
- Environment.NewLine,
- "",
- "This file exists so that if any of the projects under this folder are opened by an IDE or restored from the CLI by acceptance tests or by hand,",
- " 1. the .nupkg that is being tested can be referenced by these projects, and",
- " 2. the .nupkg that is tested does not pollute the global cache in %userprofile%\\.nuget.",
- ""));
-
- writer.WriteStartElement("configuration");
- writer.WriteStartElement("config");
-
- writer.WriteComment(" Implements the second point ");
- writer.WriteStartElement("add");
- writer.WriteAttributeString("key", "globalPackagesFolder");
- writer.WriteAttributeString("value", packageCachePath);
- writer.WriteEndElement();
-
- writer.WriteEndElement();
- writer.WriteStartElement("packageSources");
-
- writer.WriteComment(" Implements the first point ");
- writer.WriteStartElement("add");
- writer.WriteAttributeString("key", "Build script package output");
- writer.WriteAttributeString("value", testNupkgDirectory);
- writer.WriteEndElement();
-
- writer.WriteEndElement();
- writer.WriteEndElement();
- }
+ private static void WriteNuGetConfig(string directory, string testNupkgDirectory, string packageCachePath)
+ {
+ using var file = File.CreateText(Path.Combine(directory, "nuget.config"));
+ using var writer = XmlWriter.Create(file, new XmlWriterSettings { Indent = true });
+ writer.WriteComment(string.Join(
+ Environment.NewLine,
+ "",
+ "This file exists so that if any of the projects under this folder are opened by an IDE or restored from the CLI by acceptance tests or by hand,",
+ " 1. the .nupkg that is being tested can be referenced by these projects, and",
+ " 2. the .nupkg that is tested does not pollute the global cache in %userprofile%\\.nuget.",
+ ""));
+
+ writer.WriteStartElement("configuration");
+ writer.WriteStartElement("config");
+
+ writer.WriteComment(" Implements the second point ");
+ writer.WriteStartElement("add");
+ writer.WriteAttributeString("key", "globalPackagesFolder");
+ writer.WriteAttributeString("value", packageCachePath);
+ writer.WriteEndElement();
+
+ writer.WriteEndElement();
+ writer.WriteStartElement("packageSources");
+
+ writer.WriteComment(" Implements the first point ");
+ writer.WriteStartElement("add");
+ writer.WriteAttributeString("key", "Build script package output");
+ writer.WriteAttributeString("value", testNupkgDirectory);
+ writer.WriteEndElement();
+
+ writer.WriteEndElement();
+ writer.WriteEndElement();
}
-}
+}
\ No newline at end of file
diff --git a/src/NUnit.TestAdapter.Tests.Acceptance/WorkspaceTools/ProcessErrorException.cs b/src/NUnit.TestAdapter.Tests.Acceptance/WorkspaceTools/ProcessErrorException.cs
index 470433e1..350ed11d 100644
--- a/src/NUnit.TestAdapter.Tests.Acceptance/WorkspaceTools/ProcessErrorException.cs
+++ b/src/NUnit.TestAdapter.Tests.Acceptance/WorkspaceTools/ProcessErrorException.cs
@@ -1,39 +1,38 @@
using System;
using System.Text;
-namespace NUnit.VisualStudio.TestAdapter.Tests.Acceptance.WorkspaceTools
+namespace NUnit.VisualStudio.TestAdapter.Tests.Acceptance.WorkspaceTools;
+
+public sealed class ProcessErrorException : Exception
{
- public sealed class ProcessErrorException : Exception
+ public ProcessErrorException(ProcessRunResult result)
+ : base(BuildMessage(result))
{
- public ProcessErrorException(ProcessRunResult result)
- : base(BuildMessage(result))
- {
- Result = result;
- }
-
- public ProcessRunResult Result { get; }
+ Result = result;
+ }
- private static string BuildMessage(ProcessRunResult result)
- {
- var builder = new StringBuilder();
- builder.Append("Process ‘").Append(result.ProcessName);
- builder.Append("’ exited with code ").Append(result.ExitCode).Append('.');
- builder.AppendLine().Append("Executable: ").Append(result.FileName);
+ public ProcessRunResult Result { get; }
- if (!string.IsNullOrWhiteSpace(result.Arguments))
- {
- builder.AppendLine().Append("Arguments: ").Append(result.Arguments);
- }
+ private static string BuildMessage(ProcessRunResult result)
+ {
+ var builder = new StringBuilder();
+ builder.Append("Process ‘").Append(result.ProcessName);
+ builder.Append("’ exited with code ").Append(result.ExitCode).Append('.');
+ builder.AppendLine().Append("Executable: ").Append(result.FileName);
- var hasStdErr = !string.IsNullOrWhiteSpace(result.StdErr);
+ if (!string.IsNullOrWhiteSpace(result.Arguments))
+ {
+ builder.AppendLine().Append("Arguments: ").Append(result.Arguments);
+ }
- if (hasStdErr || !string.IsNullOrWhiteSpace(result.StdOut))
- {
- builder.AppendLine().Append(hasStdErr ? "Stderr:" : "Stdout:");
- builder.AppendLine().Append(hasStdErr ? result.StdErr : result.StdOut);
- }
+ var hasStdErr = !string.IsNullOrWhiteSpace(result.StdErr);
- return builder.ToString();
+ if (hasStdErr || !string.IsNullOrWhiteSpace(result.StdOut))
+ {
+ builder.AppendLine().Append(hasStdErr ? "Stderr:" : "Stdout:");
+ builder.AppendLine().Append(hasStdErr ? result.StdErr : result.StdOut);
}
+
+ return builder.ToString();
}
-}
+}
\ No newline at end of file
diff --git a/src/NUnit.TestAdapter.Tests.Acceptance/WorkspaceTools/ProcessRunResult.cs b/src/NUnit.TestAdapter.Tests.Acceptance/WorkspaceTools/ProcessRunResult.cs
index 04aeae69..3abf8f91 100644
--- a/src/NUnit.TestAdapter.Tests.Acceptance/WorkspaceTools/ProcessRunResult.cs
+++ b/src/NUnit.TestAdapter.Tests.Acceptance/WorkspaceTools/ProcessRunResult.cs
@@ -1,32 +1,25 @@
using System;
using System.IO;
-namespace NUnit.VisualStudio.TestAdapter.Tests.Acceptance.WorkspaceTools
-{
- public readonly struct ProcessRunResult
- {
- public ProcessRunResult(string fileName, string arguments, int exitCode, string stdOut, string stdErr)
- {
- FileName = fileName ?? throw new ArgumentNullException(nameof(fileName));
- Arguments = arguments;
- ExitCode = exitCode;
- StdOut = stdOut ?? string.Empty;
- StdErr = stdErr ?? string.Empty;
- }
-
- public string FileName { get; }
- public string Arguments { get; }
+namespace NUnit.VisualStudio.TestAdapter.Tests.Acceptance.WorkspaceTools;
- public string ProcessName => Path.GetFileName(FileName);
- public int ExitCode { get; }
- public string StdOut { get; }
- public string StdErr { get; }
+public readonly struct ProcessRunResult(
+ string fileName,
+ string arguments,
+ int exitCode,
+ string stdOut,
+ string stdErr)
+{
+ public string FileName { get; } = fileName ?? throw new ArgumentNullException(nameof(fileName));
+ public string Arguments { get; } = arguments;
- public ProcessRunResult ThrowIfError()
- {
- if (ExitCode == 0 && string.IsNullOrEmpty(StdErr)) return this;
+ public string ProcessName => Path.GetFileName(FileName);
+ public int ExitCode { get; } = exitCode;
+ public string StdOut { get; } = stdOut ?? string.Empty;
+ public string StdErr { get; } = stdErr ?? string.Empty;
- throw new ProcessErrorException(this);
- }
- }
-}
+ public ProcessRunResult ThrowIfError() =>
+ ExitCode == 0 && string.IsNullOrEmpty(StdErr)
+ ? this
+ : throw new ProcessErrorException(this);
+}
\ No newline at end of file
diff --git a/src/NUnit.TestAdapter.Tests.Acceptance/WorkspaceTools/ProcessUtils.cs b/src/NUnit.TestAdapter.Tests.Acceptance/WorkspaceTools/ProcessUtils.cs
index 213b6da4..ab57e217 100644
--- a/src/NUnit.TestAdapter.Tests.Acceptance/WorkspaceTools/ProcessUtils.cs
+++ b/src/NUnit.TestAdapter.Tests.Acceptance/WorkspaceTools/ProcessUtils.cs
@@ -4,158 +4,157 @@
using System.IO;
using System.Text;
-namespace NUnit.VisualStudio.TestAdapter.Tests.Acceptance.WorkspaceTools
+namespace NUnit.VisualStudio.TestAdapter.Tests.Acceptance.WorkspaceTools;
+
+public static class ProcessUtils
{
- public static class ProcessUtils
+ public static ProcessRunResult Run(string workingDirectory, string fileName, IEnumerable arguments = null)
{
- public static ProcessRunResult Run(string workingDirectory, string fileName, IEnumerable arguments = null)
- {
- if (!Path.IsPathRooted(workingDirectory))
- throw new ArgumentException(nameof(workingDirectory), "Working directory must not be relative.");
+ if (!Path.IsPathRooted(workingDirectory))
+ throw new ArgumentException(nameof(workingDirectory), "Working directory must not be relative.");
- if (string.IsNullOrWhiteSpace(fileName))
- throw new ArgumentException(nameof(fileName), "File name must be specified.");
+ if (string.IsNullOrWhiteSpace(fileName))
+ throw new ArgumentException(nameof(fileName), "File name must be specified.");
- var escapedArguments = arguments is null ? null : EscapeProcessArguments(arguments, alwaysQuote: false);
+ var escapedArguments = arguments is null ? null : EscapeProcessArguments(arguments, alwaysQuote: false);
- using var process = new Process
- {
- StartInfo =
- {
- UseShellExecute = false,
- WorkingDirectory = workingDirectory,
- FileName = fileName,
- Arguments = escapedArguments,
- RedirectStandardOutput = true,
- RedirectStandardError = true
- }
- };
- // This is inherited if the test runner was started by the Visual Studio process.
- // It breaks MSBuild 15’s targets when it tries to build legacy csprojs and vbprojs.
- process.StartInfo.EnvironmentVariables.Remove("VisualStudioVersion");
-
- var stdout = (StringBuilder)null;
- var stderr = (StringBuilder)null;
-
- process.OutputDataReceived += (sender, e) =>
+ using var process = new Process
+ {
+ StartInfo =
{
- if (e.Data is null) return;
+ UseShellExecute = false,
+ WorkingDirectory = workingDirectory,
+ FileName = fileName,
+ Arguments = escapedArguments,
+ RedirectStandardOutput = true,
+ RedirectStandardError = true
+ }
+ };
+ // This is inherited if the test runner was started by the Visual Studio process.
+ // It breaks MSBuild 15’s targets when it tries to build legacy csprojs and vbprojs.
+ process.StartInfo.EnvironmentVariables.Remove("VisualStudioVersion");
- if (stdout is null)
- stdout = new StringBuilder();
- else
- stdout.AppendLine();
+ var stdout = (StringBuilder)null;
+ var stderr = (StringBuilder)null;
- stdout.Append(e.Data);
- };
+ process.OutputDataReceived += (sender, e) =>
+ {
+ if (e.Data is null) return;
- process.ErrorDataReceived += (sender, e) =>
- {
- if (e.Data is null) return;
-
- if (stderr is null)
- stderr = new StringBuilder();
- else
- stderr.AppendLine();
-
- stderr.Append(e.Data);
- };
-
- process.Start();
- process.BeginErrorReadLine();
- process.BeginOutputReadLine();
- process.WaitForExit();
-
- return new ProcessRunResult(
- fileName,
- escapedArguments,
- process.ExitCode,
- stdout?.ToString(),
- stderr?.ToString());
- }
+ if (stdout is null)
+ stdout = new StringBuilder();
+ else
+ stdout.AppendLine();
- private static readonly char[] CharsThatRequireQuoting = { ' ', '"' };
- private static readonly char[] CharsThatRequireEscaping = { '\\', '"' };
+ stdout.Append(e.Data);
+ };
- ///
- /// Escapes arbitrary values so that the process receives the exact string you intend and injection is impossible.
- /// Spec: https://msdn.microsoft.com/en-us/library/bb776391.aspx.
- ///
- public static string EscapeProcessArguments(IEnumerable literalValues, bool alwaysQuote = false)
+ process.ErrorDataReceived += (sender, e) =>
{
- if (literalValues is null) throw new ArgumentNullException(nameof(literalValues));
+ if (e.Data is null) return;
+
+ if (stderr is null)
+ stderr = new StringBuilder();
+ else
+ stderr.AppendLine();
+
+ stderr.Append(e.Data);
+ };
+
+ process.Start();
+ process.BeginErrorReadLine();
+ process.BeginOutputReadLine();
+ process.WaitForExit();
+
+ return new ProcessRunResult(
+ fileName,
+ escapedArguments,
+ process.ExitCode,
+ stdout?.ToString(),
+ stderr?.ToString());
+ }
- using var en = literalValues.GetEnumerator();
- if (!en.MoveNext()) return string.Empty;
+ private static readonly char[] CharsThatRequireQuoting = { ' ', '"' };
+ private static readonly char[] CharsThatRequireEscaping = { '\\', '"' };
- var builder = new StringBuilder();
+ ///
+ /// Escapes arbitrary values so that the process receives the exact string you intend and injection is impossible.
+ /// Spec: https://msdn.microsoft.com/en-us/library/bb776391.aspx.
+ ///
+ public static string EscapeProcessArguments(IEnumerable literalValues, bool alwaysQuote = false)
+ {
+ if (literalValues is null) throw new ArgumentNullException(nameof(literalValues));
- while (true)
- {
- EscapeProcessArgument(builder, en.Current, alwaysQuote);
- if (!en.MoveNext()) break;
- builder.Append(' ');
- }
+ using var en = literalValues.GetEnumerator();
+ if (!en.MoveNext()) return string.Empty;
+
+ var builder = new StringBuilder();
+
+ while (true)
+ {
+ EscapeProcessArgument(builder, en.Current, alwaysQuote);
+ if (!en.MoveNext()) break;
+ builder.Append(' ');
+ }
+
+ return builder.ToString();
+ }
- return builder.ToString();
+ private static void EscapeProcessArgument(StringBuilder builder, string literalValue, bool alwaysQuote)
+ {
+ if (string.IsNullOrEmpty(literalValue))
+ {
+ builder.Append("\"\"");
+ return;
}
- private static void EscapeProcessArgument(StringBuilder builder, string literalValue, bool alwaysQuote)
+ if (literalValue.IndexOfAny(CharsThatRequireQuoting) == -1) // Happy path
{
- if (string.IsNullOrEmpty(literalValue))
+ if (!alwaysQuote)
{
- builder.Append("\"\"");
+ builder.Append(literalValue);
return;
}
-
- if (literalValue.IndexOfAny(CharsThatRequireQuoting) == -1) // Happy path
+ if (literalValue[literalValue.Length - 1] != '\\')
{
- if (!alwaysQuote)
- {
- builder.Append(literalValue);
- return;
- }
- if (literalValue[literalValue.Length - 1] != '\\')
- {
- builder.Append('"').Append(literalValue).Append('"');
- return;
- }
+ builder.Append('"').Append(literalValue).Append('"');
+ return;
}
+ }
- builder.Append('"');
+ builder.Append('"');
+
+ var nextPosition = 0;
+ while (true)
+ {
+ var nextEscapeChar = literalValue.IndexOfAny(CharsThatRequireEscaping, nextPosition);
+ if (nextEscapeChar == -1) break;
- var nextPosition = 0;
- while (true)
+ builder.Append(literalValue, nextPosition, nextEscapeChar - nextPosition);
+ nextPosition = nextEscapeChar + 1;
+
+ switch (literalValue[nextEscapeChar])
{
- var nextEscapeChar = literalValue.IndexOfAny(CharsThatRequireEscaping, nextPosition);
- if (nextEscapeChar == -1) break;
-
- builder.Append(literalValue, nextPosition, nextEscapeChar - nextPosition);
- nextPosition = nextEscapeChar + 1;
-
- switch (literalValue[nextEscapeChar])
- {
- case '"':
- builder.Append("\\\"");
- break;
- case '\\':
- var numBackslashes = 1;
- while (nextPosition < literalValue.Length && literalValue[nextPosition] == '\\')
- {
- numBackslashes++;
- nextPosition++;
- }
- if (nextPosition == literalValue.Length || literalValue[nextPosition] == '"')
- numBackslashes <<= 1;
-
- for (; numBackslashes != 0; numBackslashes--)
- builder.Append('\\');
- break;
- }
+ case '"':
+ builder.Append("\\\"");
+ break;
+ case '\\':
+ var numBackslashes = 1;
+ while (nextPosition < literalValue.Length && literalValue[nextPosition] == '\\')
+ {
+ numBackslashes++;
+ nextPosition++;
+ }
+ if (nextPosition == literalValue.Length || literalValue[nextPosition] == '"')
+ numBackslashes <<= 1;
+
+ for (; numBackslashes != 0; numBackslashes--)
+ builder.Append('\\');
+ break;
}
-
- builder.Append(literalValue, nextPosition, literalValue.Length - nextPosition);
- builder.Append('"');
}
+
+ builder.Append(literalValue, nextPosition, literalValue.Length - nextPosition);
+ builder.Append('"');
}
-}
+}
\ No newline at end of file
diff --git a/src/NUnit.TestAdapter.Tests.Acceptance/WorkspaceTools/ProcessUtilsTests.cs b/src/NUnit.TestAdapter.Tests.Acceptance/WorkspaceTools/ProcessUtilsTests.cs
index 5cd6e322..d5399e18 100644
--- a/src/NUnit.TestAdapter.Tests.Acceptance/WorkspaceTools/ProcessUtilsTests.cs
+++ b/src/NUnit.TestAdapter.Tests.Acceptance/WorkspaceTools/ProcessUtilsTests.cs
@@ -1,91 +1,90 @@
using NUnit.Framework;
-namespace NUnit.VisualStudio.TestAdapter.Tests.Acceptance.WorkspaceTools
+namespace NUnit.VisualStudio.TestAdapter.Tests.Acceptance.WorkspaceTools;
+
+public static class ProcessUtilsTests
{
- public static class ProcessUtilsTests
+ [Test]
+ public static void EscapeProcessArguments_null()
{
- [Test]
- public static void EscapeProcessArguments_null()
- {
- Assert.That(ProcessUtils.EscapeProcessArguments(new string[] { null }), Is.EqualTo("\"\""));
- }
+ Assert.That(ProcessUtils.EscapeProcessArguments(new string[] { null }), Is.EqualTo("\"\""));
+ }
- [Test]
- public static void EscapeProcessArguments_null_alwaysQuote()
- {
- Assert.That(ProcessUtils.EscapeProcessArguments(new string[] { null }, true), Is.EqualTo("\"\""));
- }
+ [Test]
+ public static void EscapeProcessArguments_null_alwaysQuote()
+ {
+ Assert.That(ProcessUtils.EscapeProcessArguments(new string[] { null }, true), Is.EqualTo("\"\""));
+ }
- [Test]
- public static void EscapeProcessArguments_empty()
- {
- Assert.That(ProcessUtils.EscapeProcessArguments(new[] { string.Empty }), Is.EqualTo("\"\""));
- }
+ [Test]
+ public static void EscapeProcessArguments_empty()
+ {
+ Assert.That(ProcessUtils.EscapeProcessArguments(new[] { string.Empty }), Is.EqualTo("\"\""));
+ }
- [Test]
- public static void EscapeProcessArguments_empty_alwaysQuote()
- {
- Assert.That(ProcessUtils.EscapeProcessArguments(new[] { string.Empty }, true), Is.EqualTo("\"\""));
- }
+ [Test]
+ public static void EscapeProcessArguments_empty_alwaysQuote()
+ {
+ Assert.That(ProcessUtils.EscapeProcessArguments(new[] { string.Empty }, true), Is.EqualTo("\"\""));
+ }
- [Test]
- public static void EscapeProcessArguments_simple()
- {
- Assert.That(ProcessUtils.EscapeProcessArguments(new[] { "123" }), Is.EqualTo("123"));
- }
+ [Test]
+ public static void EscapeProcessArguments_simple()
+ {
+ Assert.That(ProcessUtils.EscapeProcessArguments(new[] { "123" }), Is.EqualTo("123"));
+ }
- [Test]
- public static void EscapeProcessArguments_simple_alwaysQuote()
- {
- Assert.That(ProcessUtils.EscapeProcessArguments(new[] { "123" }, true), Is.EqualTo("\"123\""));
- }
+ [Test]
+ public static void EscapeProcessArguments_simple_alwaysQuote()
+ {
+ Assert.That(ProcessUtils.EscapeProcessArguments(new[] { "123" }, true), Is.EqualTo("\"123\""));
+ }
- [Test]
- public static void EscapeProcessArguments_with_ending_backslash()
- {
- Assert.That(ProcessUtils.EscapeProcessArguments(new[] { "123\\" }), Is.EqualTo("123\\"));
- }
+ [Test]
+ public static void EscapeProcessArguments_with_ending_backslash()
+ {
+ Assert.That(ProcessUtils.EscapeProcessArguments(new[] { "123\\" }), Is.EqualTo("123\\"));
+ }
- [Test]
- public static void EscapeProcessArguments_with_ending_backslash_alwaysQuote()
- {
- Assert.That(ProcessUtils.EscapeProcessArguments(new[] { "123\\" }, true), Is.EqualTo("\"123\\\\\""));
- }
+ [Test]
+ public static void EscapeProcessArguments_with_ending_backslash_alwaysQuote()
+ {
+ Assert.That(ProcessUtils.EscapeProcessArguments(new[] { "123\\" }, true), Is.EqualTo("\"123\\\\\""));
+ }
- [Test]
- public static void EscapeProcessArguments_with_spaces_and_ending_backslash()
- {
- Assert.That(ProcessUtils.EscapeProcessArguments(new[] { " 1 2 3 \\" }), Is.EqualTo("\" 1 2 3 \\\\\""));
- }
+ [Test]
+ public static void EscapeProcessArguments_with_spaces_and_ending_backslash()
+ {
+ Assert.That(ProcessUtils.EscapeProcessArguments(new[] { " 1 2 3 \\" }), Is.EqualTo("\" 1 2 3 \\\\\""));
+ }
- [Test]
- public static void EscapeProcessArguments_with_spaces()
- {
- Assert.That(ProcessUtils.EscapeProcessArguments(new[] { " 1 2 3 " }), Is.EqualTo("\" 1 2 3 \""));
- }
+ [Test]
+ public static void EscapeProcessArguments_with_spaces()
+ {
+ Assert.That(ProcessUtils.EscapeProcessArguments(new[] { " 1 2 3 " }), Is.EqualTo("\" 1 2 3 \""));
+ }
- [Test]
- public static void EscapeProcessArguments_with_quotes()
- {
- Assert.That(ProcessUtils.EscapeProcessArguments(new[] { "\"1\"2\"3\"" }), Is.EqualTo("\"\\\"1\\\"2\\\"3\\\"\""));
- }
+ [Test]
+ public static void EscapeProcessArguments_with_quotes()
+ {
+ Assert.That(ProcessUtils.EscapeProcessArguments(new[] { "\"1\"2\"3\"" }), Is.EqualTo("\"\\\"1\\\"2\\\"3\\\"\""));
+ }
- [Test]
- public static void EscapeProcessArguments_with_slashes()
- {
- Assert.That(ProcessUtils.EscapeProcessArguments(new[] { "1\\2\\\\3\\\\\\" }), Is.EqualTo("1\\2\\\\3\\\\\\"));
- }
+ [Test]
+ public static void EscapeProcessArguments_with_slashes()
+ {
+ Assert.That(ProcessUtils.EscapeProcessArguments(new[] { "1\\2\\\\3\\\\\\" }), Is.EqualTo("1\\2\\\\3\\\\\\"));
+ }
- [Test]
- public static void EscapeProcessArguments_with_slashes_alwaysQuote()
- {
- Assert.That(ProcessUtils.EscapeProcessArguments(new[] { "1\\2\\\\3\\\\\\" }, true), Is.EqualTo("\"1\\2\\\\3\\\\\\\\\\\\\""));
- }
+ [Test]
+ public static void EscapeProcessArguments_with_slashes_alwaysQuote()
+ {
+ Assert.That(ProcessUtils.EscapeProcessArguments(new[] { "1\\2\\\\3\\\\\\" }, true), Is.EqualTo("\"1\\2\\\\3\\\\\\\\\\\\\""));
+ }
- [Test]
- public static void EscapeProcessArguments_slashes_followed_by_quotes()
- {
- Assert.That(ProcessUtils.EscapeProcessArguments(new[] { "\\\\\"" }), Is.EqualTo("\"\\\\\\\\\\\"\""));
- }
+ [Test]
+ public static void EscapeProcessArguments_slashes_followed_by_quotes()
+ {
+ Assert.That(ProcessUtils.EscapeProcessArguments(new[] { "\\\\\"" }), Is.EqualTo("\"\\\\\\\\\\\"\""));
}
-}
+}
\ No newline at end of file
diff --git a/src/NUnit.TestAdapter.Tests.Acceptance/WorkspaceTools/TempFile.cs b/src/NUnit.TestAdapter.Tests.Acceptance/WorkspaceTools/TempFile.cs
index 33c57456..0940693c 100644
--- a/src/NUnit.TestAdapter.Tests.Acceptance/WorkspaceTools/TempFile.cs
+++ b/src/NUnit.TestAdapter.Tests.Acceptance/WorkspaceTools/TempFile.cs
@@ -3,25 +3,24 @@
using System.IO;
using IO = System.IO;
-namespace NUnit.VisualStudio.TestAdapter.Tests.Acceptance.WorkspaceTools
+namespace NUnit.VisualStudio.TestAdapter.Tests.Acceptance.WorkspaceTools;
+
+[DebuggerDisplay("{ToString(),nq}")]
+internal sealed class TempFile : IDisposable
{
- [DebuggerDisplay("{ToString(),nq}")]
- internal sealed class TempFile : IDisposable
- {
- public string Path { get; }
+ public string Path { get; }
- public TempFile()
- {
- Path = IO.Path.GetTempFileName();
- }
+ public TempFile()
+ {
+ Path = IO.Path.GetTempFileName();
+ }
- public void Dispose()
- {
- File.Delete(Path);
- }
+ public void Dispose()
+ {
+ File.Delete(Path);
+ }
- public override string ToString() => Path;
+ public override string ToString() => Path;
- public static implicit operator string(TempFile tempDirectory) => tempDirectory.Path;
- }
-}
+ public static implicit operator string(TempFile tempDirectory) => tempDirectory.Path;
+}
\ No newline at end of file
diff --git a/src/NUnit.TestAdapter.Tests.Acceptance/WorkspaceTools/ToolResolver.cs b/src/NUnit.TestAdapter.Tests.Acceptance/WorkspaceTools/ToolResolver.cs
index 52013a30..54350e81 100644
--- a/src/NUnit.TestAdapter.Tests.Acceptance/WorkspaceTools/ToolResolver.cs
+++ b/src/NUnit.TestAdapter.Tests.Acceptance/WorkspaceTools/ToolResolver.cs
@@ -3,101 +3,100 @@
using System.Linq;
using System.Net;
-namespace NUnit.VisualStudio.TestAdapter.Tests.Acceptance.WorkspaceTools
+namespace NUnit.VisualStudio.TestAdapter.Tests.Acceptance.WorkspaceTools;
+
+public sealed class ToolResolver
{
- public sealed class ToolResolver
- {
- private readonly string downloadCacheDirectory;
+ private readonly string downloadCacheDirectory;
- private readonly Lazy nuGet;
- public string NuGet => nuGet.Value;
+ private readonly Lazy nuGet;
+ public string NuGet => nuGet.Value;
- private readonly Lazy msBuild;
- public string MSBuild => msBuild.Value;
+ private readonly Lazy msBuild;
+ public string MSBuild => msBuild.Value;
- private readonly Lazy vsTest;
- public string VSTest => vsTest.Value;
+ private readonly Lazy vsTest;
+ public string VSTest => vsTest.Value;
- private readonly Lazy vsWhere;
- public string VSWhere => vsWhere.Value;
+ private readonly Lazy vsWhere;
+ public string VSWhere => vsWhere.Value;
- public ToolResolver(string downloadCacheDirectory)
- {
- if (!Path.IsPathRooted(downloadCacheDirectory))
- throw new ArgumentException(nameof(downloadCacheDirectory), "Download cache directory path must be rooted.");
-
- this.downloadCacheDirectory = downloadCacheDirectory;
+ public ToolResolver(string downloadCacheDirectory)
+ {
+ if (!Path.IsPathRooted(downloadCacheDirectory))
+ throw new ArgumentException(nameof(downloadCacheDirectory), "Download cache directory path must be rooted.");
- nuGet = new Lazy(() => FindDownloadedTool("NuGet", "nuget.exe", "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe"));
+ this.downloadCacheDirectory = downloadCacheDirectory;
- msBuild = new Lazy(() =>
- {
- var vsInstallation =
- FindVisualStudio(requiredComponent: "Microsoft.Component.MSBuild")
- ?? throw new InvalidOperationException("MSBuild is not installed with Visual Studio on this machine.");
+ nuGet = new Lazy(() => FindDownloadedTool("NuGet", "nuget.exe", "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe"));
- var path = Path.Combine(vsInstallation, @"MSBuild\Current\Bin\MSBuild.exe");
- if (File.Exists(path)) return path;
+ msBuild = new Lazy(() =>
+ {
+ var vsInstallation =
+ FindVisualStudio(requiredComponent: "Microsoft.Component.MSBuild")
+ ?? throw new InvalidOperationException("MSBuild is not installed with Visual Studio on this machine.");
- var oldPath = Path.Combine(vsInstallation, @"MSBuild\15.0\Bin\MSBuild.exe");
- if (File.Exists(oldPath)) return oldPath;
+ var path = Path.Combine(vsInstallation, @"MSBuild\Current\Bin\MSBuild.exe");
+ if (File.Exists(path)) return path;
- throw new FileNotFoundException("Cannot locate MSBuild.exe.");
- });
+ var oldPath = Path.Combine(vsInstallation, @"MSBuild\15.0\Bin\MSBuild.exe");
+ if (File.Exists(oldPath)) return oldPath;
- vsTest = new Lazy(() =>
- {
- var vsInstallation =
- FindVisualStudio(requiredComponent: "Microsoft.VisualStudio.TestTools.TestPlatform.V1.CLI") // https://github.com/Microsoft/vswhere/issues/126#issuecomment-360542783
- ?? throw new InvalidOperationException("VSTest is not installed with Visual Studio on this machine.");
+ throw new FileNotFoundException("Cannot locate MSBuild.exe.");
+ });
- return Path.Combine(vsInstallation, @"Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.console.exe");
- });
+ vsTest = new Lazy(() =>
+ {
+ var vsInstallation =
+ FindVisualStudio(requiredComponent: "Microsoft.VisualStudio.TestTools.TestPlatform.V1.CLI") // https://github.com/Microsoft/vswhere/issues/126#issuecomment-360542783
+ ?? throw new InvalidOperationException("VSTest is not installed with Visual Studio on this machine.");
- vsWhere = new Lazy(() => Path.Combine(
- Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86),
- @"Microsoft Visual Studio\Installer\vswhere.exe"));
- }
+ return Path.Combine(vsInstallation, @"Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.console.exe");
+ });
- private string FindDownloadedTool(string id, string fileName, string downloadUrl)
- {
- var directory = Path.Combine(downloadCacheDirectory, Utils.GetSafeFilename(id));
- var toolPath = Path.Combine(directory, fileName);
+ vsWhere = new Lazy(() => Path.Combine(
+ Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86),
+ @"Microsoft Visual Studio\Installer\vswhere.exe"));
+ }
- if (!File.Exists(toolPath))
- {
- Directory.CreateDirectory(directory);
+ private string FindDownloadedTool(string id, string fileName, string downloadUrl)
+ {
+ var directory = Path.Combine(downloadCacheDirectory, Utils.GetSafeFilename(id));
+ var toolPath = Path.Combine(directory, fileName);
- using var client = new WebClient();
- client.DownloadFile(downloadUrl, toolPath);
- }
+ if (!File.Exists(toolPath))
+ {
+ Directory.CreateDirectory(directory);
- return toolPath;
+ using var client = new WebClient();
+ client.DownloadFile(downloadUrl, toolPath);
}
- private string FindVisualStudio(string requiredComponent)
- {
- var arguments = new[] { "-latest", "-products", "*", "-requires", requiredComponent, "-property", "installationPath" };
+ return toolPath;
+ }
- var releaseInstallationPath = ProcessUtils.Run(Environment.CurrentDirectory, VSWhere, arguments)
- .ThrowIfError()
- .StdOut;
+ private string FindVisualStudio(string requiredComponent)
+ {
+ var arguments = new[] { "-latest", "-products", "*", "-requires", requiredComponent, "-property", "installationPath" };
- if (!string.IsNullOrEmpty(releaseInstallationPath))
- return releaseInstallationPath;
+ var releaseInstallationPath = ProcessUtils.Run(Environment.CurrentDirectory, VSWhere, arguments)
+ .ThrowIfError()
+ .StdOut;
- var prereleaseInstallationPath =
- ProcessUtils.Run(
+ if (!string.IsNullOrEmpty(releaseInstallationPath))
+ return releaseInstallationPath;
+
+ var prereleaseInstallationPath =
+ ProcessUtils.Run(
Environment.CurrentDirectory,
VSWhere,
arguments.Concat(new[] { "-prerelease" }))
.ThrowIfError()
.StdOut;
- if (!string.IsNullOrEmpty(prereleaseInstallationPath))
- return prereleaseInstallationPath;
+ if (!string.IsNullOrEmpty(prereleaseInstallationPath))
+ return prereleaseInstallationPath;
- return null;
- }
+ return null;
}
-}
+}
\ No newline at end of file
diff --git a/src/NUnit.TestAdapter.Tests.Acceptance/WorkspaceTools/VSTestResult.cs b/src/NUnit.TestAdapter.Tests.Acceptance/WorkspaceTools/VSTestResult.cs
index b023aaba..9ca252d6 100644
--- a/src/NUnit.TestAdapter.Tests.Acceptance/WorkspaceTools/VSTestResult.cs
+++ b/src/NUnit.TestAdapter.Tests.Acceptance/WorkspaceTools/VSTestResult.cs
@@ -6,87 +6,86 @@
using System.Xml.Linq;
using NUnit.Framework;
-namespace NUnit.VisualStudio.TestAdapter.Tests.Acceptance.WorkspaceTools
+namespace NUnit.VisualStudio.TestAdapter.Tests.Acceptance.WorkspaceTools;
+
+[DebuggerDisplay("{ToString(),nq}")]
+public readonly struct VSTestResult
{
- [DebuggerDisplay("{ToString(),nq}")]
- public readonly struct VSTestResult
- {
- public ProcessRunResult ProcessRunResult { get; }
- public string Outcome { get; }
- public VSTestResultCounters Counters { get; }
- public IReadOnlyList RunErrors { get; }
- public IReadOnlyList RunWarnings { get; }
+ public ProcessRunResult ProcessRunResult { get; }
+ public string Outcome { get; }
+ public VSTestResultCounters Counters { get; }
+ public IReadOnlyList RunErrors { get; }
+ public IReadOnlyList RunWarnings { get; }
- public VSTestResult(ProcessRunResult processRunResult)
- {
- ProcessRunResult = processRunResult;
- Outcome = "";
- Counters = VSTestResultCounters.CreateEmptyCounters();
- RunErrors = Array.Empty();
- RunWarnings = Array.Empty();
- }
+ public VSTestResult(ProcessRunResult processRunResult)
+ {
+ ProcessRunResult = processRunResult;
+ Outcome = "";
+ Counters = VSTestResultCounters.CreateEmptyCounters();
+ RunErrors = Array.Empty();
+ RunWarnings = Array.Empty();
+ }
- public VSTestResult(ProcessRunResult processRunResult, string outcome, VSTestResultCounters counters, IReadOnlyList runErrors = null, IReadOnlyList runWarnings = null)
- {
- ProcessRunResult = processRunResult;
- Outcome = outcome;
- Counters = counters;
- RunErrors = runErrors ?? Array.Empty();
- RunWarnings = runWarnings ?? Array.Empty();
- }
+ public VSTestResult(ProcessRunResult processRunResult, string outcome, VSTestResultCounters counters, IReadOnlyList runErrors = null, IReadOnlyList runWarnings = null)
+ {
+ ProcessRunResult = processRunResult;
+ Outcome = outcome;
+ Counters = counters;
+ RunErrors = runErrors ?? Array.Empty();
+ RunWarnings = runWarnings ?? Array.Empty();
+ }
- public static VSTestResult Load(ProcessRunResult processRunResult, string trxFilePath)
- {
- var trx = XDocument.Load(trxFilePath);
+ public static VSTestResult Load(ProcessRunResult processRunResult, string trxFilePath)
+ {
+ var trx = XDocument.Load(trxFilePath);
- var ns = (XNamespace)"http://microsoft.com/schemas/VisualStudio/TeamTest/2010";
+ var ns = (XNamespace)"http://microsoft.com/schemas/VisualStudio/TeamTest/2010";
- var resultSummary = trx.Root.Element(ns + "ResultSummary");
- var counters = resultSummary.Element(ns + "Counters");
+ var resultSummary = trx.Root.Element(ns + "ResultSummary");
+ var counters = resultSummary.Element(ns + "Counters");
- var runInfos = resultSummary.Element(ns + "RunInfos")?.Elements().Select(runInfo => (
- Outcome: runInfo.Attribute("outcome")?.Value,
- Text: runInfo.Element(ns + "Text")?.Value ?? string.Empty));
+ var runInfos = resultSummary.Element(ns + "RunInfos")?.Elements().Select(runInfo => (
+ Outcome: runInfo.Attribute("outcome")?.Value,
+ Text: runInfo.Element(ns + "Text")?.Value ?? string.Empty));
- return new VSTestResult(
- processRunResult,
- (string)resultSummary.Attribute("outcome"),
- new VSTestResultCounters(
- (int)counters.Attribute("total"),
- (int)counters.Attribute("executed"),
- (int)counters.Attribute("passed"),
- (int)counters.Attribute("failed"),
- (int)counters.Attribute("error"),
- (int)counters.Attribute("timeout"),
- (int)counters.Attribute("aborted"),
- (int)counters.Attribute("inconclusive"),
- (int)counters.Attribute("passedButRunAborted"),
- (int)counters.Attribute("notRunnable"),
- (int)counters.Attribute("notExecuted"),
- (int)counters.Attribute("disconnected"),
- (int)counters.Attribute("warning"),
- (int)counters.Attribute("completed"),
- (int)counters.Attribute("inProgress"),
- (int)counters.Attribute("pending")),
- runErrors: runInfos?.Where(i => i.Outcome == "Error").Select(i => i.Text).ToList(),
- runWarnings: runInfos?.Where(i => i.Outcome == "Warning").Select(i => i.Text).ToList());
- }
+ return new VSTestResult(
+ processRunResult,
+ (string)resultSummary.Attribute("outcome"),
+ new VSTestResultCounters(
+ (int)counters.Attribute("total"),
+ (int)counters.Attribute("executed"),
+ (int)counters.Attribute("passed"),
+ (int)counters.Attribute("failed"),
+ (int)counters.Attribute("error"),
+ (int)counters.Attribute("timeout"),
+ (int)counters.Attribute("aborted"),
+ (int)counters.Attribute("inconclusive"),
+ (int)counters.Attribute("passedButRunAborted"),
+ (int)counters.Attribute("notRunnable"),
+ (int)counters.Attribute("notExecuted"),
+ (int)counters.Attribute("disconnected"),
+ (int)counters.Attribute("warning"),
+ (int)counters.Attribute("completed"),
+ (int)counters.Attribute("inProgress"),
+ (int)counters.Attribute("pending")),
+ runErrors: runInfos?.Where(i => i.Outcome == "Error").Select(i => i.Text).ToList(),
+ runWarnings: runInfos?.Where(i => i.Outcome == "Warning").Select(i => i.Text).ToList());
+ }
- public void AssertSinglePassingTest()
- {
- Assert.That(RunErrors, Is.Empty);
+ public void AssertSinglePassingTest()
+ {
+ Assert.That(RunErrors, Is.Empty);
- if (RunWarnings.Any())
- Assert.Fail("Unexpected VSTest warnings. Standard output:" + Environment.NewLine + ProcessRunResult.StdOut);
+ if (RunWarnings.Any())
+ Assert.Fail("Unexpected VSTest warnings. Standard output:" + Environment.NewLine + ProcessRunResult.StdOut);
- Assert.That(Counters.Total, Is.EqualTo(1), "There should be a single test in the test results.");
- Assert.That(Counters.Passed, Is.EqualTo(1), "There should be a single test passing in the test results.");
- }
+ Assert.That(Counters.Total, Is.EqualTo(1), "There should be a single test in the test results.");
+ Assert.That(Counters.Passed, Is.EqualTo(1), "There should be a single test passing in the test results.");
+ }
- public override string ToString()
- {
- return Outcome + ", " + Counters;
- }
+ public override string ToString()
+ {
+ return Outcome + ", " + Counters;
}
-}
+}
\ No newline at end of file
diff --git a/src/NUnit.TestAdapter.Tests.Acceptance/WorkspaceTools/VSTestResultCounters.cs b/src/NUnit.TestAdapter.Tests.Acceptance/WorkspaceTools/VSTestResultCounters.cs
index c91a6f8c..1d2f1ae4 100644
--- a/src/NUnit.TestAdapter.Tests.Acceptance/WorkspaceTools/VSTestResultCounters.cs
+++ b/src/NUnit.TestAdapter.Tests.Acceptance/WorkspaceTools/VSTestResultCounters.cs
@@ -1,68 +1,67 @@
using System.Diagnostics;
-namespace NUnit.VisualStudio.TestAdapter.Tests.Acceptance.WorkspaceTools
+namespace NUnit.VisualStudio.TestAdapter.Tests.Acceptance.WorkspaceTools;
+
+[DebuggerDisplay("{ToString(),nq}")]
+public readonly struct VSTestResultCounters
{
- [DebuggerDisplay("{ToString(),nq}")]
- public readonly struct VSTestResultCounters
- {
- public int Total { get; }
- public int Executed { get; }
- public int Passed { get; }
- public int Failed { get; }
- public int Error { get; }
- public int Timeout { get; }
- public int Aborted { get; }
- public int Inconclusive { get; }
- public int PassedButRunAborted { get; }
- public int NotRunnable { get; }
- public int NotExecuted { get; }
- public int Disconnected { get; }
- public int Warning { get; }
- public int Completed { get; }
- public int InProgress { get; }
- public int Pending { get; }
+ public int Total { get; }
+ public int Executed { get; }
+ public int Passed { get; }
+ public int Failed { get; }
+ public int Error { get; }
+ public int Timeout { get; }
+ public int Aborted { get; }
+ public int Inconclusive { get; }
+ public int PassedButRunAborted { get; }
+ public int NotRunnable { get; }
+ public int NotExecuted { get; }
+ public int Disconnected { get; }
+ public int Warning { get; }
+ public int Completed { get; }
+ public int InProgress { get; }
+ public int Pending { get; }
- public static VSTestResultCounters CreateEmptyCounters() => new (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+ public static VSTestResultCounters CreateEmptyCounters() => new (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- public VSTestResultCounters(
- int total,
- int executed,
- int passed,
- int failed,
- int error,
- int timeout,
- int aborted,
- int inconclusive,
- int passedButRunAborted,
- int notRunnable,
- int notExecuted,
- int disconnected,
- int warning,
- int completed,
- int inProgress,
- int pending)
- {
- Total = total;
- Executed = executed;
- Passed = passed;
- Failed = failed;
- Error = error;
- Timeout = timeout;
- Aborted = aborted;
- Inconclusive = inconclusive;
- PassedButRunAborted = passedButRunAborted;
- NotRunnable = notRunnable;
- NotExecuted = notExecuted;
- Disconnected = disconnected;
- Warning = warning;
- Completed = completed;
- InProgress = inProgress;
- Pending = pending;
- }
+ public VSTestResultCounters(
+ int total,
+ int executed,
+ int passed,
+ int failed,
+ int error,
+ int timeout,
+ int aborted,
+ int inconclusive,
+ int passedButRunAborted,
+ int notRunnable,
+ int notExecuted,
+ int disconnected,
+ int warning,
+ int completed,
+ int inProgress,
+ int pending)
+ {
+ Total = total;
+ Executed = executed;
+ Passed = passed;
+ Failed = failed;
+ Error = error;
+ Timeout = timeout;
+ Aborted = aborted;
+ Inconclusive = inconclusive;
+ PassedButRunAborted = passedButRunAborted;
+ NotRunnable = notRunnable;
+ NotExecuted = notExecuted;
+ Disconnected = disconnected;
+ Warning = warning;
+ Completed = completed;
+ InProgress = inProgress;
+ Pending = pending;
+ }
- public override string ToString()
- {
- return "Total: " + Total;
- }
+ public override string ToString()
+ {
+ return "Total: " + Total;
}
-}
+}
\ No newline at end of file
diff --git a/src/NUnit.TestAdapter.Tests.Acceptance/WorkspaceTools/VsTestFilter.cs b/src/NUnit.TestAdapter.Tests.Acceptance/WorkspaceTools/VsTestFilter.cs
index 442b89ad..b9a37507 100644
--- a/src/NUnit.TestAdapter.Tests.Acceptance/WorkspaceTools/VsTestFilter.cs
+++ b/src/NUnit.TestAdapter.Tests.Acceptance/WorkspaceTools/VsTestFilter.cs
@@ -1,49 +1,48 @@
-namespace NUnit.VisualStudio.TestAdapter.Tests.Acceptance.WorkspaceTools
+namespace NUnit.VisualStudio.TestAdapter.Tests.Acceptance.WorkspaceTools;
+
+public interface IFilterArgument
{
- public interface IFilterArgument
- {
- string CompletedArgument();
- bool HasArguments { get; }
- }
+ string CompletedArgument();
+ bool HasArguments { get; }
+}
- public abstract class VsTestFilter : IFilterArgument
+public abstract class VsTestFilter : IFilterArgument
+{
+ protected string Arguments { get; }
+ public bool HasArguments => Arguments.Length > 0;
+ protected VsTestFilter(string arguments)
{
- protected string Arguments { get; }
- public bool HasArguments => Arguments.Length > 0;
- protected VsTestFilter(string arguments)
- {
- Arguments = arguments;
- }
+ Arguments = arguments;
+ }
- public abstract string CompletedArgument();
+ public abstract string CompletedArgument();
- public static IFilterArgument NoFilter => new VsTestTestCaseFilter("");
- }
+ public static IFilterArgument NoFilter => new VsTestTestCaseFilter("");
+}
- public class VsTestTestCaseFilter : VsTestFilter
+public class VsTestTestCaseFilter : VsTestFilter
+{
+ public VsTestTestCaseFilter(string arguments) : base(arguments)
{
- public VsTestTestCaseFilter(string arguments) : base(arguments)
- {
- }
-
- public override string CompletedArgument()
- {
- var completeFilterStatement = $"/TestCaseFilter:{Arguments}";
- return completeFilterStatement;
- }
}
- public class VsTestTestsFilter : VsTestFilter
+ public override string CompletedArgument()
{
- public VsTestTestsFilter(string arguments) : base(arguments)
- {
- }
- public override string CompletedArgument()
- {
- var completeFilterStatement = $"/Tests:{Arguments}";
- return completeFilterStatement;
- }
+ var completeFilterStatement = $"/TestCaseFilter:{Arguments}";
+ return completeFilterStatement;
}
}
+
+public class VsTestTestsFilter : VsTestFilter
+{
+ public VsTestTestsFilter(string arguments) : base(arguments)
+ {
+ }
+ public override string CompletedArgument()
+ {
+ var completeFilterStatement = $"/Tests:{Arguments}";
+ return completeFilterStatement;
+ }
+}
\ No newline at end of file
diff --git a/src/NUnit3AdapterExternalTests/NUnit3AdapterExternalTests.csproj b/src/NUnit3AdapterExternalTests/NUnit3AdapterExternalTests.csproj
index 2ab906f0..853892ab 100644
--- a/src/NUnit3AdapterExternalTests/NUnit3AdapterExternalTests.csproj
+++ b/src/NUnit3AdapterExternalTests/NUnit3AdapterExternalTests.csproj
@@ -6,8 +6,13 @@
net462;netcoreapp3.1
-
-
+
+
+
+
+
+
+
@@ -15,6 +20,7 @@
all
runtime; build; native; contentfiles; analyzers; buildtransitive
+
\ No newline at end of file
diff --git a/src/NUnitTestAdapter/AdapterSettings.cs b/src/NUnitTestAdapter/AdapterSettings.cs
index f3fc4092..f065ebb6 100644
--- a/src/NUnitTestAdapter/AdapterSettings.cs
+++ b/src/NUnitTestAdapter/AdapterSettings.cs
@@ -31,597 +31,586 @@
using NUnit.Engine;
-namespace NUnit.VisualStudio.TestAdapter
-{
- public enum VsTestCategoryType
- {
- NUnit,
- MsTest
- }
-
- public enum DisplayNameOptions
- {
- Name,
- FullName,
- FullNameSep
- }
-
- public enum DiscoveryMethod
- {
- Legacy,
- Current
- }
+namespace NUnit.VisualStudio.TestAdapter;
- public class AdapterSettings : IAdapterSettings
- {
- private const string RANDOM_SEED_FILE = "nunit_random_seed.tmp";
- private readonly ITestLogger _logger;
+public enum VsTestCategoryType
+{
+ NUnit,
+ MsTest
+}
- #region Constructor
+public enum DisplayNameOptions
+{
+ Name,
+ FullName,
+ FullNameSep
+}
- public AdapterSettings(ITestLogger logger)
- {
- _logger = logger;
- }
+public enum DiscoveryMethod
+{
+ Legacy,
+ Current
+}
- #endregion
+public class AdapterSettings(ITestLogger logger) : IAdapterSettings
+{
+ private const string RandomSeedFile = "nunit_random_seed.tmp";
- #region Properties - General
+ #region Properties - General
- public int MaxCpuCount { get; private set; }
+ public int MaxCpuCount { get; private set; }
- public string ResultsDirectory { get; private set; }
+ public string ResultsDirectory { get; private set; }
- public string TargetPlatform { get; private set; }
+ public string TargetPlatform { get; private set; }
- public string TargetFrameworkVersion { get; private set; }
+ public string TargetFrameworkVersion { get; private set; }
- public string TestAdapterPaths { get; private set; }
+ public string TestAdapterPaths { get; private set; }
- ///
- /// If false, an adapter need not parse symbols to provide test case file, line number.
- ///
- public bool CollectSourceInformation { get; private set; }
+ ///
+ /// If false, an adapter need not parse symbols to provide test case file, line number.
+ ///
+ public bool CollectSourceInformation { get; private set; }
- ///
- /// If true, an adapter shouldn't create appdomains to run tests.
- ///
- public bool DisableAppDomain { get; private set; }
+ ///
+ /// If true, an adapter shouldn't create appdomains to run tests.
+ ///
+ public bool DisableAppDomain { get; private set; }
- ///
- /// If true, an adapter should disable any test case parallelization.
- ///
- public bool DisableParallelization { get; private set; }
+ ///
+ /// If true, an adapter should disable any test case parallelization.
+ ///
+ public bool DisableParallelization { get; private set; }
- public bool AllowParallelWithDebugger { get; private set; }
+ public bool AllowParallelWithDebugger { get; private set; }
- ///
- /// True if test run is triggered in an IDE/Editor context.
- ///
- public bool DesignMode { get; private set; }
+ ///
+ /// True if test run is triggered in an IDE/Editor context.
+ ///
+ public bool DesignMode { get; private set; }
- #endregion
+ #endregion
- #region Properties - TestRunParameters
+ #region Properties - TestRunParameters
- public IDictionary TestProperties { get; private set; }
+ public IDictionary TestProperties { get; private set; }
- #endregion
+ #endregion
- #region Properties - NUnit Specific
+ #region Properties - NUnit Specific
- public string InternalTraceLevel { get; private set; }
- public InternalTraceLevel InternalTraceLevelEnum { get; private set; }
+ public string InternalTraceLevel { get; private set; }
+ public InternalTraceLevel InternalTraceLevelEnum { get; private set; }
- ///
- /// Is null if not set in runsettings.
- ///
- public string WorkDirectory { get; private set; }
- public string Where { get; private set; }
- public string TestOutputXml { get; private set; }
- public string TestOutputXmlFileName { get; private set; }
- public bool UseTestOutputXml => !string.IsNullOrEmpty(TestOutputXml) || OutputXmlFolderMode == OutputXmlFolderMode.UseResultDirectory;
+ ///
+ /// Is null if not set in runsettings.
+ ///
+ public string WorkDirectory { get; private set; }
+ public string Where { get; private set; }
+ public string TestOutputXml { get; private set; }
+ public string TestOutputXmlFileName { get; private set; }
+ public bool UseTestOutputXml => !string.IsNullOrEmpty(TestOutputXml) || OutputXmlFolderMode == OutputXmlFolderMode.UseResultDirectory;
- public OutputXmlFolderMode OutputXmlFolderMode { get; private set; } = OutputXmlFolderMode.RelativeToWorkFolder;
+ public OutputXmlFolderMode OutputXmlFolderMode { get; private set; } = OutputXmlFolderMode.RelativeToWorkFolder;
- ///
- /// Calculated property.
- ///
- public string TestOutputFolder { get; private set; } = "";
+ ///
+ /// Calculated property.
+ ///
+ public string TestOutputFolder { get; private set; } = "";
- public bool NewOutputXmlFileForEachRun { get; private set; }
- public int DefaultTimeout { get; private set; }
+ public bool NewOutputXmlFileForEachRun { get; private set; }
+ public int DefaultTimeout { get; private set; }
- public int NumberOfTestWorkers { get; private set; }
+ public int NumberOfTestWorkers { get; private set; }
- public bool ShadowCopyFiles { get; private set; }
+ public bool ShadowCopyFiles { get; private set; }
- public int Verbosity { get; private set; }
+ public int Verbosity { get; private set; }
- public bool UseVsKeepEngineRunning { get; private set; }
+ public bool UseVsKeepEngineRunning { get; private set; }
- public string BasePath { get; private set; }
+ public string BasePath { get; private set; }
- public string PrivateBinPath { get; private set; }
+ public string PrivateBinPath { get; private set; }
- public int? RandomSeed { get; private set; }
- public bool RandomSeedSpecified { get; private set; }
+ public int? RandomSeed { get; private set; }
+ public bool RandomSeedSpecified { get; private set; }
- public bool CollectDataForEachTestSeparately { get; private set; }
+ public bool CollectDataForEachTestSeparately { get; private set; }
- public bool InProcDataCollectorsAvailable { get; private set; }
+ public bool InProcDataCollectorsAvailable { get; private set; }
- public bool SynchronousEvents { get; private set; }
+ public bool SynchronousEvents { get; private set; }
- public string DomainUsage { get; private set; }
+ public string DomainUsage { get; private set; }
- public bool ShowInternalProperties { get; private set; }
- public bool UseParentFQNForParametrizedTests { get; private set; } // Default is false. True can fix certain test name patterns, but may have side effects.
- public bool UseNUnitIdforTestCaseId { get; private set; } // default is false.
- public int ConsoleOut { get; private set; }
- public bool StopOnError { get; private set; }
+ public bool ShowInternalProperties { get; private set; }
+ public bool UseParentFQNForParametrizedTests { get; private set; } // Default is false. True can fix certain test name patterns, but may have side effects.
+ public bool UseNUnitIdforTestCaseId { get; private set; } // default is false.
+ public int ConsoleOut { get; private set; }
+ public bool StopOnError { get; private set; }
- public DiscoveryMethod DiscoveryMethod { get; private set; } = DiscoveryMethod.Current;
- public bool SkipNonTestAssemblies { get; private set; }
- public int AssemblySelectLimit { get; private set; }
- public bool UseNUnitFilter { get; private set; }
- public bool IncludeStackTraceForSuites { get; private set; }
+ public DiscoveryMethod DiscoveryMethod { get; private set; } = DiscoveryMethod.Current;
+ public bool SkipNonTestAssemblies { get; private set; }
+ public int AssemblySelectLimit { get; private set; }
+ public bool UseNUnitFilter { get; private set; }
+ public bool IncludeStackTraceForSuites { get; private set; }
- public VsTestCategoryType VsTestCategoryType { get; private set; } = VsTestCategoryType.NUnit;
+ public VsTestCategoryType VsTestCategoryType { get; private set; } = VsTestCategoryType.NUnit;
- ///
- /// Syntax documentation .
- ///
- public string DefaultTestNamePattern { get; set; }
+ ///
+ /// Syntax documentation .
+ ///
+ public string DefaultTestNamePattern { get; set; }
- public bool PreFilter { get; private set; }
+ public bool PreFilter { get; private set; }
- public TestOutcome MapWarningTo { get; private set; }
+ public TestOutcome MapWarningTo { get; private set; }
- public bool UseTestNameInConsoleOutput { get; private set; }
+ public bool UseTestNameInConsoleOutput { get; private set; }
- public DisplayNameOptions DisplayName { get; private set; } = DisplayNameOptions.Name;
+ public DisplayNameOptions DisplayName { get; private set; } = DisplayNameOptions.Name;
- public char FullnameSeparator { get; private set; } = ':';
+ public char FullnameSeparator { get; private set; } = ':';
- public ExplicitModeEnum ExplicitMode { get; private set; } = ExplicitModeEnum.Strict;
- public bool SkipExecutionWhenNoTests { get; private set; }
+ public ExplicitModeEnum ExplicitMode { get; private set; } = ExplicitModeEnum.Strict;
+ public bool SkipExecutionWhenNoTests { get; private set; }
- #region NUnit Diagnostic properties
- public bool DumpXmlTestDiscovery { get; private set; }
+ #region NUnit Diagnostic properties
+ public bool DumpXmlTestDiscovery { get; private set; }
- public bool DumpXmlTestResults { get; private set; }
+ public bool DumpXmlTestResults { get; private set; }
- public bool DumpVsInput { get; private set; }
+ public bool DumpVsInput { get; private set; }
- public bool FreakMode { get; private set; }
- public bool Debug { get; private set; }
- public bool DebugExecution { get; private set; }
- public bool DebugDiscovery { get; private set; }
+ public bool FreakMode { get; private set; }
+ public bool Debug { get; private set; }
+ public bool DebugExecution { get; private set; }
+ public bool DebugDiscovery { get; private set; }
- #endregion
+ #endregion
- #endregion
+ #endregion
- #region Public Methods
+ #region Public Methods
- ///
- /// Initialized by the Load method.
- ///
- private TestLogger testLog;
+ ///
+ /// Initialized by the Load method.
+ ///
+ private TestLogger testLog;
- public void Load(IDiscoveryContext context, TestLogger testLogger)
- {
- testLog = testLogger;
- if (context == null)
- throw new ArgumentNullException(nameof(context), "Load called with null context");
+ public void Load(IDiscoveryContext context, TestLogger testLogger)
+ {
+ testLog = testLogger;
+ if (context == null)
+ throw new ArgumentNullException(nameof(context), "Load called with null context");
- Load(context.RunSettings?.SettingsXml);
- }
+ Load(context.RunSettings?.SettingsXml);
+ }
- public void Load(string settingsXml)
+ public void Load(string settingsXml)
+ {
+ if (string.IsNullOrEmpty(settingsXml))
+ settingsXml = "";
+
+ // Visual Studio already gives a good error message if the .runsettings
+ // file is poorly formed, so we don't need to do anything more.
+ var doc = new XmlDocument();
+ doc.LoadXml(settingsXml);
+
+ var nunitNode = doc.SelectSingleNode("RunSettings/NUnit");
+ Verbosity = GetInnerTextAsInt(nunitNode, nameof(Verbosity), 0);
+ logger.Verbosity = Verbosity;
+
+ ExtractRunConfiguration(doc);
+
+ UpdateTestProperties(doc);
+
+ // NUnit settings
+ WorkDirectory = GetInnerTextWithLog(nunitNode, nameof(WorkDirectory));
+ Where = GetInnerTextWithLog(nunitNode, nameof(Where));
+ DefaultTimeout = GetInnerTextAsInt(nunitNode, nameof(DefaultTimeout), 0);
+ NumberOfTestWorkers = GetInnerTextAsInt(nunitNode, nameof(NumberOfTestWorkers), -1);
+ ShadowCopyFiles = GetInnerTextAsBool(nunitNode, nameof(ShadowCopyFiles), false);
+ UseVsKeepEngineRunning = GetInnerTextAsBool(nunitNode, nameof(UseVsKeepEngineRunning), false);
+ BasePath = GetInnerTextWithLog(nunitNode, nameof(BasePath));
+ PrivateBinPath = GetInnerTextWithLog(nunitNode, nameof(PrivateBinPath));
+ ParseOutputXml(nunitNode);
+ NewOutputXmlFileForEachRun = GetInnerTextAsBool(nunitNode, nameof(NewOutputXmlFileForEachRun), false);
+
+ RandomSeed = GetInnerTextAsNullableInt(nunitNode, nameof(RandomSeed));
+ RandomSeedSpecified = RandomSeed.HasValue;
+ if (!RandomSeedSpecified)
+ RandomSeed = new Random().Next();
+ DefaultTestNamePattern = GetInnerTextWithLog(nunitNode, nameof(DefaultTestNamePattern));
+ ShowInternalProperties = GetInnerTextAsBool(nunitNode, nameof(ShowInternalProperties), false);
+ UseParentFQNForParametrizedTests = GetInnerTextAsBool(nunitNode, nameof(UseParentFQNForParametrizedTests), false);
+ UseNUnitIdforTestCaseId = GetInnerTextAsBool(nunitNode, nameof(UseNUnitIdforTestCaseId), false);
+ ConsoleOut = GetInnerTextAsInt(nunitNode, nameof(ConsoleOut), 1); // 0 no output to console, 1 : output to console, 2: output to console as warnings
+ StopOnError = GetInnerTextAsBool(nunitNode, nameof(StopOnError), false);
+ UseNUnitFilter = GetInnerTextAsBool(nunitNode, nameof(UseNUnitFilter), true);
+ IncludeStackTraceForSuites = GetInnerTextAsBool(nunitNode, nameof(IncludeStackTraceForSuites), true);
+ EnsureAttachmentFileScheme = GetInnerTextAsBool(nunitNode, nameof(EnsureAttachmentFileScheme), false);
+ SkipExecutionWhenNoTests = GetInnerTextAsBool(nunitNode, nameof(SkipExecutionWhenNoTests), false);
+
+ // Engine settings
+ DiscoveryMethod = MapEnum(GetInnerText(nunitNode, nameof(DiscoveryMethod), Verbosity > 0), DiscoveryMethod.Current);
+ SkipNonTestAssemblies = GetInnerTextAsBool(nunitNode, nameof(SkipNonTestAssemblies), true);
+ AssemblySelectLimit = GetInnerTextAsInt(nunitNode, nameof(AssemblySelectLimit), 2000);
+
+
+ ExplicitMode = MapEnum(GetInnerText(nunitNode, nameof(ExplicitMode), Verbosity > 0), ExplicitModeEnum.Strict);
+
+
+ ExtractNUnitDiagnosticSettings(nunitNode);
+
+ // Adapter Display Options
+ MapDisplayName(GetInnerText(nunitNode, nameof(DisplayName), Verbosity > 0));
+ FullnameSeparator = GetInnerText(nunitNode, nameof(FullnameSeparator), Verbosity > 0)?[0] ?? ':';
+
+ // EndDisplay
+
+ PreFilter = GetInnerTextAsBool(nunitNode, nameof(PreFilter), false);
+ MapTestCategory(GetInnerText(nunitNode, nameof(VsTestCategoryType), Verbosity > 0));
+ MapWarningTo = MapWarningOutcome(GetInnerText(nunitNode, nameof(MapWarningTo), Verbosity > 0));
+ UseTestNameInConsoleOutput = GetInnerTextAsBool(nunitNode, nameof(UseTestNameInConsoleOutput), false);
+ var inProcDataCollectorNode =
+ doc.SelectSingleNode("RunSettings/InProcDataCollectionRunSettings/InProcDataCollectors");
+ InProcDataCollectorsAvailable = inProcDataCollectorNode != null &&
+ inProcDataCollectorNode.SelectNodes("InProcDataCollector")?.Count > 0;
+
+ // Older versions of VS do not pass the CollectDataForEachTestSeparately configuration together with the LiveUnitTesting collector.
+ // However, the adapter is expected to run in CollectDataForEachTestSeparately mode.
+ // As a result for backwards compatibility reasons enable CollectDataForEachTestSeparately mode whenever LiveUnitTesting collector is being used.
+ var hasLiveUnitTestingDataCollector =
+ inProcDataCollectorNode?.SelectSingleNode(
+ "InProcDataCollector[@uri='InProcDataCollector://Microsoft/LiveUnitTesting/1.0']") != null;
+
+ // TestPlatform can choose to opt in to run tests one at a time so that the InProcDataCollectors can collect the data for each one of them separately.
+ // In that case, we need to ensure that tests do not run in parallel and the test started/test ended events are sent synchronously.
+ if (CollectDataForEachTestSeparately || hasLiveUnitTestingDataCollector)
{
- if (string.IsNullOrEmpty(settingsXml))
- settingsXml = "";
-
- // Visual Studio already gives a good error message if the .runsettings
- // file is poorly formed, so we don't need to do anything more.
- var doc = new XmlDocument();
- doc.LoadXml(settingsXml);
-
- var nunitNode = doc.SelectSingleNode("RunSettings/NUnit");
- Verbosity = GetInnerTextAsInt(nunitNode, nameof(Verbosity), 0);
- _logger.Verbosity = Verbosity;
-
- ExtractRunConfiguration(doc);
-
- UpdateTestProperties(doc);
-
- // NUnit settings
- WorkDirectory = GetInnerTextWithLog(nunitNode, nameof(WorkDirectory));
- Where = GetInnerTextWithLog(nunitNode, nameof(Where));
- DefaultTimeout = GetInnerTextAsInt(nunitNode, nameof(DefaultTimeout), 0);
- NumberOfTestWorkers = GetInnerTextAsInt(nunitNode, nameof(NumberOfTestWorkers), -1);
- ShadowCopyFiles = GetInnerTextAsBool(nunitNode, nameof(ShadowCopyFiles), false);
- UseVsKeepEngineRunning = GetInnerTextAsBool(nunitNode, nameof(UseVsKeepEngineRunning), false);
- BasePath = GetInnerTextWithLog(nunitNode, nameof(BasePath));
- PrivateBinPath = GetInnerTextWithLog(nunitNode, nameof(PrivateBinPath));
- ParseOutputXml(nunitNode);
- NewOutputXmlFileForEachRun = GetInnerTextAsBool(nunitNode, nameof(NewOutputXmlFileForEachRun), false);
-
- RandomSeed = GetInnerTextAsNullableInt(nunitNode, nameof(RandomSeed));
- RandomSeedSpecified = RandomSeed.HasValue;
- if (!RandomSeedSpecified)
- RandomSeed = new Random().Next();
- DefaultTestNamePattern = GetInnerTextWithLog(nunitNode, nameof(DefaultTestNamePattern));
- ShowInternalProperties = GetInnerTextAsBool(nunitNode, nameof(ShowInternalProperties), false);
- UseParentFQNForParametrizedTests = GetInnerTextAsBool(nunitNode, nameof(UseParentFQNForParametrizedTests), false);
- UseNUnitIdforTestCaseId = GetInnerTextAsBool(nunitNode, nameof(UseNUnitIdforTestCaseId), false);
- ConsoleOut = GetInnerTextAsInt(nunitNode, nameof(ConsoleOut), 1); // 0 no output to console, 1 : output to console, 2: output to console as warnings
- StopOnError = GetInnerTextAsBool(nunitNode, nameof(StopOnError), false);
- UseNUnitFilter = GetInnerTextAsBool(nunitNode, nameof(UseNUnitFilter), true);
- IncludeStackTraceForSuites = GetInnerTextAsBool(nunitNode, nameof(IncludeStackTraceForSuites), true);
- EnsureAttachmentFileScheme = GetInnerTextAsBool(nunitNode, nameof(EnsureAttachmentFileScheme), false);
- SkipExecutionWhenNoTests = GetInnerTextAsBool(nunitNode, nameof(SkipExecutionWhenNoTests), false);
-
- // Engine settings
- DiscoveryMethod = MapEnum(GetInnerText(nunitNode, nameof(DiscoveryMethod), Verbosity > 0), DiscoveryMethod.Current);
- SkipNonTestAssemblies = GetInnerTextAsBool(nunitNode, nameof(SkipNonTestAssemblies), true);
- AssemblySelectLimit = GetInnerTextAsInt(nunitNode, nameof(AssemblySelectLimit), 2000);
-
-
- ExplicitMode = MapEnum(GetInnerText(nunitNode, nameof(ExplicitMode), Verbosity > 0), ExplicitModeEnum.Strict);
-
-
- ExtractNUnitDiagnosticSettings(nunitNode);
-
- // Adapter Display Options
- MapDisplayName(GetInnerText(nunitNode, nameof(DisplayName), Verbosity > 0));
- FullnameSeparator = GetInnerText(nunitNode, nameof(FullnameSeparator), Verbosity > 0)?[0] ?? ':';
-
- // EndDisplay
-
- PreFilter = GetInnerTextAsBool(nunitNode, nameof(PreFilter), false);
- MapTestCategory(GetInnerText(nunitNode, nameof(VsTestCategoryType), Verbosity > 0));
- MapWarningTo = MapWarningOutcome(GetInnerText(nunitNode, nameof(MapWarningTo), Verbosity > 0));
- UseTestNameInConsoleOutput = GetInnerTextAsBool(nunitNode, nameof(UseTestNameInConsoleOutput), false);
- var inProcDataCollectorNode =
- doc.SelectSingleNode("RunSettings/InProcDataCollectionRunSettings/InProcDataCollectors");
- InProcDataCollectorsAvailable = inProcDataCollectorNode != null &&
- inProcDataCollectorNode.SelectNodes("InProcDataCollector")?.Count > 0;
-
- // Older versions of VS do not pass the CollectDataForEachTestSeparately configuration together with the LiveUnitTesting collector.
- // However, the adapter is expected to run in CollectDataForEachTestSeparately mode.
- // As a result for backwards compatibility reasons enable CollectDataForEachTestSeparately mode whenever LiveUnitTesting collector is being used.
- var hasLiveUnitTestingDataCollector =
- inProcDataCollectorNode?.SelectSingleNode(
- "InProcDataCollector[@uri='InProcDataCollector://Microsoft/LiveUnitTesting/1.0']") != null;
-
- // TestPlatform can opt-in to run tests one at a time so that the InProcDataCollectors can collect the data for each one of them separately.
- // In that case, we need to ensure that tests do not run in parallel and the test started/test ended events are sent synchronously.
- if (CollectDataForEachTestSeparately || hasLiveUnitTestingDataCollector)
+ NumberOfTestWorkers = 0;
+ SynchronousEvents = true;
+ if (Verbosity >= 4)
{
- NumberOfTestWorkers = 0;
- SynchronousEvents = true;
- if (Verbosity >= 4)
+ if (!InProcDataCollectorsAvailable)
{
- if (!InProcDataCollectorsAvailable)
- {
- _logger.Info(
- "CollectDataForEachTestSeparately is set, which is used to make InProcDataCollectors collect data for each test separately. No InProcDataCollectors can be found, thus the tests will run slower unnecessarily.");
- }
+ logger.Info(
+ "CollectDataForEachTestSeparately is set, which is used to make InProcDataCollectors collect data for each test separately. No InProcDataCollectors can be found, thus the tests will run slower unnecessarily.");
}
}
-
- // If DisableAppDomain settings is passed from the testplatform, set the DomainUsage to None.
- if (DisableAppDomain)
- {
- DomainUsage = "None";
- }
-
- // Update NumberOfTestWorkers based on the DisableParallelization and NumberOfTestWorkers from runsettings.
- UpdateNumberOfTestWorkers();
}
- private void ParseOutputXml(XmlNode nunitNode)
+ // If DisableAppDomain settings is passed from the testplatform, set the DomainUsage to None.
+ if (DisableAppDomain)
{
- TestOutputXml = GetInnerTextWithLog(nunitNode, nameof(TestOutputXml));
- TestOutputXmlFileName = GetInnerTextWithLog(nunitNode, nameof(TestOutputXmlFileName));
- if (Path.IsPathRooted(TestOutputXml))
- {
- OutputXmlFolderMode = OutputXmlFolderMode.AsSpecified;
- return;
- }
- var outputMode = GetInnerText(nunitNode, nameof(OutputXmlFolderMode), Verbosity > 0);
-
- if (string.IsNullOrEmpty(WorkDirectory) && string.IsNullOrEmpty(outputMode))
- {
- OutputXmlFolderMode = string.IsNullOrEmpty(TestOutputXml) ? OutputXmlFolderMode.UseResultDirectory : OutputXmlFolderMode.RelativeToResultDirectory;
- }
-
- OutputXmlFolderMode = MapEnum(outputMode, OutputXmlFolderMode.RelativeToWorkFolder);
+ DomainUsage = "None";
}
- public string SetTestOutputFolder(string workDirectory)
+ // Update NumberOfTestWorkers based on the DisableParallelization and NumberOfTestWorkers from runsettings.
+ UpdateNumberOfTestWorkers();
+ }
+
+ private void ParseOutputXml(XmlNode nunitNode)
+ {
+ TestOutputXml = GetInnerTextWithLog(nunitNode, nameof(TestOutputXml));
+ TestOutputXmlFileName = GetInnerTextWithLog(nunitNode, nameof(TestOutputXmlFileName));
+ if (Path.IsPathRooted(TestOutputXml))
{
- if (!UseTestOutputXml)
- return "";
- switch (OutputXmlFolderMode)
- {
- case OutputXmlFolderMode.UseResultDirectory:
- TestOutputFolder = ResultsDirectory;
- return TestOutputFolder;
- case OutputXmlFolderMode.RelativeToResultDirectory:
- TestOutputFolder = Path.Combine(ResultsDirectory, TestOutputXml);
- return TestOutputFolder;
- case OutputXmlFolderMode.RelativeToWorkFolder:
- TestOutputFolder = Path.Combine(workDirectory, TestOutputXml);
- return TestOutputFolder;
- case OutputXmlFolderMode.AsSpecified:
- TestOutputFolder = TestOutputXml;
- return TestOutputFolder;
- default:
- return "";
- }
+ OutputXmlFolderMode = OutputXmlFolderMode.AsSpecified;
+ return;
}
+ var outputMode = GetInnerText(nunitNode, nameof(OutputXmlFolderMode), Verbosity > 0);
- private void ExtractNUnitDiagnosticSettings(XmlNode nunitNode)
+ if (string.IsNullOrEmpty(WorkDirectory) && string.IsNullOrEmpty(outputMode))
{
- DumpXmlTestDiscovery = GetInnerTextAsBool(nunitNode, nameof(DumpXmlTestDiscovery), false);
- DumpXmlTestResults = GetInnerTextAsBool(nunitNode, nameof(DumpXmlTestResults), false);
- DumpVsInput = GetInnerTextAsBool(nunitNode, nameof(DumpVsInput), false);
- FreakMode = GetInnerTextAsBool(nunitNode, nameof(FreakMode), false);
- InternalTraceLevel = GetInnerTextWithLog(nunitNode, nameof(InternalTraceLevel), "Off", "Error", "Warning", "Info", "Verbose", "Debug");
- InternalTraceLevelEnum = ParseInternalTraceLevel(InternalTraceLevel);
- Debug = GetInnerTextAsBool(nunitNode, nameof(Debug), false);
- DebugExecution = Debug || GetInnerTextAsBool(nunitNode, nameof(DebugExecution), false);
- DebugDiscovery = Debug || GetInnerTextAsBool(nunitNode, nameof(DebugDiscovery), false);
+ OutputXmlFolderMode = string.IsNullOrEmpty(TestOutputXml) ? OutputXmlFolderMode.UseResultDirectory : OutputXmlFolderMode.RelativeToResultDirectory;
}
- private InternalTraceLevel ParseInternalTraceLevel(string s)
- {
- if (s == null)
- {
- return Engine.InternalTraceLevel.Off;
- }
+ OutputXmlFolderMode = MapEnum(outputMode, OutputXmlFolderMode.RelativeToWorkFolder);
+ }
- try
- {
- var internalTrace = (InternalTraceLevel)Enum.Parse(typeof(InternalTraceLevel), s);
- return internalTrace;
- }
- catch
- {
- testLog.Warning($"InternalTraceLevel is non-valid: {s}, see https://docs.nunit.org/articles/vs-test-adapter/Tips-And-Tricks.html");
- return Engine.InternalTraceLevel.Off;
- }
+ public string SetTestOutputFolder(string workDirectory)
+ {
+ if (!UseTestOutputXml)
+ return "";
+ switch (OutputXmlFolderMode)
+ {
+ case OutputXmlFolderMode.UseResultDirectory:
+ TestOutputFolder = ResultsDirectory;
+ return TestOutputFolder;
+ case OutputXmlFolderMode.RelativeToResultDirectory:
+ TestOutputFolder = Path.Combine(ResultsDirectory, TestOutputXml);
+ return TestOutputFolder;
+ case OutputXmlFolderMode.RelativeToWorkFolder:
+ TestOutputFolder = Path.Combine(workDirectory, TestOutputXml);
+ return TestOutputFolder;
+ case OutputXmlFolderMode.AsSpecified:
+ TestOutputFolder = TestOutputXml;
+ return TestOutputFolder;
+ default:
+ return "";
}
+ }
+
+ private void ExtractNUnitDiagnosticSettings(XmlNode nunitNode)
+ {
+ DumpXmlTestDiscovery = GetInnerTextAsBool(nunitNode, nameof(DumpXmlTestDiscovery), false);
+ DumpXmlTestResults = GetInnerTextAsBool(nunitNode, nameof(DumpXmlTestResults), false);
+ DumpVsInput = GetInnerTextAsBool(nunitNode, nameof(DumpVsInput), false);
+ FreakMode = GetInnerTextAsBool(nunitNode, nameof(FreakMode), false);
+ InternalTraceLevel = GetInnerTextWithLog(nunitNode, nameof(InternalTraceLevel), "Off", "Error", "Warning", "Info", "Verbose", "Debug");
+ InternalTraceLevelEnum = ParseInternalTraceLevel(InternalTraceLevel);
+ Debug = GetInnerTextAsBool(nunitNode, nameof(Debug), false);
+ DebugExecution = Debug || GetInnerTextAsBool(nunitNode, nameof(DebugExecution), false);
+ DebugDiscovery = Debug || GetInnerTextAsBool(nunitNode, nameof(DebugDiscovery), false);
+ }
- private void UpdateTestProperties(XmlDocument doc)
+ private InternalTraceLevel ParseInternalTraceLevel(string s)
+ {
+ if (s == null)
{
- TestProperties = new Dictionary();
- foreach (XmlNode node in doc.SelectNodes("RunSettings/TestRunParameters/Parameter"))
- {
- var key = node.GetAttribute("name");
- var value = node.GetAttribute("value");
- if (key != null && value != null)
- TestProperties.Add(key, value);
- }
+ return Engine.InternalTraceLevel.Off;
}
- private void ExtractRunConfiguration(XmlDocument doc)
+ try
{
- var runConfiguration = doc.SelectSingleNode("RunSettings/RunConfiguration");
- MaxCpuCount = GetInnerTextAsInt(runConfiguration, nameof(MaxCpuCount), -1);
- ResultsDirectory = GetInnerTextWithLog(runConfiguration, nameof(ResultsDirectory));
- TargetPlatform = GetInnerTextWithLog(runConfiguration, nameof(TargetPlatform));
- TargetFrameworkVersion = GetInnerTextWithLog(runConfiguration, nameof(TargetFrameworkVersion));
- TestAdapterPaths = GetInnerTextWithLog(runConfiguration, nameof(TestAdapterPaths));
- CollectSourceInformation = GetInnerTextAsBool(runConfiguration, nameof(CollectSourceInformation), true);
- DisableAppDomain = GetInnerTextAsBool(runConfiguration, nameof(DisableAppDomain), false);
- DisableParallelization = GetInnerTextAsBool(runConfiguration, nameof(DisableParallelization), false);
- AllowParallelWithDebugger = GetInnerTextAsBool(runConfiguration, nameof(AllowParallelWithDebugger), false);
- DesignMode = GetInnerTextAsBool(runConfiguration, nameof(DesignMode), false);
- CollectDataForEachTestSeparately =
- GetInnerTextAsBool(runConfiguration, nameof(CollectDataForEachTestSeparately), false);
+ var internalTrace = (InternalTraceLevel)Enum.Parse(typeof(InternalTraceLevel), s);
+ return internalTrace;
}
-
- private void MapTestCategory(string vsTestCategoryType)
+ catch
{
- if (vsTestCategoryType == null)
- return;
- var ok = TryParse.EnumTryParse(vsTestCategoryType, out VsTestCategoryType result);
- if (ok)
- VsTestCategoryType = result;
- else
- _logger.Warning($"Invalid value ({vsTestCategoryType}) for VsTestCategoryType, should be either NUnit or MsTest");
+ testLog.Warning($"InternalTraceLevel is non-valid: {s}, see https://docs.nunit.org/articles/vs-test-adapter/Tips-And-Tricks.html");
+ return Engine.InternalTraceLevel.Off;
}
+ }
- private void MapDisplayName(string displaynameoptions)
+ private void UpdateTestProperties(XmlDocument doc)
+ {
+ TestProperties = new Dictionary();
+ foreach (XmlNode node in doc.SelectNodes("RunSettings/TestRunParameters/Parameter"))
{
- if (displaynameoptions == null)
- return;
- var ok = TryParse.EnumTryParse(displaynameoptions, out DisplayNameOptions result);
- if (ok)
- DisplayName = result;
- else
- _logger.Warning($"Invalid value ({displaynameoptions}) for DisplayNameOptions, should be either Name, Fullname or FullnameSep");
+ var key = node.GetAttribute("name");
+ var value = node.GetAttribute("value");
+ if (key != null && value != null)
+ TestProperties.Add(key, value);
}
+ }
+ private void ExtractRunConfiguration(XmlDocument doc)
+ {
+ var runConfiguration = doc.SelectSingleNode("RunSettings/RunConfiguration");
+ MaxCpuCount = GetInnerTextAsInt(runConfiguration, nameof(MaxCpuCount), -1);
+ ResultsDirectory = GetInnerTextWithLog(runConfiguration, nameof(ResultsDirectory));
+ TargetPlatform = GetInnerTextWithLog(runConfiguration, nameof(TargetPlatform));
+ TargetFrameworkVersion = GetInnerTextWithLog(runConfiguration, nameof(TargetFrameworkVersion));
+ TestAdapterPaths = GetInnerTextWithLog(runConfiguration, nameof(TestAdapterPaths));
+ CollectSourceInformation = GetInnerTextAsBool(runConfiguration, nameof(CollectSourceInformation), true);
+ DisableAppDomain = GetInnerTextAsBool(runConfiguration, nameof(DisableAppDomain), false);
+ DisableParallelization = GetInnerTextAsBool(runConfiguration, nameof(DisableParallelization), false);
+ AllowParallelWithDebugger = GetInnerTextAsBool(runConfiguration, nameof(AllowParallelWithDebugger), false);
+ DesignMode = GetInnerTextAsBool(runConfiguration, nameof(DesignMode), false);
+ CollectDataForEachTestSeparately =
+ GetInnerTextAsBool(runConfiguration, nameof(CollectDataForEachTestSeparately), false);
+ }
- public void SaveRandomSeed(string dirname)
+ private void MapTestCategory(string vsTestCategoryType)
+ {
+ if (vsTestCategoryType == null)
+ return;
+ var ok = TryParse.EnumTryParse(vsTestCategoryType, out VsTestCategoryType result);
+ if (ok)
+ VsTestCategoryType = result;
+ else
+ logger.Warning($"Invalid value ({vsTestCategoryType}) for VsTestCategoryType, should be either NUnit or MsTest");
+ }
+
+ private void MapDisplayName(string displaynameoptions)
+ {
+ if (displaynameoptions == null)
+ return;
+ var ok = TryParse.EnumTryParse(displaynameoptions, out DisplayNameOptions result);
+ if (ok)
+ DisplayName = result;
+ else
+ logger.Warning($"Invalid value ({displaynameoptions}) for DisplayNameOptions, should be either Name, Fullname or FullnameSep");
+ }
+
+
+ public void SaveRandomSeed(string dirname)
+ {
+ try
{
- try
- {
- var path = Path.Combine(dirname, RANDOM_SEED_FILE);
- File.WriteAllText(path, RandomSeed.Value.ToString());
- }
- catch (Exception ex)
- {
- _logger.Warning("Failed to save random seed.", ex);
- }
+ var path = Path.Combine(dirname, RandomSeedFile);
+ File.WriteAllText(path, RandomSeed.Value.ToString());
}
+ catch (Exception ex)
+ {
+ logger.Warning("Failed to save random seed.", ex);
+ }
+ }
- public void RestoreRandomSeed(string dirname)
+ public void RestoreRandomSeed(string dirname)
+ {
+ var fullPath = Path.Combine(dirname, RandomSeedFile);
+ if (!File.Exists(fullPath))
+ return;
+ try
{
- var fullPath = Path.Combine(dirname, RANDOM_SEED_FILE);
- if (!File.Exists(fullPath))
- return;
- try
- {
- var value = File.ReadAllText(fullPath);
- RandomSeed = int.Parse(value);
- }
- catch (Exception ex)
- {
- _logger.Warning("Unable to restore random seed.", ex);
- }
+ var value = File.ReadAllText(fullPath);
+ RandomSeed = int.Parse(value);
+ }
+ catch (Exception ex)
+ {
+ logger.Warning("Unable to restore random seed.", ex);
}
+ }
- public bool EnsureAttachmentFileScheme { get; private set; }
+ public bool EnsureAttachmentFileScheme { get; private set; }
- #endregion
+ #endregion
- #region Helper Methods
+ #region Helper Methods
- private void UpdateNumberOfTestWorkers()
+ private void UpdateNumberOfTestWorkers()
+ {
+ // Overriding the NumberOfTestWorkers if DisableParallelization is true.
+ if (DisableParallelization && NumberOfTestWorkers < 0)
{
- // Overriding the NumberOfTestWorkers if DisableParallelization is true.
- if (DisableParallelization && NumberOfTestWorkers < 0)
- {
- NumberOfTestWorkers = 0;
- }
- else if (DisableParallelization && NumberOfTestWorkers > 0)
+ NumberOfTestWorkers = 0;
+ }
+ else if (DisableParallelization && NumberOfTestWorkers > 0)
+ {
+ if (logger.Verbosity > 0)
{
- if (_logger.Verbosity > 0)
- {
- _logger.Warning(
- $"DisableParallelization:{DisableParallelization} & NumberOfTestWorkers:{NumberOfTestWorkers} are conflicting settings, hence not running in parallel");
- }
- NumberOfTestWorkers = 0;
+ logger.Warning(
+ $"DisableParallelization:{DisableParallelization} & NumberOfTestWorkers:{NumberOfTestWorkers} are conflicting settings, hence not running in parallel");
}
+ NumberOfTestWorkers = 0;
}
+ }
- private string GetInnerTextWithLog(XmlNode startNode, string xpath, params string[] validValues)
- {
- return GetInnerText(startNode, xpath, true, validValues);
- }
+ private string GetInnerTextWithLog(XmlNode startNode, string xpath, params string[] validValues)
+ {
+ return GetInnerText(startNode, xpath, true, validValues);
+ }
- private string GetInnerText(XmlNode startNode, string xpath, bool log, params string[] validValues)
+ private string GetInnerText(XmlNode startNode, string xpath, bool log, params string[] validValues)
+ {
+ string val = null;
+ var targetNode = startNode?.SelectSingleNode(xpath);
+ if (targetNode != null)
{
- string val = null;
- var targetNode = startNode?.SelectSingleNode(xpath);
- if (targetNode != null)
- {
- val = targetNode.InnerText;
+ val = targetNode.InnerText;
- if (validValues is { Length: > 0 })
+ if (validValues is { Length: > 0 })
+ {
+ foreach (string valid in validValues)
{
- foreach (string valid in validValues)
- {
- if (string.Compare(valid, val, StringComparison.OrdinalIgnoreCase) == 0)
- return valid;
- }
-
- throw new ArgumentException($"Invalid value {val} passed for element {xpath}.");
+ if (string.Compare(valid, val, StringComparison.OrdinalIgnoreCase) == 0)
+ return valid;
}
- }
- if (log)
- Log(xpath, val);
- return val;
+ throw new ArgumentException($"Invalid value {val} passed for element {xpath}.");
+ }
}
+ if (log)
+ Log(xpath, val);
- private int GetInnerTextAsInt(XmlNode startNode, string xpath, int defaultValue)
- {
- var temp = GetInnerTextAsNullableInt(startNode, xpath, false);
- int res = defaultValue;
- if (temp != null)
- res = temp.Value;
- Log(xpath, res);
- return res;
- }
+ return val;
+ }
- private int? GetInnerTextAsNullableInt(XmlNode startNode, string xpath, bool log = true)
- {
- string temp = GetInnerText(startNode, xpath, log);
- int? res = null;
- if (!string.IsNullOrEmpty(temp))
- res = int.Parse(temp);
- Log(xpath, res);
- return res;
- }
+ private int GetInnerTextAsInt(XmlNode startNode, string xpath, int defaultValue)
+ {
+ var temp = GetInnerTextAsNullableInt(startNode, xpath, false);
+ int res = defaultValue;
+ if (temp != null)
+ res = temp.Value;
+ Log(xpath, res);
+ return res;
+ }
- private bool GetInnerTextAsBool(XmlNode startNode, string xpath, bool defaultValue)
- {
- string temp = GetInnerText(startNode, xpath, false);
- bool res = defaultValue;
- if (!string.IsNullOrEmpty(temp))
- res = bool.Parse(temp);
- Log(xpath, res);
- return res;
- }
+ private int? GetInnerTextAsNullableInt(XmlNode startNode, string xpath, bool log = true)
+ {
+ string temp = GetInnerText(startNode, xpath, log);
+ int? res = null;
+ if (!string.IsNullOrEmpty(temp))
+ res = int.Parse(temp);
+ Log(xpath, res);
+ return res;
+ }
- private void Log(string xpath, T res)
+ private bool GetInnerTextAsBool(XmlNode startNode, string xpath, bool defaultValue)
+ {
+ string temp = GetInnerText(startNode, xpath, false);
+ bool res = defaultValue;
+ if (!string.IsNullOrEmpty(temp))
+ res = bool.Parse(temp);
+ Log(xpath, res);
+ return res;
+ }
+
+ private void Log(string xpath, T res)
+ {
+ if (Verbosity >= 4)
{
- if (Verbosity >= 4)
- {
- _logger.Info($"Setting: {xpath} = {res}");
- }
+ logger.Info($"Setting: {xpath} = {res}");
}
+ }
- public TestOutcome MapWarningOutcome(string outcome)
- {
- if (outcome == null)
- return TestOutcome.Skipped;
+ public TestOutcome MapWarningOutcome(string outcome)
+ {
+ if (outcome == null)
+ return TestOutcome.Skipped;
- bool ok = TryParse.EnumTryParse(outcome, out TestOutcome testoutcome);
+ bool ok = TryParse.EnumTryParse(outcome, out TestOutcome testoutcome);
- if (!ok)
- {
- _logger.Warning(
- $"Invalid value ({outcome}) for MapWarningTo, should be either Skipped,Failed,Passed or None");
- return TestOutcome.Skipped;
- }
- return testoutcome;
+ if (!ok)
+ {
+ logger.Warning(
+ $"Invalid value ({outcome}) for MapWarningTo, should be either Skipped,Failed,Passed or None");
+ return TestOutcome.Skipped;
}
+ return testoutcome;
+ }
- public T MapEnum(string setting, T defaultValue)
- where T : struct, Enum
+ public T MapEnum(string setting, T defaultValue)
+ where T : struct, Enum
+ {
+ if (setting == null)
+ return defaultValue;
+ bool ok = TryParse.EnumTryParse(setting, out T result);
+ if (!ok)
{
- if (setting == null)
- return defaultValue;
- bool ok = TryParse.EnumTryParse(setting, out T result);
- if (!ok)
- {
- _logger.Warning(
- $"Invalid value ({setting}) for {typeof(T)}");
- return defaultValue;
- }
- return result;
+ logger.Warning(
+ $"Invalid value ({setting}) for {typeof(T)}");
+ return defaultValue;
}
+ return result;
+ }
- #endregion
- }
+ #endregion
+}
- public enum ExplicitModeEnum
- {
- Strict,
- Relaxed,
- None
- }
+public enum ExplicitModeEnum
+{
+ Strict,
+ Relaxed,
+ None
+}
- public enum OutputXmlFolderMode
- {
- UseResultDirectory,
- RelativeToResultDirectory,
- RelativeToWorkFolder,
- AsSpecified
- }
+public enum OutputXmlFolderMode
+{
+ UseResultDirectory,
+ RelativeToResultDirectory,
+ RelativeToWorkFolder,
+ AsSpecified
}
\ No newline at end of file
diff --git a/src/NUnitTestAdapter/CategoryList.cs b/src/NUnitTestAdapter/CategoryList.cs
index 97036b5b..7e31107a 100644
--- a/src/NUnitTestAdapter/CategoryList.cs
+++ b/src/NUnitTestAdapter/CategoryList.cs
@@ -26,148 +26,147 @@
using Microsoft.VisualStudio.TestPlatform.ObjectModel;
using NUnit.VisualStudio.TestAdapter.NUnitEngine;
-namespace NUnit.VisualStudio.TestAdapter
+namespace NUnit.VisualStudio.TestAdapter;
+
+public class CategoryList
{
- public class CategoryList
- {
- private const string NUnitTestCategoryLabel = "Category";
-
- internal static readonly TestProperty NUnitTestCategoryProperty = TestProperty.Register(
- id: "NUnit.TestCategory",
- // This label is what causes VSTest to include the values in the Test Categories column and show the
- // grouping as `X` rather than `Category [X]`. (https://github.com/nunit/nunit3-vs-adapter/issues/310)
- label: "TestCategory",
- valueType: typeof(string[]),
- TestPropertyAttributes.Hidden
+ private const string NUnitTestCategoryLabel = "Category";
+
+ internal static readonly TestProperty NUnitTestCategoryProperty = TestProperty.Register(
+ id: "NUnit.TestCategory",
+ // This label is what causes VSTest to include the values in the Test Categories column and show the
+ // grouping as `X` rather than `Category [X]`. (https://github.com/nunit/nunit3-vs-adapter/issues/310)
+ label: "TestCategory",
+ valueType: typeof(string[]),
+ TestPropertyAttributes.Hidden
#pragma warning disable CS0618 // This is the only way to fix https://github.com/nunit/nunit3-vs-adapter/issues/310, and MSTest also depends on this.
- | TestPropertyAttributes.Trait,
+ | TestPropertyAttributes.Trait,
#pragma warning restore CS0618
- owner: typeof(TestCase));
+ owner: typeof(TestCase));
- internal static readonly TestProperty NUnitExplicitProperty = TestProperty.Register(
- "NUnit.Explicit",
- "Explicit", typeof(bool), TestPropertyAttributes.Hidden, typeof(TestCase));
+ internal static readonly TestProperty NUnitExplicitProperty = TestProperty.Register(
+ "NUnit.Explicit",
+ "Explicit", typeof(bool), TestPropertyAttributes.Hidden, typeof(TestCase));
- private const string ExplicitTraitName = "Explicit";
+ private const string ExplicitTraitName = "Explicit";
- // The empty string causes the UI we want.
- // If it's null, the explicit trait doesn't show up in Test Explorer.
- // If it's not empty, it shows up as “Explicit [value]” in Test Explorer.
- private const string ExplicitTraitValue = "";
+ // The empty string causes the UI we want.
+ // If it's null, the explicit trait doesn't show up in Test Explorer.
+ // If it's not empty, it shows up as “Explicit [value]” in Test Explorer.
+ private const string ExplicitTraitValue = "";
- private readonly NUnitProperty explicitTrait = new (ExplicitTraitName, ExplicitTraitValue);
+ private readonly NUnitProperty explicitTrait = new (ExplicitTraitName, ExplicitTraitValue);
- private readonly List categorylist = new ();
- private readonly TestCase testCase;
- private readonly IAdapterSettings settings;
- private readonly bool showInternalProperties;
+ private readonly List categorylist = new ();
+ private readonly TestCase testCase;
+ private readonly IAdapterSettings settings;
+ private readonly bool showInternalProperties;
- public CategoryList(TestCase testCase, IAdapterSettings adapterSettings)
- {
- settings = adapterSettings;
- showInternalProperties = settings.ShowInternalProperties;
- this.testCase = testCase;
- // MsTestCategoryProperty = TestProperty.Register(MSTestCategoryName, VsTestCategoryLabel, typeof(string[]), TestPropertyAttributes.Hidden | TestPropertyAttributes.Trait, typeof(TestCase));
- }
+ public CategoryList(TestCase testCase, IAdapterSettings adapterSettings)
+ {
+ settings = adapterSettings;
+ showInternalProperties = settings.ShowInternalProperties;
+ this.testCase = testCase;
+ // MsTestCategoryProperty = TestProperty.Register(MSTestCategoryName, VsTestCategoryLabel, typeof(string[]), TestPropertyAttributes.Hidden | TestPropertyAttributes.Trait, typeof(TestCase));
+ }
- public void AddRange(IEnumerable categories)
- {
- categorylist.AddRange(categories);
- }
+ public void AddRange(IEnumerable categories)
+ {
+ categorylist.AddRange(categories);
+ }
- ///
- /// Unsure about purpose of this, see https://github.com/nunit/nunit3-vs-adapter/pull/763#discussion_r446668680.
- ///
- public int LastNodeListCount { get; private set; }
+ ///
+ /// Unsure about purpose of this, see https://github.com/nunit/nunit3-vs-adapter/pull/763#discussion_r446668680.
+ ///
+ public int LastNodeListCount { get; private set; }
- public IEnumerable ProcessTestCaseProperties(INUnitTestCasePropertyInfo testNode, bool addToCache, string key = null,
- IDictionary traitsCache = null)
+ public IEnumerable ProcessTestCaseProperties(INUnitTestCasePropertyInfo testNode, bool addToCache, string key = null,
+ IDictionary traitsCache = null)
+ {
+ LastNodeListCount = testNode.Properties.Count();
+ foreach (var propertyNode in testNode.Properties)
{
- LastNodeListCount = testNode.Properties.Count();
- foreach (var propertyNode in testNode.Properties)
+ if (addToCache)
+ AddTraitsToCache(traitsCache, key, propertyNode);
+ if (IsInternalProperty(propertyNode))
+ continue;
+ if (propertyNode.Name != NUnitTestCategoryLabel)
{
- if (addToCache)
- AddTraitsToCache(traitsCache, key, propertyNode);
- if (IsInternalProperty(propertyNode))
- continue;
- if (propertyNode.Name != NUnitTestCategoryLabel)
- {
- testCase.Traits.Add(new Trait(propertyNode.Name, propertyNode.Value));
- }
- else
- {
- categorylist.Add(propertyNode.Value);
- }
+ testCase.Traits.Add(new Trait(propertyNode.Name, propertyNode.Value));
}
-
- if (testNode.RunState != RunStateEnum.Explicit) // Attributes?["runstate"]?.Value != "Explicit")
- return categorylist;
- // Add UI grouping “Explicit”
- if (testCase.Traits.All(trait => trait.Name != ExplicitTraitName))
- testCase.Traits.Add(new Trait(ExplicitTraitName, ExplicitTraitValue));
-
- // Track whether the test is actually explicit since multiple things result in the same UI grouping
- testCase.SetPropertyValue(NUnitExplicitProperty, true);
-
- if (addToCache)
+ else
{
- // Add UI grouping “Explicit”
- AddTraitsToCache(traitsCache, key, explicitTrait);
-
- // Track whether the test is actually explicit since multiple things result in the same UI grouping
- GetCachedInfo(traitsCache, key).Explicit = true;
+ categorylist.Add(propertyNode.Value);
}
+ }
+ if (testNode.RunState != RunStateEnum.Explicit) // Attributes?["runstate"]?.Value != "Explicit")
return categorylist;
+ // Add UI grouping “Explicit”
+ if (testCase.Traits.All(trait => trait.Name != ExplicitTraitName))
+ testCase.Traits.Add(new Trait(ExplicitTraitName, ExplicitTraitValue));
+
+ // Track whether the test is actually explicit since multiple things result in the same UI grouping
+ testCase.SetPropertyValue(NUnitExplicitProperty, true);
+
+ if (addToCache)
+ {
+ // Add UI grouping “Explicit”
+ AddTraitsToCache(traitsCache, key, explicitTrait);
+
+ // Track whether the test is actually explicit since multiple things result in the same UI grouping
+ GetCachedInfo(traitsCache, key).Explicit = true;
}
- ///
- /// See https://github.com/nunit/nunit/blob/master/src/NUnitFramework/framework/Internal/PropertyNames.cs.
- ///
- private readonly HashSet _internalProperties = new (StringComparer.OrdinalIgnoreCase)
+ return categorylist;
+ }
+
+ ///
+ /// See https://github.com/nunit/nunit/blob/master/src/NUnitFramework/framework/Internal/PropertyNames.cs.
+ ///
+ private readonly HashSet _internalProperties = new (StringComparer.OrdinalIgnoreCase)
{ "Author", "ApartmentState", "Description", "IgnoreUntilDate", "LevelOfParallelism", "MaxTime", "Order", "ParallelScope", "Repeat", "RequiresThread", "SetCulture", "SetUICulture", "TestOf", "Timeout" };
- private bool IsInternalProperty(NUnitProperty property)
+ private bool IsInternalProperty(NUnitProperty property)
+ {
+ if (property.Name == ExplicitTraitName)
{
- if (property.Name == ExplicitTraitName)
- {
- // Otherwise the IsNullOrEmpty check does the wrong thing,
- // but I'm not sure of the consequences of allowing all empty strings.
- return false;
- }
+ // Otherwise the IsNullOrEmpty check does the wrong thing,
+ // but I'm not sure of the consequences of allowing all empty strings.
+ return false;
+ }
- // Property names starting with '_' are for internal use only, but over time this has changed, so we now use a list
- return (!showInternalProperties &&
+ // Property names starting with '_' are for internal use only, but over time this has changed, so we now use a list
+ return (!showInternalProperties &&
_internalProperties.Contains(property.Name)) || (string.IsNullOrEmpty(property.Name) ||
- property.Name[0] == '_' ||
- string.IsNullOrEmpty(property.Value));
- }
+ property.Name[0] == '_' ||
+ string.IsNullOrEmpty(property.Value));
+ }
- private void AddTraitsToCache(IDictionary traitsCache, string key, NUnitProperty property)
- {
- if (IsInternalProperty(property)) return;
+ private void AddTraitsToCache(IDictionary traitsCache, string key, NUnitProperty property)
+ {
+ if (IsInternalProperty(property)) return;
- var info = GetCachedInfo(traitsCache, key);
- info.Traits.Add(new Trait(property.Name, property.Value));
- }
+ var info = GetCachedInfo(traitsCache, key);
+ info.Traits.Add(new Trait(property.Name, property.Value));
+ }
- private static TraitsFeature.CachedTestCaseInfo GetCachedInfo(IDictionary traitsCache, string key)
- {
- if (!traitsCache.TryGetValue(key, out var info))
- traitsCache.Add(key, info = new TraitsFeature.CachedTestCaseInfo());
- return info;
- }
+ private static TraitsFeature.CachedTestCaseInfo GetCachedInfo(IDictionary traitsCache, string key)
+ {
+ if (!traitsCache.TryGetValue(key, out var info))
+ traitsCache.Add(key, info = new TraitsFeature.CachedTestCaseInfo());
+ return info;
+ }
- public void UpdateCategoriesToVs()
+ public void UpdateCategoriesToVs()
+ {
+ if (categorylist.Any())
{
- if (categorylist.Any())
- {
- testCase.SetPropertyValue(
- settings.VsTestCategoryType == VsTestCategoryType.NUnit
- ? NUnitTestCategoryProperty
- : null, categorylist.Distinct().ToArray());
- }
+ testCase.SetPropertyValue(
+ settings.VsTestCategoryType == VsTestCategoryType.NUnit
+ ? NUnitTestCategoryProperty
+ : null, categorylist.Distinct().ToArray());
}
}
}
\ No newline at end of file
diff --git a/src/NUnitTestAdapter/Dump/DumpXml.cs b/src/NUnitTestAdapter/Dump/DumpXml.cs
index ec4488c3..75275bb4 100644
--- a/src/NUnitTestAdapter/Dump/DumpXml.cs
+++ b/src/NUnitTestAdapter/Dump/DumpXml.cs
@@ -4,176 +4,177 @@
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
+
using Microsoft.VisualStudio.TestPlatform.ObjectModel;
+
using NUnit.Engine;
-namespace NUnit.VisualStudio.TestAdapter.Dump
+namespace NUnit.VisualStudio.TestAdapter.Dump;
+
+public interface IFile
{
- public interface IFile
- {
- void WriteAllText(string path, string txt);
- bool DirectoryExist(string path);
+ void WriteAllText(string path, string txt);
+ bool DirectoryExist(string path);
- void CreateDirectory(string path);
- }
+ void CreateDirectory(string path);
+}
- public class File : IFile
+public class File : IFile
+{
+ public void WriteAllText(string path, string txt)
{
- public void WriteAllText(string path, string txt)
- {
- System.IO.File.WriteAllText(path, txt);
- }
+ System.IO.File.WriteAllText(path, txt);
+ }
- public bool DirectoryExist(string path)
- {
- return Directory.Exists(path);
- }
+ public bool DirectoryExist(string path)
+ {
+ return Directory.Exists(path);
+ }
- public void CreateDirectory(string path)
- {
- Directory.CreateDirectory(path);
- }
+ public void CreateDirectory(string path)
+ {
+ Directory.CreateDirectory(path);
}
+}
- public interface IDumpXml
+public interface IDumpXml
+{
+ void AddString(string text);
+ void AddTestEvent(string text);
+ void StartDiscoveryInExecution(IGrouping testCases, TestFilter filter, TestPackage package);
+ void DumpForExecution();
+ void DumpVSInputFilter(TestFilter filter, string info);
+ void StartExecution(TestFilter filter, string atExecution);
+}
+
+public class DumpXml : IDumpXml
+{
+ private const string Header = "\n";
+ private const string Rootstart = "\n";
+ private const string Rootend = "\n";
+ private readonly IFile file;
+ private readonly string directory;
+ private readonly string filename;
+ private StringBuilder txt;
+ private static string assemblyPath;
+
+ public DumpXml(string path, IFile file = null)
{
- void AddString(string text);
- void AddTestEvent(string text);
- void StartDiscoveryInExecution(IGrouping testCases, TestFilter filter, TestPackage package);
- void DumpForExecution();
- void DumpVSInputFilter(TestFilter filter, string info);
- void StartExecution(TestFilter filter, string atExecution);
+ assemblyPath = path;
+ directory = Path.GetDirectoryName(path);
+ filename = Path.GetFileName(path);
+ this.file = file ?? new File();
+ txt = new StringBuilder();
+ txt.Append(Header);
+ txt.Append(Rootstart);
}
- public class DumpXml : IDumpXml
+ public void Dump2File(string path)
{
- private const string Header = "\n";
- private const string Rootstart = "\n";
- private const string Rootend = "\n";
- private readonly IFile file;
- private readonly string directory;
- private readonly string filename;
- private StringBuilder txt;
- private static string assemblyPath;
-
- public DumpXml(string path, IFile file = null)
- {
- assemblyPath = path;
- directory = Path.GetDirectoryName(path);
- filename = Path.GetFileName(path);
- this.file = file ?? new File();
- txt = new StringBuilder();
- txt.Append(Header);
- txt.Append(Rootstart);
- }
-
- public void Dump2File(string path)
- {
- EnsurePathExist(path);
- txt.Append(Rootend);
- file.WriteAllText(path, txt.ToString());
- txt = new StringBuilder();
- }
+ EnsurePathExist(path);
+ txt.Append(Rootend);
+ file.WriteAllText(path, txt.ToString());
+ txt = new StringBuilder();
+ }
- private void EnsurePathExist(string path)
- {
- var folder = Path.GetDirectoryName(path);
- if (!file.DirectoryExist(folder))
- file.CreateDirectory(folder);
- }
+ private void EnsurePathExist(string path)
+ {
+ var folder = Path.GetDirectoryName(path);
+ if (!file.DirectoryExist(folder))
+ file.CreateDirectory(folder);
+ }
- public void DumpForDiscovery()
- {
- var dumpfolder = Path.Combine(directory, "Dump");
- var path = Path.Combine(dumpfolder, $"D_{filename}.dump");
- Dump2File(path);
- }
+ public void DumpForDiscovery()
+ {
+ var dumpfolder = Path.Combine(directory, "Dump");
+ var path = Path.Combine(dumpfolder, $"D_{filename}.dump");
+ Dump2File(path);
+ }
- public void DumpForExecution()
- {
- var dumpfolder = Path.Combine(directory, "Dump");
- var path = Path.Combine(dumpfolder, $"E_{filename}.dump");
- Dump2File(path);
- }
+ public void DumpForExecution()
+ {
+ var dumpfolder = Path.Combine(directory, "Dump");
+ var path = Path.Combine(dumpfolder, $"E_{filename}.dump");
+ Dump2File(path);
+ }
- public string RandomName()
- {
- var guid = Guid.NewGuid();
- var res = Convert.ToBase64String(guid.ToByteArray());
- var res2 = Regex.Replace(res, @"[^a-zA-Z0-9]", "");
- return res2 + ".dump";
- }
+ public string RandomName()
+ {
+ var guid = Guid.NewGuid();
+ var res = Convert.ToBase64String(guid.ToByteArray());
+ var res2 = Regex.Replace(res, "[^a-zA-Z0-9]", "");
+ return res2 + ".dump";
+ }
- public void AddTestEvent(string text)
- {
- txt.Append("\n");
- txt.Append(text);
- txt.Append("\n\n");
- }
+ public void AddTestEvent(string text)
+ {
+ txt.Append("\n");
+ txt.Append(text);
+ txt.Append("\n\n");
+ }
- public void AddString(string text)
- {
- txt.Append(text);
- }
+ public void AddString(string text)
+ {
+ txt.Append(text);
+ }
- public void DumpVSInputFilter(TestFilter filter, string info)
- {
- AddString($"\n {info} {filter.Text}\n\n\n");
- }
+ public void DumpVSInputFilter(TestFilter filter, string info)
+ {
+ AddString($"\n {info} {filter.Text}\n\n\n");
+ }
- public void DumpVSInput(IEnumerable testCases)
+ public void DumpVSInput(IEnumerable testCases)
+ {
+ AddString(" (DisplayName : FQN : Id)\n");
+ foreach (var tc in testCases)
{
- AddString(" (DisplayName : FQN : Id)\n");
- foreach (var tc in testCases)
- {
- AddString($" {tc.DisplayName} : {tc.FullyQualifiedName} : {tc.Id}\n");
- }
- AddString("\n");
+ AddString($" {tc.DisplayName} : {tc.FullyQualifiedName} : {tc.Id}\n");
}
+ AddString("\n");
+ }
- public void DumpVSInput2NUnit(TestPackage package)
+ public void DumpVSInput2NUnit(TestPackage package)
+ {
+ AddString($"\n: {package.Name}\n\n");
+ foreach (var tc in package.SubPackages)
{
- AddString($"\n: {package.Name}\n\n");
- foreach (var tc in package.SubPackages)
- {
- DumpVSInput2NUnit(tc);
- }
- AddString("\n\n\n");
+ DumpVSInput2NUnit(tc);
}
+ AddString("\n\n\n");
+ }
- private void DumpFromVSInput(IGrouping testCases, TestFilter filter, TestPackage package)
- {
- AddString("\n\n");
- if (testCases != null)
- DumpVSInput(testCases);
- DumpVSInput2NUnit(package);
- DumpVSInputFilter(filter, "");
- AddString("\n\n");
- }
+ private void DumpFromVSInput(IGrouping testCases, TestFilter filter, TestPackage package)
+ {
+ AddString("\n\n");
+ if (testCases != null)
+ DumpVSInput(testCases);
+ DumpVSInput2NUnit(package);
+ DumpVSInputFilter(filter, "");
+ AddString("\n\n");
+ }
- public void StartDiscoveryInExecution(IGrouping testCases, TestFilter filter, TestPackage package)
- {
- DumpFromVSInput(testCases, filter, package);
- AddString($"{assemblyPath}\n\n");
- }
+ public void StartDiscoveryInExecution(IGrouping testCases, TestFilter filter, TestPackage package)
+ {
+ DumpFromVSInput(testCases, filter, package);
+ AddString($"{assemblyPath}\n\n");
+ }
- public void StartExecution(TestFilter filter, string atExecution)
- {
- DumpVSInputFilter(filter, atExecution);
- AddString($"\n\n{assemblyPath}\n\n");
- }
+ public void StartExecution(TestFilter filter, string atExecution)
+ {
+ DumpVSInputFilter(filter, atExecution);
+ AddString($"\n\n{assemblyPath}\n\n");
+ }
- public static IDumpXml CreateDump(string path, IGrouping testCases, IAdapterSettings settings)
- {
- if (!settings.DumpXmlTestResults)
- return null;
- var executionDumpXml = new DumpXml(path);
- string runningBy = testCases == null
- ? "Sources"
- : "TestCases";
- executionDumpXml.AddString($"\n{runningBy}\n");
- return executionDumpXml;
- }
+ public static IDumpXml CreateDump(string path, IGrouping testCases, IAdapterSettings settings)
+ {
+ if (!settings.DumpXmlTestResults)
+ return null;
+ var executionDumpXml = new DumpXml(path);
+ string runningBy = testCases == null
+ ? "Sources"
+ : "TestCases";
+ executionDumpXml.AddString($"\n{runningBy}\n");
+ return executionDumpXml;
}
-}
+}
\ No newline at end of file
diff --git a/src/NUnitTestAdapter/Dump/XmlNodeExtension.cs b/src/NUnitTestAdapter/Dump/XmlNodeExtension.cs
index 6d853706..d976eeef 100644
--- a/src/NUnitTestAdapter/Dump/XmlNodeExtension.cs
+++ b/src/NUnitTestAdapter/Dump/XmlNodeExtension.cs
@@ -1,22 +1,19 @@
using System.IO;
-namespace NUnit.VisualStudio.TestAdapter.Dump
+namespace NUnit.VisualStudio.TestAdapter.Dump;
+
+public static class XmlNodeExtension
{
- public static class XmlNodeExtension
+ public static string AsString(this System.Xml.XmlNode node)
{
- public static string AsString(this System.Xml.XmlNode node)
+ using var swriter = new StringWriter();
+ using (var twriter = new System.Xml.XmlTextWriter(swriter))
{
- using (var swriter = new StringWriter())
- {
- using (var twriter = new System.Xml.XmlTextWriter(swriter))
- {
- twriter.Formatting = System.Xml.Formatting.Indented;
- twriter.Indentation = 3;
- twriter.QuoteChar = '\'';
- node.WriteTo(twriter);
- }
- return swriter.ToString();
- }
+ twriter.Formatting = System.Xml.Formatting.Indented;
+ twriter.Indentation = 3;
+ twriter.QuoteChar = '\'';
+ node.WriteTo(twriter);
}
+ return swriter.ToString();
}
}
\ No newline at end of file
diff --git a/src/NUnitTestAdapter/Execution.cs b/src/NUnitTestAdapter/Execution.cs
index 74c605cf..a2d2d396 100644
--- a/src/NUnitTestAdapter/Execution.cs
+++ b/src/NUnitTestAdapter/Execution.cs
@@ -4,201 +4,178 @@
using NUnit.VisualStudio.TestAdapter.Dump;
using NUnit.VisualStudio.TestAdapter.NUnitEngine;
-namespace NUnit.VisualStudio.TestAdapter
-{
- public interface IExecutionContext
- {
- ITestLogger Log { get; }
- INUnitEngineAdapter EngineAdapter { get; }
- string TestOutputXmlFolder { get; }
- IAdapterSettings Settings { get; }
- IDumpXml Dump { get; }
+namespace NUnit.VisualStudio.TestAdapter;
- IVsTestFilter VsTestFilter { get; }
- }
+public interface IExecutionContext
+{
+ ITestLogger Log { get; }
+ INUnitEngineAdapter EngineAdapter { get; }
+ string TestOutputXmlFolder { get; }
+ IAdapterSettings Settings { get; }
+ IDumpXml Dump { get; }
- public static class ExecutionFactory
- {
- public static Execution Create(IExecutionContext ctx) => ctx.Settings.DesignMode ? new IdeExecution(ctx) : new VsTestExecution(ctx);
- }
+ IVsTestFilter VsTestFilter { get; }
+}
- public abstract class Execution
- {
- protected string TestOutputXmlFolder => ctx.TestOutputXmlFolder;
- private readonly IExecutionContext ctx;
- protected ITestLogger TestLog => ctx.Log;
- protected IAdapterSettings Settings => ctx.Settings;
+public static class ExecutionFactory
+{
+ public static Execution Create(IExecutionContext ctx) => ctx.Settings.DesignMode ? new IdeExecution(ctx) : new VsTestExecution(ctx);
+}
- protected IDumpXml Dump => ctx.Dump;
- protected IVsTestFilter VsTestFilter => ctx.VsTestFilter;
+public abstract class Execution(IExecutionContext ctx)
+{
+ protected string TestOutputXmlFolder => ctx.TestOutputXmlFolder;
+ protected ITestLogger TestLog => ctx.Log;
+ protected IAdapterSettings Settings => ctx.Settings;
- protected INUnitEngineAdapter NUnitEngineAdapter => ctx.EngineAdapter;
- protected Execution(IExecutionContext ctx)
- {
- this.ctx = ctx;
- }
+ protected IDumpXml Dump => ctx.Dump;
+ protected IVsTestFilter VsTestFilter => ctx.VsTestFilter;
+ protected INUnitEngineAdapter NUnitEngineAdapter => ctx.EngineAdapter;
- public virtual bool Run(TestFilter filter, DiscoveryConverter discovery, NUnit3TestExecutor nUnit3TestExecutor)
+ public virtual bool Run(TestFilter filter, DiscoveryConverter discovery, NUnit3TestExecutor nUnit3TestExecutor)
+ {
+ filter = CheckFilterInCurrentMode(filter, discovery);
+ nUnit3TestExecutor.Dump?.StartExecution(filter, "(At Execution)");
+ var converter = CreateConverter(discovery);
+ using var listener = new NUnitEventListener(converter, nUnit3TestExecutor);
+ try
{
- filter = CheckFilterInCurrentMode(filter, discovery);
- nUnit3TestExecutor.Dump?.StartExecution(filter, "(At Execution)");
- var converter = CreateConverter(discovery);
- using var listener = new NUnitEventListener(converter, nUnit3TestExecutor);
- try
- {
- var results = NUnitEngineAdapter.Run(listener, filter);
- NUnitEngineAdapter.GenerateTestOutput(results, discovery.AssemblyPath, TestOutputXmlFolder);
- }
- catch (NullReferenceException)
- {
- // this happens during the run when CancelRun is called.
- TestLog.Debug(" Null ref caught");
- }
-
- return true;
+ var results = NUnitEngineAdapter.Run(listener, filter);
+ NUnitEngineAdapter.GenerateTestOutput(results, discovery.AssemblyPath, TestOutputXmlFolder);
}
+ catch (NullReferenceException)
+ {
+ // this happens during the run when CancelRun is called.
+ TestLog.Debug(" Null ref caught");
+ }
+
+ return true;
+ }
- public abstract TestFilter CheckFilterInCurrentMode(TestFilter filter, IDiscoveryConverter discovery);
+ public abstract TestFilter CheckFilterInCurrentMode(TestFilter filter, IDiscoveryConverter discovery);
- protected NUnitTestFilterBuilder CreateTestFilterBuilder()
- => new(NUnitEngineAdapter.GetService(), Settings);
- protected ITestConverterCommon CreateConverter(DiscoveryConverter discovery) => Settings.DiscoveryMethod == DiscoveryMethod.Current ? discovery.TestConverter : discovery.TestConverterForXml;
+ protected NUnitTestFilterBuilder CreateTestFilterBuilder()
+ => new(NUnitEngineAdapter.GetService(), Settings);
+ protected ITestConverterCommon CreateConverter(DiscoveryConverter discovery) => Settings.DiscoveryMethod == DiscoveryMethod.Current ? discovery.TestConverter : discovery.TestConverterForXml;
- protected TestFilter CheckFilter(TestFilter testFilter, IDiscoveryConverter discovery)
+ protected TestFilter CheckFilter(TestFilter testFilter, IDiscoveryConverter discovery)
+ {
+ if (discovery.NoOfLoadedTestCasesAboveLimit && !testFilter.IsCategoryFilter())
{
- if (discovery.NoOfLoadedTestCasesAboveLimit && !testFilter.IsCategoryFilter())
- {
- TestLog.Debug("Setting filter to empty due to number of testcases");
- var filter = TestFilter.Empty;
- return filter;
- }
- if (discovery.NoOfLoadedTestCases == 0)
- return testFilter;
- if (testFilter.IsCategoryFilter())
+ TestLog.Debug("Setting filter to empty due to number of testcases");
+ var filter = TestFilter.Empty;
+ return filter;
+ }
+ if (discovery.NoOfLoadedTestCases == 0)
+ return testFilter;
+ if (testFilter.IsCategoryFilter())
+ {
+ if (!discovery.IsExplicitRun && discovery.HasExplicitTests && Settings.ExplicitMode == ExplicitModeEnum.Strict)
{
- if (!discovery.IsExplicitRun && discovery.HasExplicitTests && Settings.ExplicitMode == ExplicitModeEnum.Strict)
- {
- var filterExt = new TestFilter($"true");
- var combiner = new TestFilterCombiner(testFilter, filterExt);
- return combiner.GetFilter();
- }
- return testFilter;
+ var filterExt = new TestFilter($"true");
+ var combiner = new TestFilterCombiner(testFilter, filterExt);
+ return combiner.GetFilter();
}
- var filterBuilder = CreateTestFilterBuilder();
- return filterBuilder.FilterByList(discovery.LoadedTestCases);
+ return testFilter;
}
+ var filterBuilder = CreateTestFilterBuilder();
+ return filterBuilder.FilterByList(discovery.LoadedTestCases);
}
+}
- public class TestFilterCombiner
+public class TestFilterCombiner(TestFilter a, TestFilter b)
+{
+ public TestFilter GetFilter()
{
- private readonly TestFilter _a;
- private readonly TestFilter _b;
-
- public TestFilterCombiner(TestFilter a, TestFilter b)
- {
- _a = a;
- _b = b;
- }
-
- public TestFilter GetFilter()
- {
- var innerA = StripFilter(_a);
- var innerB = StripFilter(_b);
- var inner = $"{innerA}{innerB}";
- return new TestFilter(inner);
- }
+ var innerA = StripFilter(a);
+ var innerB = StripFilter(b);
+ var inner = $"{innerA}{innerB}";
+ return new TestFilter(inner);
+ }
- private string StripFilter(TestFilter x)
- {
- var s = x.Text.Replace("", "");
- var s2 = s.Replace("", "");
- return s2;
- }
+ private string StripFilter(TestFilter x)
+ {
+ var s = x.Text.Replace("", "");
+ var s2 = s.Replace("", "");
+ return s2;
}
+}
- public class IdeExecution : Execution
+public class IdeExecution(IExecutionContext ctx) : Execution(ctx)
+{
+ public override TestFilter CheckFilterInCurrentMode(TestFilter filter, IDiscoveryConverter discovery)
{
- public IdeExecution(IExecutionContext ctx) : base(ctx)
- {
- }
- public override TestFilter CheckFilterInCurrentMode(TestFilter filter, IDiscoveryConverter discovery)
- {
- if (!discovery.IsDiscoveryMethodCurrent)
- return filter;
- if (filter.IsEmpty())
- return filter;
- filter = CheckFilter(filter, discovery);
+ if (!discovery.IsDiscoveryMethodCurrent)
return filter;
- }
+ if (filter.IsEmpty())
+ return filter;
+ filter = CheckFilter(filter, discovery);
+ return filter;
}
+}
- public class VsTestExecution : Execution
+public class VsTestExecution(IExecutionContext ctx) : Execution(ctx)
+{
+ public override bool Run(TestFilter filter, DiscoveryConverter discovery, NUnit3TestExecutor nUnit3TestExecutor)
{
- public VsTestExecution(IExecutionContext ctx) : base(ctx)
- {
- }
+ filter = CheckVsTestFilter(filter, discovery, VsTestFilter);
- public override bool Run(TestFilter filter, DiscoveryConverter discovery, NUnit3TestExecutor nUnit3TestExecutor)
+ if (filter == NUnitTestFilterBuilder.NoTestsFound)
{
- filter = CheckVsTestFilter(filter, discovery, VsTestFilter);
-
- if (filter == NUnitTestFilterBuilder.NoTestsFound)
- {
- TestLog.Info(" Skipping assembly - no matching test cases found");
- return false;
- }
- return base.Run(filter, discovery, nUnit3TestExecutor);
+ TestLog.Info(" Skipping assembly - no matching test cases found");
+ return false;
}
+ return base.Run(filter, discovery, nUnit3TestExecutor);
+ }
- public TestFilter CheckVsTestFilter(TestFilter filter, IDiscoveryConverter discovery, IVsTestFilter vsTestFilter)
- {
- // If we have a VSTest TestFilter, convert it to an nunit filter
- if (vsTestFilter == null || vsTestFilter.IsEmpty)
- return filter;
- TestLog.Debug($"TfsFilter used, length: {vsTestFilter.TfsTestCaseFilterExpression?.TestCaseFilterValue.Length}");
- // NOTE This overwrites filter used in call
- var filterBuilder = CreateTestFilterBuilder();
- filter = Settings.DiscoveryMethod == DiscoveryMethod.Current
- ? Settings.UseNUnitFilter
- ? filterBuilder.ConvertVsTestFilterToNUnitFilter(vsTestFilter)
- : filterBuilder.ConvertTfsFilterToNUnitFilter(vsTestFilter, discovery)
- : filterBuilder.ConvertTfsFilterToNUnitFilter(vsTestFilter, discovery.LoadedTestCases);
-
- Dump?.AddString($"\n\nTFSFilter: {vsTestFilter.TfsTestCaseFilterExpression?.TestCaseFilterValue}\n");
- Dump?.DumpVSInputFilter(filter, "(At Execution (TfsFilter)");
-
+ public TestFilter CheckVsTestFilter(TestFilter filter, IDiscoveryConverter discovery, IVsTestFilter vsTestFilter)
+ {
+ // If we have a VSTest TestFilter, convert it to an nunit filter
+ if (vsTestFilter == null || vsTestFilter.IsEmpty)
return filter;
+ TestLog.Debug($"TfsFilter used, length: {vsTestFilter.TfsTestCaseFilterExpression?.TestCaseFilterValue.Length}");
+ // NOTE This overwrites filter used in call
+ var filterBuilder = CreateTestFilterBuilder();
+ filter = Settings.DiscoveryMethod == DiscoveryMethod.Current
+ ? Settings.UseNUnitFilter
+ ? filterBuilder.ConvertVsTestFilterToNUnitFilter(vsTestFilter)
+ : filterBuilder.ConvertTfsFilterToNUnitFilter(vsTestFilter, discovery)
+ : filterBuilder.ConvertTfsFilterToNUnitFilter(vsTestFilter, discovery.LoadedTestCases);
+
+ Dump?.AddString($"\n\nTFSFilter: {vsTestFilter.TfsTestCaseFilterExpression?.TestCaseFilterValue}\n");
+ Dump?.DumpVSInputFilter(filter, "(At Execution (TfsFilter)");
+
+ return filter;
+ }
+ public override TestFilter CheckFilterInCurrentMode(TestFilter filter, IDiscoveryConverter discovery)
+ {
+ if (!discovery.IsDiscoveryMethodCurrent)
+ return filter;
+ if (filter != TestFilter.Empty)
+ {
+ filter = CheckFilter(filter, discovery);
}
- public override TestFilter CheckFilterInCurrentMode(TestFilter filter, IDiscoveryConverter discovery)
+ else if (VsTestFilter is { IsEmpty: false } && !Settings.UseNUnitFilter)
{
- if (!discovery.IsDiscoveryMethodCurrent)
- return filter;
- if (filter != TestFilter.Empty)
- {
- filter = CheckFilter(filter, discovery);
- }
- else if (VsTestFilter is { IsEmpty: false } && !Settings.UseNUnitFilter)
- {
- var s = VsTestFilter.TfsTestCaseFilterExpression.TestCaseFilterValue;
- var scount = s.Split('|', '&').Length;
- filter = CheckAssemblySelectLimit(filter, scount);
- }
-
- return filter;
+ var s = VsTestFilter.TfsTestCaseFilterExpression.TestCaseFilterValue;
+ var scount = s.Split('|', '&').Length;
+ filter = CheckAssemblySelectLimit(filter, scount);
}
- private TestFilter CheckAssemblySelectLimit(TestFilter filter, int scount)
+ return filter;
+ }
+
+ private TestFilter CheckAssemblySelectLimit(TestFilter filter, int scount)
+ {
+ if (scount <= Settings.AssemblySelectLimit)
{
- if (scount <= Settings.AssemblySelectLimit)
- {
- return filter;
- }
- TestLog.Debug("Setting filter to empty due to TfsFilter size");
- return TestFilter.Empty;
+ return filter;
}
+ TestLog.Debug("Setting filter to empty due to TfsFilter size");
+ return TestFilter.Empty;
}
-}
+}
\ No newline at end of file
diff --git a/src/NUnitTestAdapter/Internal/Extensions.cs b/src/NUnitTestAdapter/Internal/Extensions.cs
index a0f8fb2a..c6582ce7 100644
--- a/src/NUnitTestAdapter/Internal/Extensions.cs
+++ b/src/NUnitTestAdapter/Internal/Extensions.cs
@@ -1,15 +1,14 @@
using System;
-namespace NUnit.VisualStudio.TestAdapter.Internal
-{
+namespace NUnit.VisualStudio.TestAdapter.Internal;
#if NET462DISABLED
- public static class TypeExtensions
- {
- public static Type GetTypeInfo(this Type type) => type;
- }
-#endif
- public static class StringExtensions
- {
- public static bool IsNullOrWhiteSpace(this string value) => string.IsNullOrEmpty(value) || value.Trim().Length == 0;
- }
+public static class TypeExtensions
+{
+ public static Type GetTypeInfo(this Type type) => type;
}
+#endif
+public static class StringExtensions
+{
+ public static bool IsNullOrWhiteSpace(this string value)
+ => string.IsNullOrEmpty(value) || value.Trim().Length == 0;
+}
\ No newline at end of file
diff --git a/src/NUnitTestAdapter/Internal/TimingLogger.cs b/src/NUnitTestAdapter/Internal/TimingLogger.cs
index e16c3735..d6a06296 100644
--- a/src/NUnitTestAdapter/Internal/TimingLogger.cs
+++ b/src/NUnitTestAdapter/Internal/TimingLogger.cs
@@ -1,38 +1,37 @@
using System.Diagnostics;
-namespace NUnit.VisualStudio.TestAdapter.Internal
+namespace NUnit.VisualStudio.TestAdapter.Internal;
+
+public class TimingLogger
{
- public class TimingLogger
- {
- private readonly IAdapterSettings settings;
- private readonly ITestLogger logger;
- public Stopwatch Stopwatch { get; }
+ private readonly IAdapterSettings settings;
+ private readonly ITestLogger logger;
+ public Stopwatch Stopwatch { get; }
- public TimingLogger(IAdapterSettings settings, ITestLogger logger)
- {
- this.settings = settings;
- this.logger = logger;
- if (settings.Verbosity < 5)
- return;
- Stopwatch = Stopwatch.StartNew();
- }
+ public TimingLogger(IAdapterSettings settings, ITestLogger logger)
+ {
+ this.settings = settings;
+ this.logger = logger;
+ if (settings.Verbosity < 5)
+ return;
+ Stopwatch = Stopwatch.StartNew();
+ }
- public TimingLogger ReStart()
- {
- if (settings.Verbosity < 5)
- return this;
- Stopwatch.StartNew();
+ public TimingLogger ReStart()
+ {
+ if (settings.Verbosity < 5)
return this;
- }
+ Stopwatch.StartNew();
+ return this;
+ }
- public TimingLogger LogTime(string leadText = "")
- {
- if (settings.Verbosity < 5 || Stopwatch == null)
- return this;
- var ts = Stopwatch.Elapsed;
- string elapsedTime = $"{ts.Hours:00}:{ts.Minutes:00}:{ts.Seconds:00}.{ts.Milliseconds / 10:00}";
- logger.Info($"{leadText} :Elapsed: {elapsedTime}");
+ public TimingLogger LogTime(string leadText = "")
+ {
+ if (settings.Verbosity < 5 || Stopwatch == null)
return this;
- }
+ var ts = Stopwatch.Elapsed;
+ string elapsedTime = $"{ts.Hours:00}:{ts.Minutes:00}:{ts.Seconds:00}.{ts.Milliseconds / 10:00}";
+ logger.Info($"{leadText} :Elapsed: {elapsedTime}");
+ return this;
}
-}
+}
\ No newline at end of file
diff --git a/src/NUnitTestAdapter/Metadata/DirectReflectionMetadataProvider.cs b/src/NUnitTestAdapter/Metadata/DirectReflectionMetadataProvider.cs
index 50d1402a..f0f6e530 100644
--- a/src/NUnitTestAdapter/Metadata/DirectReflectionMetadataProvider.cs
+++ b/src/NUnitTestAdapter/Metadata/DirectReflectionMetadataProvider.cs
@@ -25,84 +25,82 @@
using System.IO;
using System.Linq;
using System.Reflection;
-using NUnit.VisualStudio.TestAdapter.Internal;
#if !NET462 && !NETSTANDARD
using System.Runtime.Loader;
#endif
-namespace NUnit.VisualStudio.TestAdapter.Metadata
+namespace NUnit.VisualStudio.TestAdapter.Metadata;
+
+internal sealed class DirectReflectionMetadataProvider : IMetadataProvider
{
- internal sealed class DirectReflectionMetadataProvider : IMetadataProvider
+ public TypeInfo? GetDeclaringType(string assemblyPath, string reflectedTypeName, string methodName)
{
- public TypeInfo? GetDeclaringType(string assemblyPath, string reflectedTypeName, string methodName)
- {
- var type = TryGetSingleMethod(assemblyPath, reflectedTypeName, methodName)?.DeclaringType;
- if (type == null) return null;
+ var type = TryGetSingleMethod(assemblyPath, reflectedTypeName, methodName)?.DeclaringType;
+ if (type == null) return null;
- if (type.IsConstructedGenericType)
- {
- type = type.GetGenericTypeDefinition();
- }
-
- return new TypeInfo(type);
+ if (type.IsConstructedGenericType)
+ {
+ type = type.GetGenericTypeDefinition();
}
- public TypeInfo? GetStateMachineType(string assemblyPath, string reflectedTypeName, string methodName)
- {
- var method = TryGetSingleMethod(assemblyPath, reflectedTypeName, methodName);
- if (method == null) return null;
+ return new TypeInfo(type);
+ }
+
+ public TypeInfo? GetStateMachineType(string assemblyPath, string reflectedTypeName, string methodName)
+ {
+ var method = TryGetSingleMethod(assemblyPath, reflectedTypeName, methodName);
+ if (method == null) return null;
- var candidate = (Type)null;
+ var candidate = (Type)null;
- foreach (var attributeData in CustomAttributeData.GetCustomAttributes(method))
+ foreach (var attributeData in CustomAttributeData.GetCustomAttributes(method))
+ {
+ for (var current = attributeData.Constructor.DeclaringType; current != null; current = current.GetTypeInfo().BaseType)
{
- for (var current = attributeData.Constructor.DeclaringType; current != null; current = current.GetTypeInfo().BaseType)
- {
- if (current.FullName != "System.Runtime.CompilerServices.StateMachineAttribute") continue;
+ if (current.FullName != "System.Runtime.CompilerServices.StateMachineAttribute") continue;
- var parameters = attributeData.Constructor.GetParameters();
- for (var i = 0; i < parameters.Length; i++)
+ var parameters = attributeData.Constructor.GetParameters();
+ for (var i = 0; i < parameters.Length; i++)
+ {
+ if (parameters[i].Name != "stateMachineType") continue;
+ if (attributeData.ConstructorArguments[i].Value is Type argument)
{
- if (parameters[i].Name != "stateMachineType") continue;
- if (attributeData.ConstructorArguments[i].Value is Type argument)
- {
- if (candidate != null)
- return null;
- candidate = argument;
- }
+ if (candidate != null)
+ return null;
+ candidate = argument;
}
}
}
-
- if (candidate == null)
- return null;
- return new TypeInfo(candidate);
}
- private static MethodInfo TryGetSingleMethod(string assemblyPath, string reflectedTypeName, string methodName)
+ if (candidate == null)
+ return null;
+ return new TypeInfo(candidate);
+ }
+
+ private static MethodInfo TryGetSingleMethod(string assemblyPath, string reflectedTypeName, string methodName)
+ {
+ try
{
- try
- {
#if !NET462 && !NETSTANDARD
- var assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(assemblyPath);
+ var assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(assemblyPath);
#else
- var assembly = Assembly.LoadFrom(assemblyPath);
+ var assembly = Assembly.LoadFrom(assemblyPath);
#endif
- var type = assembly.GetType(reflectedTypeName, throwOnError: false);
+ var type = assembly.GetType(reflectedTypeName, throwOnError: false);
- var methods = type?.GetMethods().Where(m => m.Name == methodName).Take(2).ToList();
- return methods?.Count == 1 ? methods[0] : null;
- }
- catch (FileNotFoundException)
- {
- return null;
- }
+ var methods = type?.GetMethods().Where(m => m.Name == methodName).Take(2).ToList();
+ return methods?.Count == 1 ? methods[0] : null;
}
-
- void IDisposable.Dispose()
+ catch (FileNotFoundException)
{
+ return null;
}
}
-}
+
+ void IDisposable.Dispose()
+ {
+ }
+}
\ No newline at end of file
diff --git a/src/NUnitTestAdapter/Metadata/IMetadataProvider.cs b/src/NUnitTestAdapter/Metadata/IMetadataProvider.cs
index 9fcf5bfa..7edae21f 100644
--- a/src/NUnitTestAdapter/Metadata/IMetadataProvider.cs
+++ b/src/NUnitTestAdapter/Metadata/IMetadataProvider.cs
@@ -23,11 +23,10 @@
using System;
-namespace NUnit.VisualStudio.TestAdapter.Metadata
+namespace NUnit.VisualStudio.TestAdapter.Metadata;
+
+public interface IMetadataProvider : IDisposable
{
- public interface IMetadataProvider : IDisposable
- {
- TypeInfo? GetDeclaringType(string assemblyPath, string reflectedTypeName, string methodName);
- TypeInfo? GetStateMachineType(string assemblyPath, string reflectedTypeName, string methodName);
- }
-}
+ TypeInfo? GetDeclaringType(string assemblyPath, string reflectedTypeName, string methodName);
+ TypeInfo? GetStateMachineType(string assemblyPath, string reflectedTypeName, string methodName);
+}
\ No newline at end of file
diff --git a/src/NUnitTestAdapter/Metadata/TypeInfo.cs b/src/NUnitTestAdapter/Metadata/TypeInfo.cs
index 40e31217..f09134b1 100644
--- a/src/NUnitTestAdapter/Metadata/TypeInfo.cs
+++ b/src/NUnitTestAdapter/Metadata/TypeInfo.cs
@@ -23,28 +23,17 @@
using System;
using System.Reflection;
-using NUnit.VisualStudio.TestAdapter.Internal;
-namespace NUnit.VisualStudio.TestAdapter.Metadata
-{
+namespace NUnit.VisualStudio.TestAdapter.Metadata;
#if NET462
- [Serializable]
+[Serializable]
#endif
- public struct TypeInfo
+public readonly struct TypeInfo(string assemblyPath, string fullName)
+{
+ public TypeInfo(Type type) : this(type.GetTypeInfo().Assembly.Location, type.FullName)
{
- public TypeInfo(Type type)
- {
- AssemblyPath = type.GetTypeInfo().Assembly.Location;
- FullName = type.FullName;
- }
-
- public TypeInfo(string assemblyPath, string fullName)
- {
- AssemblyPath = assemblyPath;
- FullName = fullName;
- }
-
- public string AssemblyPath { get; }
- public string FullName { get; }
}
-}
+
+ public string AssemblyPath { get; } = assemblyPath;
+ public string FullName { get; } = fullName;
+}
\ No newline at end of file
diff --git a/src/NUnitTestAdapter/NUnit.TestAdapter.csproj b/src/NUnitTestAdapter/NUnit.TestAdapter.csproj
index 64224c2a..bd04ae78 100644
--- a/src/NUnitTestAdapter/NUnit.TestAdapter.csproj
+++ b/src/NUnitTestAdapter/NUnit.TestAdapter.csproj
@@ -33,8 +33,8 @@
-
-
+
+
@@ -54,6 +54,7 @@
all
runtime; build; native; contentfiles; analyzers; buildtransitive
+
diff --git a/src/NUnitTestAdapter/NUnit3TestDiscoverer.cs b/src/NUnitTestAdapter/NUnit3TestDiscoverer.cs
index e41d4094..80b3d863 100644
--- a/src/NUnitTestAdapter/NUnit3TestDiscoverer.cs
+++ b/src/NUnitTestAdapter/NUnit3TestDiscoverer.cs
@@ -21,7 +21,6 @@
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// ***********************************************************************
-
using System;
using System.Collections.Generic;
using System.ComponentModel;
@@ -29,173 +28,173 @@
using System.IO;
using System.Linq;
using System.Xml;
+
using Microsoft.VisualStudio.TestPlatform.ObjectModel;
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter;
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging;
+
using NUnit.Engine;
using NUnit.VisualStudio.TestAdapter.Dump;
using NUnit.VisualStudio.TestAdapter.Internal;
using NUnit.VisualStudio.TestAdapter.NUnitEngine;
-namespace NUnit.VisualStudio.TestAdapter
-{
+namespace NUnit.VisualStudio.TestAdapter;
#if !NET462
- [FileExtension(".appx")]
+[FileExtension(".appx")]
#endif
- [FileExtension(".dll")]
- [FileExtension(".exe")]
- [DefaultExecutorUri(NUnit3TestExecutor.ExecutorUri)]
- [Category("managed")]
- public sealed class NUnit3TestDiscoverer : NUnitTestAdapter, ITestDiscoverer
+[FileExtension(".dll")]
+[FileExtension(".exe")]
+[DefaultExecutorUri(ExecutorUri)]
+[Category("managed")]
+public sealed class NUnit3TestDiscoverer : NUnitTestAdapter, ITestDiscoverer
+{
+ private DumpXml dumpXml;
+
+ #region ITestDiscoverer Members
+
+ public void DiscoverTests(IEnumerable sources, IDiscoveryContext discoveryContext, IMessageLogger messageLogger, ITestCaseDiscoverySink discoverySink)
{
- private DumpXml dumpXml;
+ Initialize(discoveryContext, messageLogger);
+ CheckIfDebug();
+ TestLog.Info($"NUnit Adapter {AdapterVersion}: Test discovery starting");
- #region ITestDiscoverer Members
+ // Ensure any channels registered by other adapters are unregistered
+ CleanUpRegisteredChannels();
- public void DiscoverTests(IEnumerable sources, IDiscoveryContext discoveryContext, IMessageLogger messageLogger, ITestCaseDiscoverySink discoverySink)
+ if (Settings.InProcDataCollectorsAvailable && sources.Count() > 1)
{
- Initialize(discoveryContext, messageLogger);
- CheckIfDebug();
- TestLog.Info($"NUnit Adapter {AdapterVersion}: Test discovery starting");
-
- // Ensure any channels registered by other adapters are unregistered
- CleanUpRegisteredChannels();
+ TestLog.Error("Unexpected to discover tests in multiple assemblies when InProcDataCollectors specified in run configuration.");
+ Unload();
+ return;
+ }
- if (Settings.InProcDataCollectorsAvailable && sources.Count() > 1)
+ foreach (string sourceAssembly in sources)
+ {
+ string sourceAssemblyPath = Path.IsPathRooted(sourceAssembly) ? sourceAssembly : Path.Combine(Directory.GetCurrentDirectory(), sourceAssembly);
+ TestLog.Debug("Processing " + sourceAssembly);
+ if (Settings.DumpXmlTestDiscovery)
{
- TestLog.Error("Unexpected to discover tests in multiple assemblies when InProcDataCollectors specified in run configuration.");
- Unload();
- return;
+ dumpXml = new DumpXml(sourceAssemblyPath);
}
- foreach (string sourceAssembly in sources)
+ try
{
- string sourceAssemblyPath = Path.IsPathRooted(sourceAssembly) ? sourceAssembly : Path.Combine(Directory.GetCurrentDirectory(), sourceAssembly);
- TestLog.Debug("Processing " + sourceAssembly);
- if (Settings.DumpXmlTestDiscovery)
- {
- dumpXml = new DumpXml(sourceAssemblyPath);
- }
+ var package = CreateTestPackage(sourceAssemblyPath, null);
+ NUnitEngineAdapter.CreateRunner(package);
+ var results = NUnitEngineAdapter.Explore();
+ dumpXml?.AddString(results.AsString());
- try
+ if (results.IsRunnable)
{
- var package = CreateTestPackage(sourceAssemblyPath, null);
- NUnitEngineAdapter.CreateRunner(package);
- var results = NUnitEngineAdapter.Explore();
- dumpXml?.AddString(results.AsString());
-
- if (results.IsRunnable)
+ int cases;
+ using (var testConverter = new TestConverterForXml(TestLog, sourceAssemblyPath, Settings))
{
- int cases;
- using (var testConverter = new TestConverterForXml(TestLog, sourceAssemblyPath, Settings))
- {
- var timing = new TimingLogger(Settings, TestLog);
- cases = ProcessTestCases(results, discoverySink, testConverter);
- timing.LogTime("Discovery/Processing/Converting:");
- }
-
- TestLog.Debug($"Discovered {cases} test cases");
- // Only save if seed is not specified in runsettings
- // This allows workaround in case there is no valid
- // location in which the seed may be saved.
- if (cases > 0 && !Settings.RandomSeedSpecified)
- Settings.SaveRandomSeed(Path.GetDirectoryName(sourceAssemblyPath));
- }
- else
- {
- if (results.HasNoNUnitTests)
- {
- if (Settings.Verbosity > 0)
- TestLog.Info("Assembly contains no NUnit 3.0 tests: " + sourceAssembly);
- }
- else
- {
- TestLog.Info("NUnit failed to load " + sourceAssembly);
- }
+ var timing = new TimingLogger(Settings, TestLog);
+ cases = ProcessTestCases(results, discoverySink, testConverter);
+ timing.LogTime("Discovery/Processing/Converting:");
}
+
+ TestLog.Debug($"Discovered {cases} test cases");
+ // Only save if seed is not specified in runsettings
+ // This allows workaround in case there is no valid
+ // location in which the seed may be saved.
+ if (cases > 0 && !Settings.RandomSeedSpecified)
+ Settings.SaveRandomSeed(Path.GetDirectoryName(sourceAssemblyPath));
}
- catch (NUnitEngineException e)
+ else
{
- if (e.InnerException is BadImageFormatException)
+ if (results.HasNoNUnitTests)
{
- // we skip the native c++ binaries that we don't support.
- TestLog.Warning("Assembly not supported: " + sourceAssembly);
+ if (Settings.Verbosity > 0)
+ TestLog.Info("Assembly contains no NUnit 3.0 tests: " + sourceAssembly);
}
else
{
- TestLog.Warning("Exception thrown discovering tests in " + sourceAssembly, e);
+ TestLog.Info("NUnit failed to load " + sourceAssembly);
}
}
- catch (BadImageFormatException)
+ }
+ catch (NUnitEngineException e)
+ {
+ if (e.InnerException is BadImageFormatException)
{
// we skip the native c++ binaries that we don't support.
TestLog.Warning("Assembly not supported: " + sourceAssembly);
}
- catch (FileNotFoundException ex)
- {
- // Either the NUnit framework was not referenced by the test assembly
- // or some other error occurred. Not a problem if not an NUnit assembly.
- TestLog.Warning("Dependent Assembly " + ex.FileName + " of " + sourceAssembly + " not found. Can be ignored if not an NUnit project.");
- }
- catch (FileLoadException ex)
+ else
{
- // Attempts to load an invalid assembly, or an assembly with missing dependencies
- TestLog.Warning("Assembly " + ex.FileName + " loaded through " + sourceAssembly + " failed. Assembly is ignored. Correct deployment of dependencies if this is an error.");
+ TestLog.Warning("Exception thrown discovering tests in " + sourceAssembly, e);
}
- catch (TypeLoadException ex)
- {
- if (ex.TypeName == "NUnit.Framework.Api.FrameworkController")
- TestLog.Warning(" Skipping NUnit 2.x test assembly");
- else
- TestLog.Warning("Exception thrown discovering tests in " + sourceAssembly, ex);
- }
- catch (Exception ex)
- {
+ }
+ catch (BadImageFormatException)
+ {
+ // we skip the native c++ binaries that we don't support.
+ TestLog.Warning("Assembly not supported: " + sourceAssembly);
+ }
+ catch (FileNotFoundException ex)
+ {
+ // Either the NUnit framework was not referenced by the test assembly
+ // or some other error occurred. Not a problem if not an NUnit assembly.
+ TestLog.Warning("Dependent Assembly " + ex.FileName + " of " + sourceAssembly + " not found. Can be ignored if not an NUnit project.");
+ }
+ catch (FileLoadException ex)
+ {
+ // Attempts to load an invalid assembly, or an assembly with missing dependencies
+ TestLog.Warning("Assembly " + ex.FileName + " loaded through " + sourceAssembly + " failed. Assembly is ignored. Correct deployment of dependencies if this is an error.");
+ }
+ catch (TypeLoadException ex)
+ {
+ if (ex.TypeName == "NUnit.Framework.Api.FrameworkController")
+ TestLog.Warning(" Skipping NUnit 2.x test assembly");
+ else
TestLog.Warning("Exception thrown discovering tests in " + sourceAssembly, ex);
- }
- finally
- {
- dumpXml?.DumpForDiscovery();
- NUnitEngineAdapter?.CloseRunner();
- }
}
+ catch (Exception ex)
+ {
+ TestLog.Warning("Exception thrown discovering tests in " + sourceAssembly, ex);
+ }
+ finally
+ {
+ dumpXml?.DumpForDiscovery();
+ NUnitEngineAdapter?.CloseRunner();
+ }
+ }
- TestLog.Info($"NUnit Adapter {AdapterVersion}: Test discovery complete");
+ TestLog.Info($"NUnit Adapter {AdapterVersion}: Test discovery complete");
- Unload();
- }
+ Unload();
+ }
- #endregion
+ #endregion
- #region Helper Methods
+ #region Helper Methods
- private int ProcessTestCases(NUnitResults results, ITestCaseDiscoverySink discoverySink, TestConverterForXml testConverterForXml)
+ private int ProcessTestCases(NUnitResults results, ITestCaseDiscoverySink discoverySink, TestConverterForXml testConverterForXml)
+ {
+ int cases = 0;
+ foreach (XmlNode testNode in results.TestCases())
{
- int cases = 0;
- foreach (XmlNode testNode in results.TestCases())
+ try
{
- try
- {
- var testCase = testConverterForXml.ConvertTestCase(new NUnitEventTestCase(testNode));
- discoverySink.SendTestCase(testCase);
- cases += 1;
- }
- catch (Exception ex)
- {
- TestLog.Warning("Exception converting " + testNode.GetAttribute("fullname"), ex);
- }
+ var testCase = testConverterForXml.ConvertTestCase(new NUnitEventTestCase(testNode));
+ discoverySink.SendTestCase(testCase);
+ cases += 1;
+ }
+ catch (Exception ex)
+ {
+ TestLog.Warning("Exception converting " + testNode.GetAttribute("fullname"), ex);
}
-
- return cases;
}
- private void CheckIfDebug()
- {
- if (!Settings.DebugDiscovery)
- return;
- if (!Debugger.IsAttached)
- Debugger.Launch();
- }
- #endregion
+ return cases;
+ }
+
+ private void CheckIfDebug()
+ {
+ if (!Settings.DebugDiscovery)
+ return;
+ if (!Debugger.IsAttached)
+ Debugger.Launch();
}
-}
+ #endregion
+}
\ No newline at end of file
diff --git a/src/NUnitTestAdapter/NUnit3TestExecutor.cs b/src/NUnitTestAdapter/NUnit3TestExecutor.cs
index 4f8a5a7a..59756168 100644
--- a/src/NUnitTestAdapter/NUnit3TestExecutor.cs
+++ b/src/NUnitTestAdapter/NUnit3TestExecutor.cs
@@ -37,365 +37,369 @@
using NUnit.VisualStudio.TestAdapter.Internal;
using NUnit.VisualStudio.TestAdapter.NUnitEngine;
-namespace NUnit.VisualStudio.TestAdapter
+namespace NUnit.VisualStudio.TestAdapter;
+
+public interface INUnit3TestExecutor
{
- public interface INUnit3TestExecutor
- {
- void StopRun();
- IDumpXml Dump { get; }
- IAdapterSettings Settings { get; }
- IFrameworkHandle FrameworkHandle { get; }
- }
+ void StopRun();
+ IDumpXml Dump { get; }
+ IAdapterSettings Settings { get; }
+ IFrameworkHandle FrameworkHandle { get; }
+}
- public enum RunType
- {
- Unknown,
- CommandLineLegacy,
- CommandLineCurrentVSTest,
- CommandLineCurrentNUnit,
- Ide
- }
+public enum RunType
+{
+ Unknown,
+ CommandLineLegacy,
+ CommandLineCurrentVSTest,
+ CommandLineCurrentNUnit,
+ Ide
+}
- [ExtensionUri(ExecutorUri)]
- public sealed class NUnit3TestExecutor : NUnitTestAdapter, ITestExecutor, IDisposable, INUnit3TestExecutor,
- IExecutionContext
- {
- #region Properties
+[ExtensionUri(ExecutorUri)]
+public sealed class NUnit3TestExecutor : NUnitTestAdapter, ITestExecutor, IDisposable, INUnit3TestExecutor,
+ IExecutionContext
+{
+ #region Properties
- private RunType RunType { get; set; }
+ private RunType RunType { get; set; }
- // Properties set when either of the RunTests methods is called
- public IRunContext RunContext { get; private set; }
- public IFrameworkHandle FrameworkHandle { get; private set; }
+ // Properties set when either of the RunTests methods is called
+ public IRunContext RunContext { get; private set; }
+ public IFrameworkHandle FrameworkHandle { get; private set; }
- public IVsTestFilter VsTestFilter { get; private set; }
+ public IVsTestFilter VsTestFilter { get; private set; }
- public ITestLogger Log => TestLog;
+ public ITestLogger Log => TestLog;
- public INUnitEngineAdapter EngineAdapter => NUnitEngineAdapter;
+ public INUnitEngineAdapter EngineAdapter => NUnitEngineAdapter;
- public string TestOutputXmlFolder { get; set; } = "";
+ public string TestOutputXmlFolder { get; set; } = "";
- // NOTE: an earlier version of this code had a FilterBuilder
- // property. This seemed to make sense, because we instantiate
- // it in two different places. However, the existence of an
- // NUnitTestFilterBuilder, containing a reference to an engine
- // service caused our second-level tests of the test executor
- // to throw an exception. So if you consider doing this, beware!
+ // NOTE: an earlier version of this code had a FilterBuilder
+ // property. This seemed to make sense, because we instantiate
+ // it in two different places. However, the existence of an
+ // NUnitTestFilterBuilder, containing a reference to an engine
+ // service caused our second-level tests of the test executor
+ // to throw an exception. So if you consider doing this, beware!
- #endregion
+ #endregion
- #region ITestExecutor Implementation
+ #region ITestExecutor Implementation
- ///
- /// Called by dotnet test, and TFS Build
- /// to run either all or selected tests. In the latter case, a filter is provided
- /// as part of the run context.
- ///
- /// Sources to be run.
- /// Context to use when executing the tests.
- /// Test log to send results and messages through.
- public void RunTests(IEnumerable sources, IRunContext runContext, IFrameworkHandle frameworkHandle)
- {
- Initialize(runContext, frameworkHandle);
- CheckIfDebug();
+ ///
+ /// Called by dotnet test, and TFS Build
+ /// to run either all or selected tests. In the latter case, a filter is provided
+ /// as part of the run context.
+ ///
+ /// Sources to be run.
+ /// Context to use when executing the tests.
+ /// Test log to send results and messages through.
+ public void RunTests(IEnumerable sources, IRunContext runContext, IFrameworkHandle frameworkHandle)
+ {
+ Initialize(runContext, frameworkHandle);
+ CheckIfDebug();
#if REVERSEENGINEERING
- var st = new StackTrace();
- var frames = st.GetFrames();
- var filenames = frames?.Select(x => x.GetMethod()?.DeclaringType?.Assembly.CodeBase).Distinct().ToList();
+ var st = new StackTrace();
+ var frames = st.GetFrames();
+ var filenames = frames?.Select(x => x.GetMethod()?.DeclaringType?.Assembly.CodeBase).Distinct().ToList();
#endif
- InitializeForExecution(runContext, frameworkHandle);
- TestLog.Debug($"RunTests by IEnumerable,({sources.Count()} entries), called from {WhoIsCallingUsEntry}");
+ InitializeForExecution(runContext, frameworkHandle);
+ TestLog.Debug($"RunTests by IEnumerable,({sources.Count()} entries), called from {WhoIsCallingUsEntry}");
- if (Settings.InProcDataCollectorsAvailable && sources.Count() > 1)
- {
- TestLog.Error(
- "Failed to run tests for multiple assemblies when InProcDataCollectors specified in run configuration.");
- Unload();
- return;
- }
+ if (Settings.InProcDataCollectorsAvailable && sources.Count() > 1)
+ {
+ TestLog.Error(
+ "Failed to run tests for multiple assemblies when InProcDataCollectors specified in run configuration.");
+ Unload();
+ return;
+ }
- SetRunTypeByStrings();
- var builder = CreateTestFilterBuilder();
- TestFilter filter = null;
- if (RunType == RunType.CommandLineCurrentNUnit)
- {
- var vsTestFilter = VsTestFilterFactory.CreateVsTestFilter(Settings, runContext);
- filter = builder.ConvertVsTestFilterToNUnitFilter(vsTestFilter);
- }
+ SetRunTypeByStrings();
+ var builder = CreateTestFilterBuilder();
+ TestFilter filter = null;
+ if (RunType == RunType.CommandLineCurrentNUnit)
+ {
+ var vsTestFilter = VsTestFilterFactory.CreateVsTestFilter(Settings, runContext);
+ filter = builder.ConvertVsTestFilterToNUnitFilter(vsTestFilter);
+ }
- filter ??= builder.FilterByWhere(Settings.Where);
+ filter ??= builder.FilterByWhere(Settings.Where);
- foreach (string assemblyName in sources)
- {
- try
- {
- string assemblyPath = Path.IsPathRooted(assemblyName)
- ? assemblyName
- : Path.Combine(Directory.GetCurrentDirectory(), assemblyName);
- RunAssembly(assemblyPath, null, filter);
- }
- catch (Exception ex)
- {
- if (ex is TargetInvocationException) { ex = ex.InnerException; }
+ RunAssemblies(sources, filter);
- TestLog.Warning("Exception thrown executing tests", ex);
- }
+ TestLog.Info($"NUnit Adapter {AdapterVersion}: Test execution complete");
+ Unload();
+ }
+
+ private void RunAssemblies(IEnumerable sources, TestFilter filter)
+ {
+ foreach (string assemblyName in sources)
+ {
+ try
+ {
+ string assemblyPath = Path.IsPathRooted(assemblyName)
+ ? assemblyName
+ : Path.Combine(Directory.GetCurrentDirectory(), assemblyName);
+ RunAssembly(assemblyPath, null, filter);
}
+ catch (Exception ex)
+ {
+ if (ex is TargetInvocationException) { ex = ex.InnerException; }
- TestLog.Info($"NUnit Adapter {AdapterVersion}: Test execution complete");
- Unload();
+ TestLog.Warning("Exception thrown executing tests", ex);
+ }
}
+ }
- private void SetRunTypeByStrings()
+ private void SetRunTypeByStrings()
+ {
+ RunType = !Settings.DesignMode
+ ? Settings.DiscoveryMethod == DiscoveryMethod.Legacy
+ ? RunType.CommandLineLegacy
+ : Settings.UseNUnitFilter
+ ? RunType.CommandLineCurrentNUnit
+ : RunType.CommandLineCurrentVSTest
+ : RunType.Ide;
+ TestLog.Debug($"Runtype: {RunType}");
+ }
+
+ ///
+ /// Called by the VisualStudio IDE when all or selected tests are to be run. Never called from TFS Build, except (at least 2022, probably also 2019) when 'vstest.console' uses /test: then this is being used.
+ ///
+ /// The tests to be run.
+ /// The RunContext.
+ /// The FrameworkHandle.
+ public void RunTests(IEnumerable tests, IRunContext runContext, IFrameworkHandle frameworkHandle)
+ {
+ Initialize(runContext, frameworkHandle);
+ CheckIfDebug();
+ InitializeForExecution(runContext, frameworkHandle);
+ RunType = RunType.Ide;
+ TestLog.Debug($"RunTests by IEnumerable. RunType = Ide, called from {WhoIsCallingUsEntry}");
+ var timing = new TimingLogger(Settings, TestLog);
+ Debug.Assert(NUnitEngineAdapter != null, "NUnitEngineAdapter is null");
+ Debug.Assert(NUnitEngineAdapter.EngineEnabled, "NUnitEngineAdapter TestEngine is null");
+ var assemblyGroups = tests.GroupBy(tc => tc.Source).ToList();
+ if (assemblyGroups.Count > 1)
+ TestLog.Debug($"Multiple ({assemblyGroups.Count}) assemblies in one test");
+ if (IsInProcDataCollectorsSpecifiedWithMultipleAssemblies(assemblyGroups))
{
- RunType = !Settings.DesignMode
- ? Settings.DiscoveryMethod == DiscoveryMethod.Legacy
- ? RunType.CommandLineLegacy
- : Settings.UseNUnitFilter
- ? RunType.CommandLineCurrentNUnit
- : RunType.CommandLineCurrentVSTest
- : RunType.Ide;
- TestLog.Debug($"Runtype: {RunType}");
+ TestLog.Error(
+ "Failed to run tests for multiple assemblies when InProcDataCollectors specified in run configuration.");
+ Unload();
+ return;
}
- ///
- /// Called by the VisualStudio IDE when all or selected tests are to be run. Never called from TFS Build, except (at least 2022, probably also 2019) when vstest.console uses /test: then this is being used.
- ///
- /// The tests to be run.
- /// The RunContext.
- /// The FrameworkHandle.
- public void RunTests(IEnumerable tests, IRunContext runContext, IFrameworkHandle frameworkHandle)
+ foreach (var assemblyGroup in assemblyGroups)
{
- Initialize(runContext, frameworkHandle);
- CheckIfDebug();
- InitializeForExecution(runContext, frameworkHandle);
- RunType = RunType.Ide;
- TestLog.Debug($"RunTests by IEnumerable. RunType = Ide, called from {WhoIsCallingUsEntry}");
- var timing = new TimingLogger(Settings, TestLog);
- Debug.Assert(NUnitEngineAdapter != null, "NUnitEngineAdapter is null");
- Debug.Assert(NUnitEngineAdapter.EngineEnabled, "NUnitEngineAdapter TestEngine is null");
- var assemblyGroups = tests.GroupBy(tc => tc.Source).ToList();
- if (assemblyGroups.Count > 1)
- TestLog.Debug($"Multiple ({assemblyGroups.Count}) assemblies in one test");
- if (IsInProcDataCollectorsSpecifiedWithMultipleAssemblies(assemblyGroups))
- {
- TestLog.Error(
- "Failed to run tests for multiple assemblies when InProcDataCollectors specified in run configuration.");
- Unload();
- return;
- }
-
- foreach (var assemblyGroup in assemblyGroups)
+ var assemblytiming = new TimingLogger(Settings, TestLog);
+ try
{
- var assemblytiming = new TimingLogger(Settings, TestLog);
- try
- {
- string assemblyName = assemblyGroup.Key;
- string assemblyPath = Path.IsPathRooted(assemblyName)
- ? assemblyName
- : Path.Combine(Directory.GetCurrentDirectory(), assemblyName);
-
- var filterBuilder = CreateTestFilterBuilder();
- var filter = filterBuilder.FilterByList(assemblyGroup);
+ string assemblyName = assemblyGroup.Key;
+ string assemblyPath = Path.IsPathRooted(assemblyName)
+ ? assemblyName
+ : Path.Combine(Directory.GetCurrentDirectory(), assemblyName);
- RunAssembly(assemblyPath, assemblyGroup, filter);
- }
- catch (Exception ex)
- {
- if (ex is TargetInvocationException) { ex = ex.InnerException; }
+ var filterBuilder = CreateTestFilterBuilder();
+ var filter = filterBuilder.FilterByList(assemblyGroup);
- TestLog.Warning("Exception thrown executing tests", ex);
- }
+ RunAssembly(assemblyPath, assemblyGroup, filter);
+ }
+ catch (Exception ex)
+ {
+ if (ex is TargetInvocationException) { ex = ex.InnerException; }
- assemblytiming.LogTime($"Executing {assemblyGroup.Key} time ");
+ TestLog.Warning("Exception thrown executing tests", ex);
}
- timing.LogTime("Total execution time");
- TestLog.Info($"NUnit Adapter {AdapterVersion}: Test execution complete");
- Unload();
+ assemblytiming.LogTime($"Executing {assemblyGroup.Key} time ");
}
- private bool IsInProcDataCollectorsSpecifiedWithMultipleAssemblies(
- IEnumerable> assemblyGroups)
- => Settings.InProcDataCollectorsAvailable && assemblyGroups.Count() > 1;
-
- void ITestExecutor.Cancel()
- {
- StopRun();
- }
+ timing.LogTime("Total execution time");
+ TestLog.Info($"NUnit Adapter {AdapterVersion}: Test execution complete");
+ Unload();
+ }
-#endregion
+ private bool IsInProcDataCollectorsSpecifiedWithMultipleAssemblies(
+ IEnumerable> assemblyGroups)
+ => Settings.InProcDataCollectorsAvailable && assemblyGroups.Count() > 1;
-#region IDisposable Implementation
+ void ITestExecutor.Cancel()
+ {
+ StopRun();
+ }
- public void Dispose()
- {
- // TODO: Nothing here at the moment. Check what needs disposing, if anything. Otherwise, remove.
- }
+ #endregion
-#endregion
+ #region IDisposable Implementation
-#region Helper Methods
+ public void Dispose()
+ {
+ // TODO: Nothing here at the moment. Check what needs disposing, if anything. Otherwise, remove.
+ }
- public void InitializeForExecution(IRunContext runContext, IFrameworkHandle frameworkHandle)
- {
- TestLog.Info($"NUnit Adapter {AdapterVersion}: Test execution started");
+ #endregion
- RunContext = runContext;
- FrameworkHandle = frameworkHandle;
- VsTestFilter = VsTestFilterFactory.CreateVsTestFilter(Settings, runContext);
+ #region Helper Methods
- CleanUpRegisteredChannels();
+ public void InitializeForExecution(IRunContext runContext, IFrameworkHandle frameworkHandle)
+ {
+ TestLog.Info($"NUnit Adapter {AdapterVersion}: Test execution started");
- TestLog.Debug("KeepAlive: " + runContext.KeepAlive);
- TestLog.Debug("UseVsKeepEngineRunning: " + Settings.UseVsKeepEngineRunning);
+ RunContext = runContext;
+ FrameworkHandle = frameworkHandle;
+ VsTestFilter = VsTestFilterFactory.CreateVsTestFilter(Settings, runContext);
- bool enableShutdown = true;
- if (Settings.UseVsKeepEngineRunning)
- {
- enableShutdown = !runContext.KeepAlive;
- }
+ CleanUpRegisteredChannels();
- if (VsTestFilter.IsEmpty)
- {
- if (!(enableShutdown &&
- !runContext
- .KeepAlive)) // Otherwise causes exception when run as commandline, illegal to enableshutdown when Keepalive is false, might be only VS2012
- frameworkHandle.EnableShutdownAfterTestRun = enableShutdown;
- }
+ TestLog.Debug("KeepAlive: " + runContext.KeepAlive);
+ TestLog.Debug("UseVsKeepEngineRunning: " + Settings.UseVsKeepEngineRunning);
- TestLog.Debug("EnableShutdown: " + enableShutdown);
+ bool enableShutdown = true;
+ if (Settings.UseVsKeepEngineRunning)
+ {
+ enableShutdown = !runContext.KeepAlive;
}
- private void RunAssembly(string assemblyPath, IGrouping testCases, TestFilter filter)
+ if (VsTestFilter.IsEmpty)
{
- LogActionAndSelection(assemblyPath, filter);
- RestoreRandomSeed(assemblyPath);
- Dump = DumpXml.CreateDump(assemblyPath, testCases, Settings);
+ if (!(enableShutdown &&
+ !runContext
+ .KeepAlive)) // Otherwise causes exception when run as commandline, illegal to enableshutdown when Keepalive is false, might be only VS2012
+ frameworkHandle.EnableShutdownAfterTestRun = enableShutdown;
+ }
- try
+ TestLog.Debug("EnableShutdown: " + enableShutdown);
+ }
+
+ private void RunAssembly(string assemblyPath, IGrouping testCases, TestFilter filter)
+ {
+ LogActionAndSelection(assemblyPath, filter);
+ RestoreRandomSeed(assemblyPath);
+ Dump = DumpXml.CreateDump(assemblyPath, testCases, Settings);
+
+ try
+ {
+ var package = CreateTestPackage(assemblyPath, testCases);
+ NUnitEngineAdapter.CreateRunner(package);
+ CreateTestOutputFolder();
+ Dump?.StartDiscoveryInExecution(testCases, filter, package);
+ TestLog.DebugRunfrom();
+ // var discoveryResults = RunType == RunType.CommandLineCurrentNUnit ? null : NUnitEngineAdapter.Explore(filter);
+ var discoveryResults = NUnitEngineAdapter.Explore(filter);
+ Dump?.AddString(discoveryResults?.AsString() ?? " No discovery");
+
+ if (discoveryResults?.IsRunnable ?? true)
{
- var package = CreateTestPackage(assemblyPath, testCases);
- NUnitEngineAdapter.CreateRunner(package);
- CreateTestOutputFolder();
- Dump?.StartDiscoveryInExecution(testCases, filter, package);
- TestLog.DebugRunfrom();
- // var discoveryResults = RunType == RunType.CommandLineCurrentNUnit ? null : NUnitEngineAdapter.Explore(filter);
- var discoveryResults = NUnitEngineAdapter.Explore(filter);
- Dump?.AddString(discoveryResults?.AsString() ?? " No discovery");
-
- if (discoveryResults?.IsRunnable ?? true)
+ var discovery = new DiscoveryConverter(TestLog, Settings);
+ discovery.Convert(discoveryResults, assemblyPath);
+ if (!Settings.SkipExecutionWhenNoTests || discovery.AllTestCases.Any())
{
- var discovery = new DiscoveryConverter(TestLog, Settings);
- discovery.Convert(discoveryResults, assemblyPath);
- if (!Settings.SkipExecutionWhenNoTests || discovery.AllTestCases.Any())
- {
- var ea = ExecutionFactory.Create(this);
- ea.Run(filter, discovery, this);
- }
- else
- {
- TestLog.InfoNoTests(assemblyPath);
- }
+ var ea = ExecutionFactory.Create(this);
+ ea.Run(filter, discovery, this);
}
else
{
- TestLog.InfoNoTests(discoveryResults.HasNoNUnitTests, assemblyPath);
+ TestLog.InfoNoTests(assemblyPath);
}
}
- catch (Exception ex) when (ex is BadImageFormatException || ex.InnerException is BadImageFormatException)
+ else
{
- // we skip the native c++ binaries that we don't support.
- TestLog.Warning(" Assembly not supported: " + assemblyPath);
+ TestLog.InfoNoTests(discoveryResults.HasNoNUnitTests, assemblyPath);
}
- catch (FileNotFoundException ex)
+ }
+ catch (Exception ex) when (ex is BadImageFormatException || ex.InnerException is BadImageFormatException)
+ {
+ // we skip the native c++ binaries that we don't support.
+ TestLog.Warning(" Assembly not supported: " + assemblyPath);
+ }
+ catch (FileNotFoundException ex)
+ {
+ // Probably from the GetExportedTypes in NUnit.core, attempting to find an assembly, not a problem if it is not NUnit here
+ TestLog.Warning(" Dependent Assembly " + ex.FileName + " of " + assemblyPath +
+ " not found. Can be ignored if not an NUnit project.");
+ }
+ catch (Exception ex)
+ {
+ if (ex is TargetInvocationException)
+ ex = ex.InnerException;
+ TestLog.Warning(" Exception thrown executing tests in " + assemblyPath, ex);
+ }
+ finally
+ {
+ Dump?.DumpForExecution();
+ try
{
- // Probably from the GetExportedTypes in NUnit.core, attempting to find an assembly, not a problem if it is not NUnit here
- TestLog.Warning(" Dependent Assembly " + ex.FileName + " of " + assemblyPath +
- " not found. Can be ignored if not an NUnit project.");
+ NUnitEngineAdapter?.CloseRunner();
}
catch (Exception ex)
{
- if (ex is TargetInvocationException)
- ex = ex.InnerException;
- TestLog.Warning(" Exception thrown executing tests in " + assemblyPath, ex);
- }
- finally
- {
- Dump?.DumpForExecution();
- try
- {
- NUnitEngineAdapter?.CloseRunner();
- }
- catch (Exception ex)
- {
- // can happen if CLR throws CannotUnloadAppDomainException, for example
- // due to a long-lasting operation in a protected region (catch/finally clause).
- if (ex is TargetInvocationException) { ex = ex.InnerException; }
+ // can happen if CLR throws CannotUnloadAppDomainException, for example
+ // due to a long-lasting operation in a protected region (catch/finally clause).
+ if (ex is TargetInvocationException) { ex = ex.InnerException; }
- TestLog.Warning($" Exception thrown unloading tests from {assemblyPath}", ex);
- }
+ TestLog.Warning($" Exception thrown unloading tests from {assemblyPath}", ex);
}
}
+ }
- private void LogActionAndSelection(string assemblyPath, TestFilter filter)
- {
- string actionText = Debugger.IsAttached ? "Debugging " : "Running ";
- string selectionText = filter == null || filter == TestFilter.Empty ? "all" : "selected";
- TestLog.Info(actionText + selectionText + " tests in " + assemblyPath);
- }
+ private void LogActionAndSelection(string assemblyPath, TestFilter filter)
+ {
+ string actionText = Debugger.IsAttached ? "Debugging " : "Running ";
+ string selectionText = filter == null || filter == TestFilter.Empty ? "all" : "selected";
+ TestLog.Info(actionText + selectionText + " tests in " + assemblyPath);
+ }
- private void RestoreRandomSeed(string assemblyPath)
- {
- // No need to restore if the seed was in runsettings file
- if (!Settings.RandomSeedSpecified)
- Settings.RestoreRandomSeed(Path.GetDirectoryName(assemblyPath));
- }
+ private void RestoreRandomSeed(string assemblyPath)
+ {
+ // No need to restore if the seed was in runsettings file
+ if (!Settings.RandomSeedSpecified)
+ Settings.RestoreRandomSeed(Path.GetDirectoryName(assemblyPath));
+ }
- private NUnitTestFilterBuilder CreateTestFilterBuilder() => new(NUnitEngineAdapter.GetService(), Settings);
+ private NUnitTestFilterBuilder CreateTestFilterBuilder() => new(NUnitEngineAdapter.GetService(), Settings);
- ///
- /// Must be called after WorkDir have been set.
- ///
- private void CreateTestOutputFolder()
+ ///
+ /// Must be called after WorkDir have been set.
+ ///
+ private void CreateTestOutputFolder()
+ {
+ if (!Settings.UseTestOutputXml)
{
- if (!Settings.UseTestOutputXml)
- {
- return;
- }
- string path = Settings.SetTestOutputFolder(WorkDir);
- try
- {
- Directory.CreateDirectory(path);
- TestOutputXmlFolder = path;
- TestLog.Info($" Test Output folder checked/created : {path} ");
- }
- catch (UnauthorizedAccessException)
- {
- TestLog.Error($" Failed creating test output folder at {path}");
- throw;
- }
+ return;
}
-
-#endregion
-
- public void StopRun()
+ string path = Settings.SetTestOutputFolder(WorkDir);
+ try
{
- NUnitEngineAdapter?.StopRun();
+ Directory.CreateDirectory(path);
+ TestOutputXmlFolder = path;
+ TestLog.Info($" Test Output folder checked/created : {path} ");
}
-
- public IDumpXml Dump { get; private set; }
-
- private void CheckIfDebug()
+ catch (UnauthorizedAccessException)
{
- if (!Settings.DebugExecution)
- return;
- if (!Debugger.IsAttached)
- Debugger.Launch();
+ TestLog.Error($" Failed creating test output folder at {path}");
+ throw;
}
}
+
+ #endregion
+
+ public void StopRun()
+ {
+ NUnitEngineAdapter?.StopRun();
+ }
+
+ public IDumpXml Dump { get; private set; }
+
+ private void CheckIfDebug()
+ {
+ if (!Settings.DebugExecution)
+ return;
+ if (!Debugger.IsAttached)
+ Debugger.Launch();
+ }
}
\ No newline at end of file
diff --git a/src/NUnitTestAdapter/NUnitEngine/DiscoveryConverter.cs b/src/NUnitTestAdapter/NUnitEngine/DiscoveryConverter.cs
index a031b2f1..65ae6940 100644
--- a/src/NUnitTestAdapter/NUnitEngine/DiscoveryConverter.cs
+++ b/src/NUnitTestAdapter/NUnitEngine/DiscoveryConverter.cs
@@ -26,448 +26,434 @@
using System.Linq;
using System.Xml;
using System.Xml.Linq;
+
using Microsoft.VisualStudio.TestPlatform.ObjectModel;
+
using NUnit.VisualStudio.TestAdapter.Internal;
-namespace NUnit.VisualStudio.TestAdapter.NUnitEngine
+namespace NUnit.VisualStudio.TestAdapter.NUnitEngine;
+
+public interface IDiscoveryConverter
{
- public interface IDiscoveryConverter
- {
- IEnumerable AllTestCases { get; }
- bool IsExplicitRun { get; }
- IList LoadedTestCases { get; }
- int NoOfLoadedTestCases { get; }
-
- ///
- /// Checks if we're running the latest Current DiscoveryMethod.
- ///
- bool IsDiscoveryMethodCurrent { get; }
-
- bool NoOfLoadedTestCasesAboveLimit { get; }
- int NoOfExplicitTestCases { get; }
- bool HasExplicitTests { get; }
- IEnumerable GetExplicitTestCases(IEnumerable filteredTestCases);
- }
+ IEnumerable AllTestCases { get; }
+ bool IsExplicitRun { get; }
+ IList LoadedTestCases { get; }
+ int NoOfLoadedTestCases { get; }
+
+ ///
+ /// Checks if we're running the latest Current DiscoveryMethod.
+ ///
+ bool IsDiscoveryMethodCurrent { get; }
+
+ bool NoOfLoadedTestCasesAboveLimit { get; }
+ int NoOfExplicitTestCases { get; }
+ bool HasExplicitTests { get; }
+ IEnumerable GetExplicitTestCases(IEnumerable filteredTestCases);
+}
- public class DiscoveryConverter : IDiscoveryConverter
- {
- private const string ParameterizedFixture = nameof(ParameterizedFixture);
- private const string TestFixture = nameof(TestFixture);
- private const string GenericFixture = nameof(GenericFixture);
- private const string SetUpFixture = nameof(SetUpFixture);
- private const string TestSuite = nameof(TestSuite);
+public class DiscoveryConverter(ITestLogger logger, IAdapterSettings settings) : IDiscoveryConverter
+{
+ private const string ParameterizedFixture = nameof(ParameterizedFixture);
+ private const string TestFixture = nameof(TestFixture);
+ private const string GenericFixture = nameof(GenericFixture);
+ private const string SetUpFixture = nameof(SetUpFixture);
+ private const string TestSuite = nameof(TestSuite);
- internal static class NUnitXmlAttributeNames
- {
- public const string Id = "id";
- public const string Type = "type";
- public const string Name = "name";
- public const string Fullname = "fullname";
- public const string Runstate = "runstate";
- public const string Testcasecount = "testcasecount";
- public const string Classname = "classname";
- public const string Methodname = "methodname";
- public const string Seed = "seed";
- }
+ internal static class NUnitXmlAttributeNames
+ {
+ public const string Id = "id";
+ public const string Type = "type";
+ public const string Name = "name";
+ public const string Fullname = "fullname";
+ public const string Runstate = "runstate";
+ public const string Testcasecount = "testcasecount";
+ public const string Classname = "classname";
+ public const string Methodname = "methodname";
+ public const string Seed = "seed";
+ }
- private ITestConverterXml converterForXml;
- private ITestConverter converter;
+ private ITestConverterXml converterForXml;
+ private ITestConverter converter;
- public ITestConverterCommon TestConverterForXml => converterForXml;
+ public ITestConverterCommon TestConverterForXml => converterForXml;
- public ITestConverterCommon TestConverter => converter;
+ public ITestConverterCommon TestConverter => converter;
- public NUnitDiscoveryTestRun TestRun { get; private set; }
+ public NUnitDiscoveryTestRun TestRun { get; private set; }
- ///
- /// Checks if we're running the latest Current DiscoveryMethod.
- ///
- public bool IsDiscoveryMethodCurrent => Settings.DiscoveryMethod == DiscoveryMethod.Current;
+ ///
+ /// Checks if we're running the latest Current DiscoveryMethod.
+ ///
+ public bool IsDiscoveryMethodCurrent => Settings.DiscoveryMethod == DiscoveryMethod.Current;
- public NUnitDiscoveryTestAssembly CurrentTestAssembly => TestRun.TestAssembly;
+ public NUnitDiscoveryTestAssembly CurrentTestAssembly => TestRun.TestAssembly;
- public NUnitDiscoveryTestSuite TopLevelTestSuite => CurrentTestAssembly.TestSuites.FirstOrDefault();
+ public NUnitDiscoveryTestSuite TopLevelTestSuite => CurrentTestAssembly.TestSuites.FirstOrDefault();
- public IEnumerable AllTestCases => CurrentTestAssembly.AllTestCases;
+ public IEnumerable AllTestCases => CurrentTestAssembly.AllTestCases;
- public bool IsExplicitRun => CurrentTestAssembly?.IsExplicit ?? false;
+ public bool IsExplicitRun => CurrentTestAssembly?.IsExplicit ?? false;
- public int NoOfExplicitTestCases => CurrentTestAssembly.NoOfExplicitTestCases;
+ public int NoOfExplicitTestCases => CurrentTestAssembly.NoOfExplicitTestCases;
- public bool HasExplicitTests => NoOfExplicitTestCases > 0;
+ public bool HasExplicitTests => NoOfExplicitTestCases > 0;
- private readonly List loadedTestCases = new ();
- public IList LoadedTestCases => loadedTestCases;
+ private readonly List loadedTestCases = new();
+ public IList LoadedTestCases => loadedTestCases;
- public int NoOfLoadedTestCases => loadedTestCases.Count;
+ public int NoOfLoadedTestCases => loadedTestCases.Count;
- public string AssemblyPath { get; private set; }
+ public string AssemblyPath { get; private set; }
- private IAdapterSettings Settings { get; }
- private ITestLogger TestLog { get; }
+ private IAdapterSettings Settings { get; } = settings;
+ private ITestLogger TestLog { get; } = logger;
- public bool NoOfLoadedTestCasesAboveLimit => NoOfLoadedTestCases > Settings.AssemblySelectLimit;
- public IEnumerable GetExplicitTestCases(IEnumerable filteredTestCases)
+ public bool NoOfLoadedTestCasesAboveLimit => NoOfLoadedTestCases > Settings.AssemblySelectLimit;
+ public IEnumerable GetExplicitTestCases(IEnumerable filteredTestCases)
+ {
+ var explicitCases = new List();
+ foreach (var tc in filteredTestCases)
{
- var explicitCases = new List();
- foreach (var tc in filteredTestCases)
+ var correspondingNUnitTestCase = AllTestCases.FirstOrDefault(o => o.FullName == tc.FullyQualifiedName);
+ if (correspondingNUnitTestCase == null)
{
- var correspondingNUnitTestCase = AllTestCases.FirstOrDefault(o => o.FullName == tc.FullyQualifiedName);
- if (correspondingNUnitTestCase == null)
- {
- TestLog.Warning(
- $"CheckExplicit: Can't locate corresponding NUnit testcase {tc.FullyQualifiedName}");
- continue;
- }
-
- if (correspondingNUnitTestCase.IsExplicitReverse)
- explicitCases.Add(tc);
+ TestLog.Warning(
+ $"CheckExplicit: Can't locate corresponding NUnit testcase {tc.FullyQualifiedName}");
+ continue;
}
- return explicitCases;
+
+ if (correspondingNUnitTestCase.IsExplicitReverse)
+ explicitCases.Add(tc);
}
+ return explicitCases;
+ }
- public DiscoveryConverter(ITestLogger logger, IAdapterSettings settings)
+ public IList Convert(NUnitResults discoveryResults, string assemblyPath)
+ {
+ if (discoveryResults == null)
+ return new List();
+ AssemblyPath = assemblyPath;
+ var timing = new TimingLogger(Settings, TestLog);
+ if (Settings.DiscoveryMethod != DiscoveryMethod.Legacy)
{
- Settings = settings;
- TestLog = logger;
+ TestRun = ConvertXml(discoveryResults);
}
- public IList Convert(NUnitResults discoveryResults, string assemblyPath)
- {
- if (discoveryResults == null)
- return new List();
- AssemblyPath = assemblyPath;
- var timing = new TimingLogger(Settings, TestLog);
- if (Settings.DiscoveryMethod != DiscoveryMethod.Legacy)
- {
- TestRun = ConvertXml(discoveryResults);
- }
-
- var nunitTestCases = discoveryResults.TestCases();
-
- // As a side effect of calling TestConverter.ConvertTestCase,
- // the converter's cache of all test cases is populated as well.
- // All future calls to convert a test case may now use the cache.
+ var nunitTestCases = discoveryResults.TestCases();
- if (Settings.DiscoveryMethod == DiscoveryMethod.Legacy)
- {
- converterForXml = new TestConverterForXml(TestLog, AssemblyPath, Settings);
- foreach (XmlNode testNode in nunitTestCases)
- loadedTestCases.Add(converterForXml.ConvertTestCase(new NUnitEventTestCase(testNode)));
- TestLog.Info(
- $" NUnit3TestExecutor discovered {loadedTestCases.Count} of {nunitTestCases.Count} NUnit test cases using Legacy discovery mode");
- }
- else
- {
- converter = new TestConverter(TestLog, AssemblyPath, Settings, this);
- var isExplicit = TestRun.IsExplicit;
- var testCases = RunnableTestCases(isExplicit);
- foreach (var testNode in testCases)
- loadedTestCases.Add(converter.ConvertTestCase(testNode));
- var msg = isExplicit ? "Explicit run" : "Non-Explicit run";
- TestLog.Info(
- $" NUnit3TestExecutor discovered {loadedTestCases.Count} of {nunitTestCases.Count} NUnit test cases using Current Discovery mode, {msg}");
- }
-
- timing.LogTime("Converting test cases ");
- return loadedTestCases;
-
- IEnumerable RunnableTestCases(bool isExplicit) =>
- isExplicit
- ? TestRun.TestAssembly.AllTestCases
- : TestRun.TestAssembly.RunnableTestCases;
- }
+ // As a side effect of calling TestConverter.ConvertTestCase,
+ // the converter's cache of all test cases is populated as well.
+ // All future calls to convert a test case may now use the cache.
- public NUnitDiscoveryTestRun ConvertXml(NUnitResults discovery)
+ if (Settings.DiscoveryMethod == DiscoveryMethod.Legacy)
{
- var doc = XDocument.Load(new XmlNodeReader(discovery.FullTopNode));
- var testrun = ExtractTestRun(doc);
- var anode = doc.Root.Elements("test-suite");
- var assemblyNode = anode.Single(o => o.Attribute(NUnitXmlAttributeNames.Type).Value == "Assembly");
- var testassembly = ExtractTestAssembly(assemblyNode, testrun);
- ExtractAllFixtures(testassembly, assemblyNode);
- return testrun;
+ converterForXml = new TestConverterForXml(TestLog, AssemblyPath, Settings);
+ foreach (XmlNode testNode in nunitTestCases)
+ loadedTestCases.Add(converterForXml.ConvertTestCase(new NUnitEventTestCase(testNode)));
+ TestLog.Info(
+ $" NUnit3TestExecutor discovered {loadedTestCases.Count} of {nunitTestCases.Count} NUnit test cases using Legacy discovery mode");
}
-
- private static NUnitDiscoveryTestSuite ExtractTestSuite(XElement node, NUnitDiscoverySuiteBase parent)
+ else
{
- var b = ExtractSuiteBasePropertiesClass(node);
- var ts = new NUnitDiscoveryTestSuite(b, parent);
- return ts;
+ converter = new TestConverter(TestLog, AssemblyPath, Settings, this);
+ var isExplicit = TestRun.IsExplicit;
+ var testCases = RunnableTestCases(isExplicit);
+ foreach (var testNode in testCases)
+ loadedTestCases.Add(converter.ConvertTestCase(testNode));
+ var msg = isExplicit ? "Explicit run" : "Non-Explicit run";
+ TestLog.Info(
+ $" NUnit3TestExecutor discovered {loadedTestCases.Count} of {nunitTestCases.Count} NUnit test cases using Current Discovery mode, {msg}");
}
- private void ExtractAllFixtures(NUnitDiscoveryCanHaveTestFixture parent, XElement node)
+ timing.LogTime("Converting test cases ");
+ return loadedTestCases;
+
+ IEnumerable RunnableTestCases(bool isExplicit) =>
+ isExplicit
+ ? TestRun.TestAssembly.AllTestCases
+ : TestRun.TestAssembly.RunnableTestCases;
+ }
+
+ public NUnitDiscoveryTestRun ConvertXml(NUnitResults discovery)
+ {
+ var doc = XDocument.Load(new XmlNodeReader(discovery.FullTopNode));
+ var testrun = ExtractTestRun(doc);
+ var anode = doc.Root.Elements("test-suite");
+ var assemblyNode = anode.Single(o => o.Attribute(NUnitXmlAttributeNames.Type).Value == "Assembly");
+ var testassembly = ExtractTestAssembly(assemblyNode, testrun);
+ ExtractAllFixtures(testassembly, assemblyNode);
+ return testrun;
+ }
+
+ private static NUnitDiscoveryTestSuite ExtractTestSuite(XElement node, NUnitDiscoverySuiteBase parent)
+ {
+ var b = ExtractSuiteBasePropertiesClass(node);
+ var ts = new NUnitDiscoveryTestSuite(b, parent);
+ return ts;
+ }
+
+ private void ExtractAllFixtures(NUnitDiscoveryCanHaveTestFixture parent, XElement node)
+ {
+ foreach (var child in node.Elements("test-suite"))
{
- foreach (var child in node.Elements("test-suite"))
+ var type = child.Attribute(NUnitXmlAttributeNames.Type)?.Value;
+ if (type == null)
{
- var type = child.Attribute(NUnitXmlAttributeNames.Type)?.Value;
- if (type == null)
- {
- TestLog.Debug($"ETF1:Don't understand element: {child}");
- continue;
- }
-
- var className = child.Attribute(NUnitXmlAttributeNames.Classname)?.Value;
- switch (type)
- {
- case TestFixture:
- var tf = ExtractTestFixture(parent, child, className);
- parent.AddTestFixture(tf);
- ExtractTestCases(tf, child);
- ExtractParameterizedMethodsAndTheories(tf, child);
- break;
- case GenericFixture:
- var gtf = ExtractGenericTestFixture(parent, child);
- parent.AddTestGenericFixture(gtf);
- ExtractTestFixtures(gtf, child);
- break;
- case ParameterizedFixture:
- var ptf = ExtractParameterizedTestFixture(parent, child);
- parent.AddParameterizedFixture(ptf);
- ExtractTestFixtures(ptf, child);
- break;
- case SetUpFixture:
- var stf = ExtractSetUpTestFixture(parent, child, className);
- parent.AddSetUpFixture(stf);
- ExtractTestFixtures(stf, child);
- break;
- case TestSuite:
- var ts = ExtractTestSuite(child, parent);
- parent.AddTestSuite(ts);
- if (child.HasElements)
- ExtractAllFixtures(ts, child);
- break;
- default:
- throw new DiscoveryException($"Invalid type found in ExtractAllFixtures for test suite: {type}");
- }
+ TestLog.Debug($"ETF1:Don't understand element: {child}");
+ continue;
}
- }
- private void ExtractTestFixtures(NUnitDiscoveryCanHaveTestFixture parent, XElement node)
- {
- foreach (var child in node.Elements().Where(o => o.Name != "properties"))
+ var className = child.Attribute(NUnitXmlAttributeNames.Classname)?.Value;
+ switch (type)
{
- var type = child.Attribute(NUnitXmlAttributeNames.Type)?.Value;
- if (type == null)
- {
- TestLog.Debug($"ETF2:Don't understand element: {child}");
- continue;
- }
- var className = child.Attribute(NUnitXmlAttributeNames.Classname)?.Value;
- var btf = ExtractSuiteBasePropertiesClass(child);
- switch (type)
- {
- case TestFixture:
- var tf = new NUnitDiscoveryTestFixture(btf, className, parent);
- parent.AddTestFixture(tf);
- ExtractTestCases(tf, child);
- ExtractParameterizedMethodsAndTheories(tf, child);
- break;
- case TestSuite:
- var ts = ExtractTestSuite(child, parent);
- parent.AddTestSuite(ts);
- if (child.HasElements)
- ExtractAllFixtures(ts, child);
- break;
- case SetUpFixture:
- var tsf = ExtractSetUpTestFixture(parent, node, className);
- parent.AddSetUpFixture(tsf);
- if (child.HasElements)
- {
- ExtractTestFixtures(tsf, child);
- }
- break;
- case ParameterizedFixture:
- var ptf = ExtractParameterizedTestFixture(parent, node);
- parent.AddParameterizedFixture(ptf);
- if (child.HasElements)
- {
- ExtractTestFixtures(ptf, child);
- }
- break;
- case GenericFixture:
- var gf = ExtractGenericTestFixture(parent, node);
- parent.AddTestGenericFixture(gf);
- if (child.HasElements)
- {
- ExtractTestFixtures(gf, child);
- }
- break;
- default:
- throw new DiscoveryException($"Not a TestFixture, SetUpFixture, ParameterizedFixture, GenericFixture or TestSuite, but {type}");
- }
+ case TestFixture:
+ var tf = ExtractTestFixture(parent, child, className);
+ parent.AddTestFixture(tf);
+ ExtractTestCases(tf, child);
+ ExtractParameterizedMethodsAndTheories(tf, child);
+ break;
+ case GenericFixture:
+ var gtf = ExtractGenericTestFixture(parent, child);
+ parent.AddTestGenericFixture(gtf);
+ ExtractTestFixtures(gtf, child);
+ break;
+ case ParameterizedFixture:
+ var ptf = ExtractParameterizedTestFixture(parent, child);
+ parent.AddParameterizedFixture(ptf);
+ ExtractTestFixtures(ptf, child);
+ break;
+ case SetUpFixture:
+ var stf = ExtractSetUpTestFixture(parent, child, className);
+ parent.AddSetUpFixture(stf);
+ ExtractTestFixtures(stf, child);
+ break;
+ case TestSuite:
+ var ts = ExtractTestSuite(child, parent);
+ parent.AddTestSuite(ts);
+ if (child.HasElements)
+ ExtractAllFixtures(ts, child);
+ break;
+ default:
+ throw new DiscoveryException($"Invalid type found in ExtractAllFixtures for test suite: {type}");
}
}
+ }
- private static void ExtractParameterizedMethodsAndTheories(NUnitDiscoveryTestFixture tf, XElement node)
+ private void ExtractTestFixtures(NUnitDiscoveryCanHaveTestFixture parent, XElement node)
+ {
+ foreach (var child in node.Elements().Where(o => o.Name != "properties"))
{
- const string parameterizedMethod = "ParameterizedMethod";
- const string theory = "Theory";
- foreach (var child in node.Elements("test-suite"))
+ var type = child.Attribute(NUnitXmlAttributeNames.Type)?.Value;
+ if (type == null)
{
- var type = child.Attribute(NUnitXmlAttributeNames.Type)?.Value;
- if (type != parameterizedMethod && type != "Theory" && type != "GenericMethod")
- throw new DiscoveryException($"Expected ParameterizedMethod, Theory or GenericMethod, but was {type}");
- var className = child.Attribute(NUnitXmlAttributeNames.Classname)?.Value;
- var btf = ExtractSuiteBasePropertiesClass(child);
- switch (type)
- {
- case parameterizedMethod:
- {
- var tc = new NUnitDiscoveryParameterizedMethod(btf, className, tf);
- ExtractTestCases(tc, child);
- tf.AddParameterizedMethod(tc);
- break;
- }
- case theory:
- {
- var tc = new NUnitDiscoveryTheory(btf, className, tf);
- tf.AddTheory(tc);
- ExtractTestCases(tc, child);
- break;
- }
- default:
- {
- var tc = new NUnitDiscoveryGenericMethod(btf, className, tf);
- tf.AddGenericMethod(tc);
- ExtractTestCases(tc, child);
- break;
- }
- }
+ TestLog.Debug($"ETF2:Don't understand element: {child}");
+ continue;
}
- }
-
- public static IEnumerable ExtractTestCases(INUnitDiscoveryCanHaveTestCases tf, XElement node)
- {
- foreach (var child in node.Elements("test-case"))
+ var className = child.Attribute(NUnitXmlAttributeNames.Classname)?.Value;
+ var btf = ExtractSuiteBasePropertiesClass(child);
+ switch (type)
{
- var tc = ExtractTestCase(tf, child);
- tf.AddTestCase(tc);
+ case TestFixture:
+ var tf = new NUnitDiscoveryTestFixture(btf, className, parent);
+ parent.AddTestFixture(tf);
+ ExtractTestCases(tf, child);
+ ExtractParameterizedMethodsAndTheories(tf, child);
+ break;
+ case TestSuite:
+ var ts = ExtractTestSuite(child, parent);
+ parent.AddTestSuite(ts);
+ if (child.HasElements)
+ ExtractAllFixtures(ts, child);
+ break;
+ case SetUpFixture:
+ var tsf = ExtractSetUpTestFixture(parent, node, className);
+ parent.AddSetUpFixture(tsf);
+ if (child.HasElements)
+ {
+ ExtractTestFixtures(tsf, child);
+ }
+ break;
+ case ParameterizedFixture:
+ var ptf = ExtractParameterizedTestFixture(parent, node);
+ parent.AddParameterizedFixture(ptf);
+ if (child.HasElements)
+ {
+ ExtractTestFixtures(ptf, child);
+ }
+ break;
+ case GenericFixture:
+ var gf = ExtractGenericTestFixture(parent, node);
+ parent.AddTestGenericFixture(gf);
+ if (child.HasElements)
+ {
+ ExtractTestFixtures(gf, child);
+ }
+ break;
+ default:
+ throw new DiscoveryException($"Not a TestFixture, SetUpFixture, ParameterizedFixture, GenericFixture or TestSuite, but {type}");
}
-
- return tf.TestCases;
}
+ }
- ///
- /// Extracts single test case, made public for testing.
- ///
- public static NUnitDiscoveryTestCase ExtractTestCase(INUnitDiscoveryCanHaveTestCases tf, XElement child)
+ private static void ExtractParameterizedMethodsAndTheories(NUnitDiscoveryTestFixture tf, XElement node)
+ {
+ const string parameterizedMethod = "ParameterizedMethod";
+ const string theory = "Theory";
+ foreach (var child in node.Elements("test-suite"))
{
+ var type = child.Attribute(NUnitXmlAttributeNames.Type)?.Value;
+ if (type != parameterizedMethod && type != "Theory" && type != "GenericMethod")
+ throw new DiscoveryException($"Expected ParameterizedMethod, Theory or GenericMethod, but was {type}");
var className = child.Attribute(NUnitXmlAttributeNames.Classname)?.Value;
- var methodName = child.Attribute(NUnitXmlAttributeNames.Methodname)?.Value;
- var seedAtr = child.Attribute(NUnitXmlAttributeNames.Seed)?.Value;
- var seed = seedAtr != null ? long.Parse(seedAtr, CultureInfo.InvariantCulture) : 0;
var btf = ExtractSuiteBasePropertiesClass(child);
- var tc = new NUnitDiscoveryTestCase(btf, tf, className, methodName, seed);
- return tc;
- }
-
-
- public static NUnitDiscoveryTestFixture ExtractTestFixture(INUnitDiscoveryCanHaveTestFixture parent, XElement node,
- string className)
- {
- var b = ExtractSuiteBasePropertiesClass(node);
- var ts = new NUnitDiscoveryTestFixture(b, className, parent);
- return ts;
+ switch (type)
+ {
+ case parameterizedMethod:
+ {
+ var tc = new NUnitDiscoveryParameterizedMethod(btf, className, tf);
+ ExtractTestCases(tc, child);
+ tf.AddParameterizedMethod(tc);
+ break;
+ }
+ case theory:
+ {
+ var tc = new NUnitDiscoveryTheory(btf, className, tf);
+ tf.AddTheory(tc);
+ ExtractTestCases(tc, child);
+ break;
+ }
+ default:
+ {
+ var tc = new NUnitDiscoveryGenericMethod(btf, className, tf);
+ tf.AddGenericMethod(tc);
+ ExtractTestCases(tc, child);
+ break;
+ }
+ }
}
+ }
- private static NUnitDiscoveryGenericFixture ExtractGenericTestFixture(
- NUnitDiscoveryCanHaveTestFixture parent,
- XElement node)
- {
- var b = ExtractSuiteBasePropertiesClass(node);
- var ts = new NUnitDiscoveryGenericFixture(b, parent);
- return ts;
- }
- private static NUnitDiscoverySetUpFixture ExtractSetUpTestFixture(
- NUnitDiscoveryCanHaveTestFixture parent,
- XElement node, string className)
- {
- var b = ExtractSuiteBasePropertiesClass(node);
- var ts = new NUnitDiscoverySetUpFixture(b, className, parent);
- return ts;
- }
- private static NUnitDiscoveryParameterizedTestFixture ExtractParameterizedTestFixture(
- NUnitDiscoveryCanHaveTestFixture parent, XElement node)
+ public static IEnumerable ExtractTestCases(INUnitDiscoveryCanHaveTestCases tf, XElement node)
+ {
+ foreach (var child in node.Elements("test-case"))
{
- var b = ExtractSuiteBasePropertiesClass(node);
- var ts = new NUnitDiscoveryParameterizedTestFixture(b, parent);
- return ts;
+ var tc = ExtractTestCase(tf, child);
+ tf.AddTestCase(tc);
}
- private NUnitDiscoveryTestAssembly ExtractTestAssembly(XElement node, NUnitDiscoveryTestRun parent)
- {
- string dType = node.Attribute(NUnitXmlAttributeNames.Type)?.Value;
- if (dType is not "Assembly")
- throw new DiscoveryException("Node is not of type assembly: " + node);
- var aBase = ExtractSuiteBasePropertiesClass(node);
- var assembly = new NUnitDiscoveryTestAssembly(aBase, parent);
- parent.AddTestAssembly(assembly);
- return assembly;
- }
+ return tf.TestCases;
+ }
- private static BaseProperties ExtractSuiteBasePropertiesClass(XElement node)
- {
- string dId = node.Attribute(NUnitXmlAttributeNames.Id).Value;
- string dName = node.Attribute(NUnitXmlAttributeNames.Name).Value;
- string dFullname = node.Attribute(NUnitXmlAttributeNames.Fullname).Value;
- var dRunstate = ExtractRunState(node);
- const char apo = '\'';
- var tcs = node.Attribute(NUnitXmlAttributeNames.Testcasecount)?.Value.Trim(apo);
- int dTestcasecount = int.Parse(tcs ?? "1", CultureInfo.InvariantCulture);
- var bp = new BaseProperties(dId, dName, dFullname, dTestcasecount, dRunstate);
-
- foreach (var propnode in node.Elements("properties").Elements("property"))
- {
- var prop = new NUnitProperty(propnode);
- bp.Properties.Add(prop);
- }
- return bp;
- }
+ ///
+ /// Extracts single test case, made public for testing.
+ ///
+ public static NUnitDiscoveryTestCase ExtractTestCase(INUnitDiscoveryCanHaveTestCases tf, XElement child)
+ {
+ var className = child.Attribute(NUnitXmlAttributeNames.Classname)?.Value;
+ var methodName = child.Attribute(NUnitXmlAttributeNames.Methodname)?.Value;
+ var seedAtr = child.Attribute(NUnitXmlAttributeNames.Seed)?.Value;
+ var seed = seedAtr != null ? long.Parse(seedAtr, CultureInfo.InvariantCulture) : 0;
+ var btf = ExtractSuiteBasePropertiesClass(child);
+ var tc = new NUnitDiscoveryTestCase(btf, tf, className, methodName, seed);
+ return tc;
+ }
- private NUnitDiscoveryTestRun ExtractTestRun(XDocument node)
- {
- var sb = ExtractSuiteBasePropertiesClass(node.Root);
- var tr = new NUnitDiscoveryTestRun(sb);
- return tr;
- }
+ public static NUnitDiscoveryTestFixture ExtractTestFixture(INUnitDiscoveryCanHaveTestFixture parent, XElement node,
+ string className)
+ {
+ var b = ExtractSuiteBasePropertiesClass(node);
+ var ts = new NUnitDiscoveryTestFixture(b, className, parent);
+ return ts;
+ }
+ private static NUnitDiscoveryGenericFixture ExtractGenericTestFixture(
+ NUnitDiscoveryCanHaveTestFixture parent,
+ XElement node)
+ {
+ var b = ExtractSuiteBasePropertiesClass(node);
+ var ts = new NUnitDiscoveryGenericFixture(b, parent);
+ return ts;
+ }
+ private static NUnitDiscoverySetUpFixture ExtractSetUpTestFixture(
+ NUnitDiscoveryCanHaveTestFixture parent,
+ XElement node, string className)
+ {
+ var b = ExtractSuiteBasePropertiesClass(node);
+ var ts = new NUnitDiscoverySetUpFixture(b, className, parent);
+ return ts;
+ }
+ private static NUnitDiscoveryParameterizedTestFixture ExtractParameterizedTestFixture(
+ NUnitDiscoveryCanHaveTestFixture parent, XElement node)
+ {
+ var b = ExtractSuiteBasePropertiesClass(node);
+ var ts = new NUnitDiscoveryParameterizedTestFixture(b, parent);
+ return ts;
+ }
- private static RunStateEnum ExtractRunState(XElement node)
- {
- var runState = node.Attribute(NUnitXmlAttributeNames.Runstate)?.Value switch
- {
- "Runnable" => RunStateEnum.Runnable,
- "Explicit" => RunStateEnum.Explicit,
- "NotRunnable" => RunStateEnum.NotRunnable,
- _ => RunStateEnum.NA
- };
- return runState;
- }
+ private NUnitDiscoveryTestAssembly ExtractTestAssembly(XElement node, NUnitDiscoveryTestRun parent)
+ {
+ string dType = node.Attribute(NUnitXmlAttributeNames.Type)?.Value;
+ if (dType is not "Assembly")
+ throw new DiscoveryException("Node is not of type assembly: " + node);
+ var aBase = ExtractSuiteBasePropertiesClass(node);
+ var assembly = new NUnitDiscoveryTestAssembly(aBase, parent);
+ parent.AddTestAssembly(assembly);
+ return assembly;
}
- public class BaseProperties
+ private static BaseProperties ExtractSuiteBasePropertiesClass(XElement node)
{
- public BaseProperties(string dId, string dName, string dFullname, int dTestcasecount, RunStateEnum dRunstate)
+ string dId = node.Attribute(NUnitXmlAttributeNames.Id).Value;
+ string dName = node.Attribute(NUnitXmlAttributeNames.Name).Value;
+ string dFullname = node.Attribute(NUnitXmlAttributeNames.Fullname).Value;
+ var dRunstate = ExtractRunState(node);
+ const char apo = '\'';
+ var tcs = node.Attribute(NUnitXmlAttributeNames.Testcasecount)?.Value.Trim(apo);
+ int dTestcasecount = int.Parse(tcs ?? "1", CultureInfo.InvariantCulture);
+ var bp = new BaseProperties(dId, dName, dFullname, dTestcasecount, dRunstate);
+
+ foreach (var propnode in node.Elements("properties").Elements("property"))
{
- Id = dId;
- Name = dName;
- Fullname = dFullname;
- TestCaseCount = dTestcasecount;
- RunState = dRunstate;
+ var prop = new NUnitProperty(propnode);
+ bp.Properties.Add(prop);
}
+ return bp;
+ }
+
- public List Properties { get; } = new ();
+ private NUnitDiscoveryTestRun ExtractTestRun(XDocument node)
+ {
+ var sb = ExtractSuiteBasePropertiesClass(node.Root);
+ var tr = new NUnitDiscoveryTestRun(sb);
+ return tr;
+ }
- public string Id { get; }
- public string Name { get; }
- public string Fullname { get; }
- public RunStateEnum RunState { get; }
- public int TestCaseCount { get; }
+ private static RunStateEnum ExtractRunState(XElement node)
+ {
+ var runState = node.Attribute(NUnitXmlAttributeNames.Runstate)?.Value switch
+ {
+ "Runnable" => RunStateEnum.Runnable,
+ "Explicit" => RunStateEnum.Explicit,
+ "NotRunnable" => RunStateEnum.NotRunnable,
+ _ => RunStateEnum.NA
+ };
+ return runState;
}
}
+
+public class BaseProperties(string dId, string dName, string dFullname, int dTestcasecount, RunStateEnum dRunstate)
+{
+ public List Properties { get; } = [];
+
+ public string Id { get; } = dId;
+ public string Name { get; } = dName;
+ public string Fullname { get; } = dFullname;
+ public RunStateEnum RunState { get; } = dRunstate;
+
+ public int TestCaseCount { get; } = dTestcasecount;
+}
\ No newline at end of file
diff --git a/src/NUnitTestAdapter/NUnitEngine/DiscoveryException.cs b/src/NUnitTestAdapter/NUnitEngine/DiscoveryException.cs
index b58a7ba0..4b1d0479 100644
--- a/src/NUnitTestAdapter/NUnitEngine/DiscoveryException.cs
+++ b/src/NUnitTestAdapter/NUnitEngine/DiscoveryException.cs
@@ -24,27 +24,26 @@
using System;
using System.Runtime.Serialization;
-namespace NUnit.VisualStudio.TestAdapter.NUnitEngine
+namespace NUnit.VisualStudio.TestAdapter.NUnitEngine;
+
+[Serializable]
+public class DiscoveryException : Exception
{
- [Serializable]
- public class DiscoveryException : Exception
+ public DiscoveryException()
{
- public DiscoveryException()
- {
- }
+ }
- public DiscoveryException(string message) : base(message)
- {
- }
+ public DiscoveryException(string message) : base(message)
+ {
+ }
- public DiscoveryException(string message, Exception inner) : base(message, inner)
- {
- }
+ public DiscoveryException(string message, Exception inner) : base(message, inner)
+ {
+ }
- protected DiscoveryException(
- SerializationInfo info,
- StreamingContext context) : base(info, context)
- {
- }
+ protected DiscoveryException(
+ SerializationInfo info,
+ StreamingContext context) : base(info, context)
+ {
}
}
\ No newline at end of file
diff --git a/src/NUnitTestAdapter/NUnitEngine/Extensions.cs b/src/NUnitTestAdapter/NUnitEngine/Extensions.cs
index b717cced..8ad94dda 100644
--- a/src/NUnitTestAdapter/NUnitEngine/Extensions.cs
+++ b/src/NUnitTestAdapter/NUnitEngine/Extensions.cs
@@ -27,23 +27,22 @@
using NUnit.Engine;
#pragma warning disable SA1618 // Generic type parameters should be documented
-namespace NUnit.VisualStudio.TestAdapter.NUnitEngine
+namespace NUnit.VisualStudio.TestAdapter.NUnitEngine;
+
+public static class Extensions
{
- public static class Extensions
- {
- ///
- /// All will return true if seq is empty. This returns false if sequence is empty.
- ///
- public static bool AllWithEmptyFalse(this IEnumerable list, Func pred) =>
- list.All(pred) && list.Any();
+ ///
+ /// All will return true if seq is empty. This returns false if sequence is empty.
+ ///
+ public static bool AllWithEmptyFalse(this IEnumerable list, Func pred)
+ => list.All(pred) && list.Any();
- public static bool IsEmpty(this TestFilter filter) => filter == TestFilter.Empty;
+ public static bool IsEmpty(this TestFilter filter) => filter == TestFilter.Empty;
- public static bool IsCategoryFilter(this TestFilter filter) =>
- filter != TestFilter.Empty && filter.Text.Contains("");
+ public static bool IsCategoryFilter(this TestFilter filter) =>
+ filter != TestFilter.Empty && filter.Text.Contains("");
- public static bool IsNegativeCategoryFilter(this TestFilter filter) =>
- filter.IsCategoryFilter() && filter.Text.Contains("");
- }
-}
+ public static bool IsNegativeCategoryFilter(this TestFilter filter) =>
+ filter.IsCategoryFilter() && filter.Text.Contains("");
+}
\ No newline at end of file
diff --git a/src/NUnitTestAdapter/NUnitEngine/NUnitDiscoveryTestClasses.cs b/src/NUnitTestAdapter/NUnitEngine/NUnitDiscoveryTestClasses.cs
index ceea0925..ee41abb7 100644
--- a/src/NUnitTestAdapter/NUnitEngine/NUnitDiscoveryTestClasses.cs
+++ b/src/NUnitTestAdapter/NUnitEngine/NUnitDiscoveryTestClasses.cs
@@ -27,379 +27,349 @@
// ReSharper disable InconsistentNaming
-namespace NUnit.VisualStudio.TestAdapter.NUnitEngine
-{
- public interface INUnitDiscoverySuiteBase : INUnitTestCasePropertyInfo
- {
- string Id { get; }
- string Name { get; }
- string FullName { get; }
- int TestCaseCount { get; }
- INUnitDiscoverySuiteBase Parent { get; }
- NUnitDiscoveryProperties NUnitDiscoveryProperties { get; }
- bool IsExplicit { get; }
- bool IsExplicitReverse { get; }
-
- bool IsParameterizedMethod { get; }
- void AddToAllTestCases(NUnitDiscoveryTestCase tc);
- }
-
- public abstract class NUnitDiscoverySuiteBase : INUnitDiscoverySuiteBase
- {
- public string Id { get; }
- public string Name { get; }
- public string FullName { get; }
- public int TestCaseCount { get; }
- public RunStateEnum RunState { get; }
- public INUnitDiscoverySuiteBase Parent { get; }
-
-
- private NUnitDiscoverySuiteBase(string id, string name, string fullname, int count)
- {
- Id = id;
- Name = name;
- FullName = fullname;
- TestCaseCount = count;
- }
+namespace NUnit.VisualStudio.TestAdapter.NUnitEngine;
- protected NUnitDiscoverySuiteBase(BaseProperties other)
- : this(other.Id, other.Name, other.Fullname, other.TestCaseCount)
- {
- RunState = other.RunState;
- foreach (var prop in other.Properties)
- {
- NUnitDiscoveryProperties.Add(prop);
- }
- }
-
- protected NUnitDiscoverySuiteBase(BaseProperties other, INUnitDiscoverySuiteBase parent) : this(other)
- {
- Parent = parent;
- }
+public interface INUnitDiscoverySuiteBase : INUnitTestCasePropertyInfo
+{
+ string Id { get; }
+ string Name { get; }
+ string FullName { get; }
+ int TestCaseCount { get; }
+ INUnitDiscoverySuiteBase Parent { get; }
+ NUnitDiscoveryProperties NUnitDiscoveryProperties { get; }
+ bool IsExplicit { get; }
+ bool IsExplicitReverse { get; }
+
+ bool IsParameterizedMethod { get; }
+ void AddToAllTestCases(NUnitDiscoveryTestCase tc);
+}
- public NUnitDiscoveryProperties NUnitDiscoveryProperties { get; } = new ();
+public abstract class NUnitDiscoverySuiteBase : INUnitDiscoverySuiteBase
+{
+ public string Id { get; }
+ public string Name { get; }
+ public string FullName { get; }
+ public int TestCaseCount { get; }
+ public RunStateEnum RunState { get; }
+ public INUnitDiscoverySuiteBase Parent { get; }
- public abstract bool IsExplicit { get; }
- public virtual bool IsExplicitReverse => RunState == RunStateEnum.Explicit || (Parent?.IsExplicitReverse ?? RunState == RunStateEnum.Explicit);
- public virtual bool IsParameterizedMethod => false;
- public IEnumerable Properties => NUnitDiscoveryProperties.Properties;
- public virtual void AddToAllTestCases(NUnitDiscoveryTestCase tc)
- {
- Parent.AddToAllTestCases(tc);
- }
+ private NUnitDiscoverySuiteBase(string id, string name, string fullname, int count)
+ {
+ Id = id;
+ Name = name;
+ FullName = fullname;
+ TestCaseCount = count;
}
-
- public class NUnitDiscoveryTestRun : NUnitDiscoverySuiteBase
+ protected NUnitDiscoverySuiteBase(BaseProperties other)
+ : this(other.Id, other.Name, other.Fullname, other.TestCaseCount)
{
- public NUnitDiscoveryTestRun(BaseProperties baseProps) : base(baseProps)
+ RunState = other.RunState;
+ foreach (var prop in other.Properties)
{
- }
-
- public NUnitDiscoveryTestAssembly TestAssembly { get; set; }
- public override bool IsExplicit =>
- RunState == RunStateEnum.Explicit || TestAssembly.IsExplicit;
-
- public void AddTestAssembly(NUnitDiscoveryTestAssembly testAssembly)
- {
- TestAssembly = testAssembly;
+ NUnitDiscoveryProperties.Add(prop);
}
}
- public class NUnitDiscoveryProperties
+ protected NUnitDiscoverySuiteBase(BaseProperties other, INUnitDiscoverySuiteBase parent) : this(other)
{
- private List TheProperties { get; } = new ();
- public IEnumerable Properties => TheProperties;
+ Parent = parent;
+ }
- public void Add(NUnitProperty p) => TheProperties.Add(p);
+ public NUnitDiscoveryProperties NUnitDiscoveryProperties { get; } = new();
- public bool AllInternal => TheProperties.All(o => o.IsInternal);
- }
+ public abstract bool IsExplicit { get; }
+ public virtual bool IsExplicitReverse => RunState == RunStateEnum.Explicit || (Parent?.IsExplicitReverse ?? RunState == RunStateEnum.Explicit);
+ public virtual bool IsParameterizedMethod => false;
+ public IEnumerable Properties => NUnitDiscoveryProperties.Properties;
- public class NUnitDiscoveryTestSuite : NUnitDiscoveryCanHaveTestFixture
+ public virtual void AddToAllTestCases(NUnitDiscoveryTestCase tc)
{
- public NUnitDiscoveryTestSuite(BaseProperties theBase, INUnitDiscoverySuiteBase parent) : base(theBase, parent)
- {
- }
-
- public NUnitDiscoveryTestAssembly ParentAssembly { get; set; }
+ Parent.AddToAllTestCases(tc);
}
+}
+public class NUnitDiscoveryTestRun(BaseProperties baseProps) : NUnitDiscoverySuiteBase(baseProps)
+{
+ public NUnitDiscoveryTestAssembly TestAssembly { get; set; }
+ public override bool IsExplicit =>
+ RunState == RunStateEnum.Explicit || TestAssembly.IsExplicit;
- public sealed class NUnitDiscoveryTestAssembly : NUnitDiscoveryTestSuite
+ public void AddTestAssembly(NUnitDiscoveryTestAssembly testAssembly)
{
- public NUnitDiscoveryTestAssembly(BaseProperties theBase, NUnitDiscoveryTestRun parent) : base(theBase, parent)
- { }
+ TestAssembly = testAssembly;
+ }
+}
- private readonly List allTestCases = new ();
+public class NUnitDiscoveryProperties
+{
+ private List TheProperties { get; } = new();
+ public IEnumerable Properties => TheProperties;
- ///
- /// If all testcases are Explicit, we can run this one.
- ///
- public IEnumerable AllTestCases => allTestCases;
+ public void Add(NUnitProperty p) => TheProperties.Add(p);
- ///
- /// If there are a mixture of explicit and non-explicit, this one will filter out the explicit ones.
- ///
- public IEnumerable RunnableTestCases => allTestCases.Where(c => !c.IsExplicitReverse);
+ public bool AllInternal => TheProperties.All(o => o.IsInternal);
+}
- public int NoOfExplicitTestCases => allTestCases.Count(c => c.IsExplicitReverse);
+public class NUnitDiscoveryTestSuite(BaseProperties theBase, INUnitDiscoverySuiteBase parent)
+ : NUnitDiscoveryCanHaveTestFixture(theBase, parent)
+{
+ public NUnitDiscoveryTestAssembly ParentAssembly { get; set; }
+}
- public void AddTestSuiteToAssembly(NUnitDiscoveryTestSuite ts)
- {
- AddTestSuite(ts);
- }
- public override void AddToAllTestCases(NUnitDiscoveryTestCase tc)
- {
- allTestCases.Add(tc);
- }
- }
- public sealed class NUnitDiscoveryTestFixture : NUnitDiscoveryCanHaveTestCases
- {
- private readonly List parameterizedMethods = new ();
- public IEnumerable ParameterizedMethods => parameterizedMethods;
+public sealed class NUnitDiscoveryTestAssembly(BaseProperties theBase, NUnitDiscoveryTestRun parent)
+ : NUnitDiscoveryTestSuite(theBase, parent)
+{
+ private readonly List allTestCases = new();
- private readonly List theories = new ();
+ ///
+ /// If all testcases are Explicit, we can run this one.
+ ///
+ public IEnumerable AllTestCases => allTestCases;
- private readonly List genericMethods = new ();
- public IEnumerable Theories => theories;
+ ///
+ /// If there are a mixture of explicit and non-explicit, this one will filter out the explicit ones.
+ ///
+ public IEnumerable RunnableTestCases => allTestCases.Where(c => !c.IsExplicitReverse);
- public override int NoOfActualTestCases =>
- base.NoOfActualTestCases
- + parameterizedMethods.Sum(o => o.NoOfActualTestCases)
- + theories.Sum(o => o.NoOfActualTestCases)
- + genericMethods.Sum(o => o.NoOfActualTestCases);
+ public int NoOfExplicitTestCases => allTestCases.Count(c => c.IsExplicitReverse);
- public override bool IsExplicit
- {
- get
- {
- if (RunState == RunStateEnum.Explicit)
- return true;
- var all = new List();
- all.AddRange(TestCases.Cast());
- all.AddRange(parameterizedMethods.Cast());
- all.AddRange(theories.Cast());
- all.AddRange(genericMethods.Cast());
- return all.All(o => o.IsExplicit);
- }
- }
+ public void AddTestSuiteToAssembly(NUnitDiscoveryTestSuite ts)
+ {
+ AddTestSuite(ts);
+ }
- public IEnumerable GenericMethods => genericMethods;
+ public override void AddToAllTestCases(NUnitDiscoveryTestCase tc)
+ {
+ allTestCases.Add(tc);
+ }
+}
- public NUnitDiscoveryTestFixture(BaseProperties theBase, string classname, INUnitDiscoverySuiteBase parent) : base(theBase, parent, classname)
- {
- }
+public sealed class NUnitDiscoveryTestFixture(BaseProperties theBase, string classname, INUnitDiscoverySuiteBase parent)
+ : NUnitDiscoveryCanHaveTestCases(theBase, parent, classname)
+{
+ private readonly List parameterizedMethods = new();
+ public IEnumerable ParameterizedMethods => parameterizedMethods;
- public void AddParameterizedMethod(NUnitDiscoveryParameterizedMethod ts)
- {
- parameterizedMethods.Add(ts);
- }
+ private readonly List theories = new();
+ private readonly List genericMethods = new();
+ public IEnumerable Theories => theories;
- public void AddTheory(NUnitDiscoveryTheory tc)
- {
- theories.Add(tc);
- }
+ public override int NoOfActualTestCases =>
+ base.NoOfActualTestCases
+ + parameterizedMethods.Sum(o => o.NoOfActualTestCases)
+ + theories.Sum(o => o.NoOfActualTestCases)
+ + genericMethods.Sum(o => o.NoOfActualTestCases);
- public void AddGenericMethod(NUnitDiscoveryGenericMethod tc)
+ public override bool IsExplicit
+ {
+ get
{
- genericMethods.Add(tc);
+ if (RunState == RunStateEnum.Explicit)
+ return true;
+ var all = new List();
+ all.AddRange(TestCases);
+ all.AddRange(parameterizedMethods);
+ all.AddRange(theories);
+ all.AddRange(genericMethods);
+ return all.All(o => o.IsExplicit);
}
}
- public interface INUnitDiscoveryTestCase : INUnitDiscoverySuiteBase
- {
- string ClassName { get; }
- string MethodName { get; }
- long Seed { get; set; }
- }
+ public IEnumerable GenericMethods => genericMethods;
- ///
- /// Interface for common properties between event testcase and discoverytestcase.
- ///
- public interface INUnitCommonTestCase
+ public void AddParameterizedMethod(NUnitDiscoveryParameterizedMethod ts)
{
- string Id { get; }
- string Name { get; }
- string FullName { get; }
- string ClassName { get; }
- string MethodName { get; }
- long Seed { get; }
+ parameterizedMethods.Add(ts);
}
- public sealed class NUnitDiscoveryTestCase : NUnitDiscoverySuiteBase, INUnitDiscoveryTestCase, INUnitCommonTestCase
- {
- public string ClassName { get; }
- public string MethodName { get; set; }
- public long Seed { get; set; }
-
- public NUnitDiscoveryTestCase(BaseProperties theBase, INUnitDiscoveryCanHaveTestCases parent,
- string className,
- string methodname, long seed) : base(theBase, parent)
- {
- ClassName = className;
- MethodName = methodname;
- Seed = seed;
- }
- public override bool IsExplicit => RunState == RunStateEnum.Explicit;
- }
-
- public sealed class NUnitDiscoveryParameterizedMethod : NUnitDiscoveryCanHaveTestCases
+ public void AddTheory(NUnitDiscoveryTheory tc)
{
- public NUnitDiscoveryParameterizedMethod(BaseProperties theBase, string classname, INUnitDiscoverySuiteBase parent) : base(theBase, parent, classname)
- {
- }
-
- public override bool IsParameterizedMethod => true;
+ theories.Add(tc);
}
- public interface INUnitDiscoveryCanHaveTestCases : INUnitDiscoverySuiteBase
+ public void AddGenericMethod(NUnitDiscoveryGenericMethod tc)
{
- IEnumerable TestCases { get; }
- int NoOfActualTestCases { get; }
- void AddTestCase(NUnitDiscoveryTestCase tc);
+ genericMethods.Add(tc);
}
+}
- public abstract class NUnitDiscoveryCanHaveTestCases : NUnitDiscoverySuiteBase, INUnitDiscoveryCanHaveTestCases
- {
- private readonly List testCases = new ();
+public interface INUnitDiscoveryTestCase : INUnitDiscoverySuiteBase
+{
+ string ClassName { get; }
+ string MethodName { get; }
+ long Seed { get; set; }
+}
- public IEnumerable TestCases => testCases;
- public virtual int NoOfActualTestCases => testCases.Count;
+///
+/// Interface for common properties between event testcase and discoverytestcase.
+///
+public interface INUnitCommonTestCase
+{
+ string Id { get; }
+ string Name { get; }
+ string FullName { get; }
+ string ClassName { get; }
+ string MethodName { get; }
+ long Seed { get; }
+}
- public override bool IsExplicit =>
- RunState == RunStateEnum.Explicit || testCases.AllWithEmptyFalse(o => o.IsExplicit);
+public sealed class NUnitDiscoveryTestCase(
+ BaseProperties theBase,
+ INUnitDiscoveryCanHaveTestCases parent,
+ string className,
+ string methodname,
+ long seed)
+ : NUnitDiscoverySuiteBase(theBase, parent), INUnitDiscoveryTestCase, INUnitCommonTestCase
+{
+ public string ClassName { get; } = className;
+ public string MethodName { get; set; } = methodname;
+ public long Seed { get; set; } = seed;
- public string ClassName { get; }
+ public override bool IsExplicit => RunState == RunStateEnum.Explicit;
+}
- public void AddTestCase(NUnitDiscoveryTestCase tc)
- {
- testCases.Add(tc);
- Parent.AddToAllTestCases(tc);
- }
+public sealed class NUnitDiscoveryParameterizedMethod(
+ BaseProperties theBase,
+ string classname,
+ INUnitDiscoverySuiteBase parent)
+ : NUnitDiscoveryCanHaveTestCases(theBase, parent, classname)
+{
+ public override bool IsParameterizedMethod => true;
+}
- protected NUnitDiscoveryCanHaveTestCases(BaseProperties theBase, INUnitDiscoverySuiteBase parent, string classname) : base(theBase, parent)
- {
- ClassName = classname;
- }
- }
+public interface INUnitDiscoveryCanHaveTestCases : INUnitDiscoverySuiteBase
+{
+ IEnumerable TestCases { get; }
+ int NoOfActualTestCases { get; }
+ void AddTestCase(NUnitDiscoveryTestCase tc);
+}
- public interface INUnitDiscoveryCanHaveTestFixture : INUnitDiscoverySuiteBase
- {
- IEnumerable TestFixtures { get; }
- int NoOfActualTestCases { get; }
- void AddTestFixture(NUnitDiscoveryTestFixture tf);
- }
+public abstract class NUnitDiscoveryCanHaveTestCases(
+ BaseProperties theBase,
+ INUnitDiscoverySuiteBase parent,
+ string classname)
+ : NUnitDiscoverySuiteBase(theBase, parent), INUnitDiscoveryCanHaveTestCases
+{
+ private readonly List testCases = new();
- public abstract class NUnitDiscoveryCanHaveTestFixture : NUnitDiscoverySuiteBase, INUnitDiscoveryCanHaveTestFixture
- {
- private readonly List testFixtures = new ();
+ public IEnumerable TestCases => testCases;
+ public virtual int NoOfActualTestCases => testCases.Count;
- public IEnumerable TestFixtures => testFixtures;
+ public override bool IsExplicit =>
+ RunState == RunStateEnum.Explicit || testCases.AllWithEmptyFalse(o => o.IsExplicit);
- public void AddTestFixture(NUnitDiscoveryTestFixture tf)
- {
- testFixtures.Add(tf);
- }
- protected NUnitDiscoveryCanHaveTestFixture(BaseProperties theBase, INUnitDiscoverySuiteBase parent) : base(theBase, parent)
- {
- }
+ public string ClassName { get; } = classname;
+
+ public void AddTestCase(NUnitDiscoveryTestCase tc)
+ {
+ testCases.Add(tc);
+ Parent.AddToAllTestCases(tc);
+ }
+}
+public interface INUnitDiscoveryCanHaveTestFixture : INUnitDiscoverySuiteBase
+{
+ IEnumerable TestFixtures { get; }
+ int NoOfActualTestCases { get; }
+ void AddTestFixture(NUnitDiscoveryTestFixture tf);
+}
- private readonly List testSuites = new ();
+public abstract class NUnitDiscoveryCanHaveTestFixture(BaseProperties theBase, INUnitDiscoverySuiteBase parent)
+ : NUnitDiscoverySuiteBase(theBase, parent), INUnitDiscoveryCanHaveTestFixture
+{
+ private readonly List testFixtures = new();
- private readonly List genericFixtures = new ();
- private readonly List setUpFixtures = new ();
- private readonly List parameterizedFixtures = new ();
+ public IEnumerable TestFixtures => testFixtures;
+ public void AddTestFixture(NUnitDiscoveryTestFixture tf)
+ {
+ testFixtures.Add(tf);
+ }
- public IEnumerable TestSuites => testSuites;
- public IEnumerable SetUpFixtures => setUpFixtures;
- public IEnumerable ParameterizedFixtures => parameterizedFixtures;
- public IEnumerable GenericFixtures => genericFixtures;
+ private readonly List testSuites = new();
- public override bool IsExplicit
- {
- get
- {
- if (RunState == RunStateEnum.Explicit)
- return true;
- var fullList = new List();
- fullList.AddRange(TestFixtures.Cast());
- fullList.AddRange(TestSuites.Cast());
- fullList.AddRange(GenericFixtures.Cast());
- fullList.AddRange(SetUpFixtures.Cast());
- fullList.AddRange(ParameterizedFixtures.Cast());
- return fullList.All(o => o.IsExplicit);
- }
- }
+ private readonly List genericFixtures = new();
+ private readonly List setUpFixtures = new();
+ private readonly List parameterizedFixtures = new();
- public int NoOfActualTestCases => testFixtures.Sum(o => o.NoOfActualTestCases)
- + testSuites.Sum(o => o.NoOfActualTestCases)
- + genericFixtures.Sum(o => o.NoOfActualTestCases)
- + setUpFixtures.Sum(o => o.NoOfActualTestCases)
- + parameterizedFixtures.Sum(o => o.NoOfActualTestCases);
- public void AddTestSuite(NUnitDiscoveryTestSuite ts)
- {
- testSuites.Add(ts);
- }
+ public IEnumerable TestSuites => testSuites;
+ public IEnumerable SetUpFixtures => setUpFixtures;
+ public IEnumerable ParameterizedFixtures => parameterizedFixtures;
- public void AddTestGenericFixture(NUnitDiscoveryGenericFixture ts)
- {
- genericFixtures.Add(ts);
- }
- public void AddSetUpFixture(NUnitDiscoverySetUpFixture ts)
- {
- setUpFixtures.Add(ts);
- }
- public void AddParameterizedFixture(NUnitDiscoveryParameterizedTestFixture ts)
- {
- parameterizedFixtures.Add(ts);
- }
- }
+ public IEnumerable GenericFixtures => genericFixtures;
- public sealed class NUnitDiscoveryGenericFixture : NUnitDiscoveryCanHaveTestFixture
+ public override bool IsExplicit
{
- public NUnitDiscoveryGenericFixture(BaseProperties theBase, INUnitDiscoverySuiteBase parent) : base(theBase, parent)
+ get
{
+ if (RunState == RunStateEnum.Explicit)
+ return true;
+ var fullList = new List();
+ fullList.AddRange(TestFixtures);
+ fullList.AddRange(TestSuites);
+ fullList.AddRange(GenericFixtures);
+ fullList.AddRange(SetUpFixtures);
+ fullList.AddRange(ParameterizedFixtures);
+ return fullList.All(o => o.IsExplicit);
}
}
- public sealed class NUnitDiscoveryParameterizedTestFixture : NUnitDiscoveryCanHaveTestFixture
+ public int NoOfActualTestCases => testFixtures.Sum(o => o.NoOfActualTestCases)
+ + testSuites.Sum(o => o.NoOfActualTestCases)
+ + genericFixtures.Sum(o => o.NoOfActualTestCases)
+ + setUpFixtures.Sum(o => o.NoOfActualTestCases)
+ + parameterizedFixtures.Sum(o => o.NoOfActualTestCases);
+
+ public void AddTestSuite(NUnitDiscoveryTestSuite ts)
{
- public NUnitDiscoveryParameterizedTestFixture(BaseProperties theBase, NUnitDiscoveryCanHaveTestFixture parent) : base(theBase, parent)
- {
- }
+ testSuites.Add(ts);
}
- public sealed class NUnitDiscoverySetUpFixture : NUnitDiscoveryCanHaveTestFixture
+ public void AddTestGenericFixture(NUnitDiscoveryGenericFixture ts)
{
- public string ClassName { get; }
- public NUnitDiscoverySetUpFixture(BaseProperties theBase, string classname, NUnitDiscoveryCanHaveTestFixture parent) : base(theBase, parent)
- {
- ClassName = classname;
- }
+ genericFixtures.Add(ts);
}
-
- public sealed class NUnitDiscoveryTheory : NUnitDiscoveryCanHaveTestCases
+ public void AddSetUpFixture(NUnitDiscoverySetUpFixture ts)
{
- public NUnitDiscoveryTheory(BaseProperties theBase, string classname, INUnitDiscoverySuiteBase parent) : base(theBase, parent, classname)
- {
- }
+ setUpFixtures.Add(ts);
}
-
- public sealed class NUnitDiscoveryGenericMethod : NUnitDiscoveryCanHaveTestCases
+ public void AddParameterizedFixture(NUnitDiscoveryParameterizedTestFixture ts)
{
- public NUnitDiscoveryGenericMethod(BaseProperties theBase, string classname, INUnitDiscoverySuiteBase parent) : base(theBase, parent, classname)
- {
- }
+ parameterizedFixtures.Add(ts);
}
}
+
+public sealed class NUnitDiscoveryGenericFixture(BaseProperties theBase, INUnitDiscoverySuiteBase parent)
+ : NUnitDiscoveryCanHaveTestFixture(theBase, parent);
+
+public sealed class NUnitDiscoveryParameterizedTestFixture(
+ BaseProperties theBase,
+ NUnitDiscoveryCanHaveTestFixture parent)
+ : NUnitDiscoveryCanHaveTestFixture(theBase, parent);
+
+public sealed class NUnitDiscoverySetUpFixture(
+ BaseProperties theBase,
+ string classname,
+ NUnitDiscoveryCanHaveTestFixture parent)
+ : NUnitDiscoveryCanHaveTestFixture(theBase, parent)
+{
+ public string ClassName { get; } = classname;
+}
+
+public sealed class NUnitDiscoveryTheory(BaseProperties theBase, string classname, INUnitDiscoverySuiteBase parent)
+ : NUnitDiscoveryCanHaveTestCases(theBase, parent, classname);
+
+public sealed class NUnitDiscoveryGenericMethod(
+ BaseProperties theBase,
+ string classname,
+ INUnitDiscoverySuiteBase parent)
+ : NUnitDiscoveryCanHaveTestCases(theBase, parent, classname);
\ No newline at end of file
diff --git a/src/NUnitTestAdapter/NUnitEngine/NUnitEngineAdapter.cs b/src/NUnitTestAdapter/NUnitEngine/NUnitEngineAdapter.cs
index 3ee39a07..3c4ce429 100644
--- a/src/NUnitTestAdapter/NUnitEngine/NUnitEngineAdapter.cs
+++ b/src/NUnitTestAdapter/NUnitEngine/NUnitEngineAdapter.cs
@@ -22,199 +22,182 @@
// ***********************************************************************
using System;
-using System.Diagnostics;
using System.IO;
using System.Threading;
using NUnit.Engine;
using NUnit.VisualStudio.TestAdapter.Internal;
-namespace NUnit.VisualStudio.TestAdapter.NUnitEngine
+namespace NUnit.VisualStudio.TestAdapter.NUnitEngine;
+
+public interface INUnitEngineAdapter
{
- public interface INUnitEngineAdapter
- {
- NUnitResults Explore();
- void CloseRunner();
- NUnitResults Explore(TestFilter filter);
- NUnitResults Run(ITestEventListener listener, TestFilter filter);
- void StopRun();
+ NUnitResults Explore();
+ void CloseRunner();
+ NUnitResults Explore(TestFilter filter);
+ NUnitResults Run(ITestEventListener listener, TestFilter filter);
+ void StopRun();
- T GetService()
- where T : class;
+ T GetService()
+ where T : class;
- void GenerateTestOutput(NUnitResults testResults, string assemblyPath, string testOutputXmlFolder);
- string GetXmlFilePath(string folder, string defaultFileName, string extension);
- }
+ void GenerateTestOutput(NUnitResults testResults, string assemblyPath, string testOutputXmlFolder);
+ string GetXmlFilePath(string folder, string defaultFileName, string extension);
+}
- public class NUnitEngineAdapter : INUnitEngineAdapter, IDisposable
- {
- private IAdapterSettings settings;
- private ITestLogger logger;
- private TestPackage package;
- private ITestEngine TestEngine { get; set; }
- private ITestRunner Runner { get; set; }
+public class NUnitEngineAdapter : INUnitEngineAdapter, IDisposable
+{
+ private IAdapterSettings settings;
+ private ITestLogger logger;
+ private TestPackage package;
+ private ITestEngine TestEngine { get; set; }
+ private ITestRunner Runner { get; set; }
- internal event Action InternalEngineCreated;
+ internal event Action InternalEngineCreated;
- public bool EngineEnabled => TestEngine != null;
+ public bool EngineEnabled => TestEngine != null;
- public void Initialize()
- {
+ public void Initialize()
+ {
#if NET462
- var engineX = new TestEngine();
+ var engineX = new TestEngine();
#else
- var engineX = TestEngineActivator.CreateInstance();
+ var engineX = TestEngineActivator.CreateInstance() ?? new TestEngine();
#endif
- if (engineX == null)
- engineX = new TestEngine();
-
- InternalEngineCreated?.Invoke(engineX);
- TestEngine = engineX;
- var tmpPath = Path.Combine(Path.GetTempPath(), "NUnit.Engine");
- if (!Directory.Exists(tmpPath))
- Directory.CreateDirectory(tmpPath);
- TestEngine.WorkDirectory = tmpPath;
- TestEngine.InternalTraceLevel = InternalTraceLevel.Off;
- }
- public void InitializeSettingsAndLogging(IAdapterSettings setting, ITestLogger testLog)
- {
- logger = testLog;
- settings = setting;
-#if EnableTraceLevelAtInitialization
-
-#endif
- }
+ InternalEngineCreated?.Invoke(engineX);
+ TestEngine = engineX;
+ var tmpPath = Path.Combine(Path.GetTempPath(), "NUnit.Engine");
+ if (!Directory.Exists(tmpPath))
+ Directory.CreateDirectory(tmpPath);
+ TestEngine.WorkDirectory = tmpPath;
+ TestEngine.InternalTraceLevel = InternalTraceLevel.Off;
+ }
- public void CreateRunner(TestPackage testPackage)
- {
- package = testPackage;
- Runner = TestEngine.GetRunner(package);
- }
+ public void InitializeSettingsAndLogging(IAdapterSettings setting, ITestLogger testLog)
+ {
+ logger = testLog;
+ settings = setting;
+ }
- public NUnitResults Explore()
- {
- return Explore(TestFilter.Empty);
- }
+ public void CreateRunner(TestPackage testPackage)
+ {
+ package = testPackage;
+ Runner = TestEngine.GetRunner(package);
+ }
- public NUnitResults Explore(TestFilter filter)
- {
- var timing = new TimingLogger(settings, logger);
- var results = new NUnitResults(Runner.Explore(filter));
- return LogTiming(filter, timing, results);
- }
+ public NUnitResults Explore()
+ => Explore(TestFilter.Empty);
- public NUnitResults Run(ITestEventListener listener, TestFilter filter)
- {
- var timing = new TimingLogger(settings, logger);
- var results = new NUnitResults(Runner.Run(listener, filter));
- return LogTiming(filter, timing, results);
- }
+ public NUnitResults Explore(TestFilter filter)
+ {
+ var timing = new TimingLogger(settings, logger);
+ var results = new NUnitResults(Runner.Explore(filter));
+ return LogTiming(filter, timing, results);
+ }
+
+ public NUnitResults Run(ITestEventListener listener, TestFilter filter)
+ {
+ var timing = new TimingLogger(settings, logger);
+ var results = new NUnitResults(Runner.Run(listener, filter));
+ return LogTiming(filter, timing, results);
+ }
+
+ private NUnitResults LogTiming(TestFilter filter, TimingLogger timing, NUnitResults results)
+ {
+ timing.LogTime($"Execution engine run time with filter length {filter.Text.Length}");
+ if (filter.Text.Length < 300)
+ logger.Debug($"Filter: {filter.Text}");
+ return results;
+ }
- private NUnitResults LogTiming(TestFilter filter, TimingLogger timing, NUnitResults results)
+ public T GetService()
+ where T : class
+ {
+ var service = TestEngine.Services.GetService();
+ if (service == null)
{
- timing.LogTime($"Execution engine run time with filter length {filter.Text.Length}");
- if (filter.Text.Length < 300)
- logger.Debug($"Filter: {filter.Text}");
- return results;
+ logger.Warning($"Engine GetService can't create service {typeof(T)}.");
}
+ return service;
+ }
+
+ public void StopRun()
+ => Runner?.StopRun(true);
+
+ public void CloseRunner()
+ {
+ if (Runner == null)
+ return;
+ if (Runner.IsTestRunning)
+ Runner.StopRun(true);
- public T GetService()
- where T : class
+ try
{
- var service = TestEngine.Services.GetService();
- if (service == null)
- {
- logger.Warning($"Engine GetService can't create service {typeof(T)}.");
- }
- return service;
+ Runner.Unload();
+ Runner.Dispose();
}
-
- public void StopRun()
+ catch (NUnitEngineUnloadException ex)
{
- Runner?.StopRun(true);
+ logger.Warning($"Engine encountered NUnitEngineUnloadException : {ex.Message}");
}
+ Runner = null;
+ }
- public void CloseRunner()
- {
- if (Runner == null)
- return;
- if (Runner.IsTestRunning)
- Runner.StopRun(true);
+ public void Dispose()
+ {
+ CloseRunner();
+ TestEngine?.Dispose();
+ }
- try
- {
- Runner.Unload();
- Runner.Dispose();
- }
- catch (NUnitEngineUnloadException ex)
- {
- logger.Warning($"Engine encountered NUnitEngineUnloadException : {ex.Message}");
- }
- Runner = null;
- }
+ public void GenerateTestOutput(NUnitResults testResults, string assemblyPath, string testOutputXmlFolder)
+ {
+ if (!settings.UseTestOutputXml)
+ return;
+
+ var resultService = GetService();
- public void Dispose()
+ using Mutex mutex = new Mutex(false, string.IsNullOrWhiteSpace(assemblyPath) ? nameof(GenerateTestOutput) : Path.GetFileNameWithoutExtension(assemblyPath));
+ bool received = false;
+ try
{
- CloseRunner();
- TestEngine?.Dispose();
+ received = mutex.WaitOne();
+ string path = GetXmlFilePath(testOutputXmlFolder, GetTestOutputFileName(assemblyPath), "xml");
+
+ // Following null argument should work for nunit3 format. Empty array is OK as well.
+ // If you decide to handle other formats in the runsettings, it needs more work.
+ var resultWriter = resultService.GetResultWriter("nunit3", null);
+ resultWriter.WriteResultFile(testResults.FullTopNode, path);
+ logger.Info($" Test results written to {path}");
}
-
- public void GenerateTestOutput(NUnitResults testResults, string assemblyPath, string testOutputXmlFolder)
+ finally
{
- if (!settings.UseTestOutputXml)
- return;
-
- var resultService = GetService();
-
- using (Mutex mutex = new Mutex(false, string.IsNullOrWhiteSpace(assemblyPath) ? nameof(GenerateTestOutput) : Path.GetFileNameWithoutExtension(assemblyPath)))
+ if (received)
{
- bool received = false;
- try
- {
- received = mutex.WaitOne();
- string path = GetXmlFilePath(testOutputXmlFolder, GetTestOutputFileName(assemblyPath), "xml");
-
- // Following null argument should work for nunit3 format. Empty array is OK as well.
- // If you decide to handle other formats in the runsettings, it needs more work.
- var resultWriter = resultService.GetResultWriter("nunit3", null);
- resultWriter.WriteResultFile(testResults.FullTopNode, path);
- logger.Info($" Test results written to {path}");
- }
- finally
- {
- if (received)
- {
- mutex.ReleaseMutex();
- }
- }
+ mutex.ReleaseMutex();
}
}
+ }
- public string GetTestOutputFileName(string assemblyPath)
+ public string GetTestOutputFileName(string assemblyPath)
+ => string.IsNullOrWhiteSpace(settings.TestOutputXmlFileName)
+ ? Path.GetFileNameWithoutExtension(assemblyPath)
+ : settings.TestOutputXmlFileName;
+
+ public string GetXmlFilePath(string folder, string defaultFileName, string extension)
+ {
+ if (!settings.NewOutputXmlFileForEachRun)
{
- if (string.IsNullOrWhiteSpace(settings.TestOutputXmlFileName))
- {
- return Path.GetFileNameWithoutExtension(assemblyPath);
- }
- return settings.TestOutputXmlFileName;
+ // overwrite the existing file
+ return Path.Combine(folder, $"{defaultFileName}.{extension}");
}
-
- public string GetXmlFilePath(string folder, string defaultFileName, string extension)
+ // allways create a new file
+ int i = 1;
+ while (true)
{
- if (!settings.NewOutputXmlFileForEachRun)
- {
- // overwrite the existing file
- return Path.Combine(folder, $"{defaultFileName}.{extension}");
- }
- // allways create a new file
- int i = 1;
- while (true)
- {
- string path = Path.Combine(folder, $"{defaultFileName}.{i++}.{extension}");
- if (!File.Exists(path))
- return path;
- }
+ string path = Path.Combine(folder, $"{defaultFileName}.{i++}.{extension}");
+ if (!File.Exists(path))
+ return path;
}
}
-}
+}
\ No newline at end of file
diff --git a/src/NUnitTestAdapter/NUnitEngine/NUnitEventTestCase.cs b/src/NUnitTestAdapter/NUnitEngine/NUnitEventTestCase.cs
index 1240c25a..76dc5490 100644
--- a/src/NUnitTestAdapter/NUnitEngine/NUnitEventTestCase.cs
+++ b/src/NUnitTestAdapter/NUnitEngine/NUnitEventTestCase.cs
@@ -24,67 +24,66 @@
using System.Collections.Generic;
using System.Xml;
-namespace NUnit.VisualStudio.TestAdapter.NUnitEngine
+namespace NUnit.VisualStudio.TestAdapter.NUnitEngine;
+
+public interface INUnitTestCase : INUnitTestNode
{
- public interface INUnitTestCase : INUnitTestNode
- {
- bool IsTestCase { get; }
- bool IsParameterizedMethod { get; }
- string Type { get; }
- string ClassName { get; }
- string MethodName { get; }
- RunStateEnum RunState { get; }
- NUnitEventTestCase Parent { get; }
- }
+ bool IsTestCase { get; }
+ bool IsParameterizedMethod { get; }
+ string Type { get; }
+ string ClassName { get; }
+ string MethodName { get; }
+ RunStateEnum RunState { get; }
+ NUnitEventTestCase Parent { get; }
+}
- public enum RunStateEnum
- {
- NA,
- Runnable,
- Explicit,
- NotRunnable
- }
+public enum RunStateEnum
+{
+ NA,
+ Runnable,
+ Explicit,
+ NotRunnable
+}
- public interface INUnitTestCasePropertyInfo
- {
- RunStateEnum RunState { get; }
- IEnumerable Properties { get; }
- }
+public interface INUnitTestCasePropertyInfo
+{
+ RunStateEnum RunState { get; }
+ IEnumerable Properties { get; }
+}
- public class NUnitEventTestCase : NUnitTestNode, INUnitTestCase, INUnitTestCasePropertyInfo
- {
- public bool IsTestCase => !IsNull && Node.Name == "test-case";
- public bool IsParameterizedMethod => Type == "ParameterizedMethod";
- public string Type => Node.GetAttribute("type");
- public string ClassName => Node.GetAttribute("classname");
- public string MethodName => Node.GetAttribute("methodname");
+public class NUnitEventTestCase : NUnitTestNode, INUnitTestCase, INUnitTestCasePropertyInfo
+{
+ public bool IsTestCase => !IsNull && Node.Name == "test-case";
+ public bool IsParameterizedMethod => Type == "ParameterizedMethod";
+ public string Type => Node.GetAttribute("type");
+ public string ClassName => Node.GetAttribute("classname");
+ public string MethodName => Node.GetAttribute("methodname");
- private RunStateEnum runState = RunStateEnum.NA;
+ private RunStateEnum runState = RunStateEnum.NA;
- public RunStateEnum RunState
+ public RunStateEnum RunState
+ {
+ get
{
- get
+ if (runState == RunStateEnum.NA)
{
- if (runState == RunStateEnum.NA)
+ runState = Node.GetAttribute("runstate") switch
{
- runState = Node.GetAttribute("runstate") switch
- {
- "Runnable" => RunStateEnum.Runnable,
- "Explicit" => RunStateEnum.Explicit,
- "NotRunnable" => RunStateEnum.NotRunnable,
- _ => runState
- };
- }
- return runState;
+ "Runnable" => RunStateEnum.Runnable,
+ "Explicit" => RunStateEnum.Explicit,
+ "NotRunnable" => RunStateEnum.NotRunnable,
+ _ => runState
+ };
}
+ return runState;
}
+ }
- public NUnitEventTestCase(XmlNode testCase) : base(testCase)
- {
- if (Node.ParentNode != null)
- Parent = new NUnitEventTestCase(Node.ParentNode);
- }
-
- public NUnitEventTestCase Parent { get; }
+ public NUnitEventTestCase(XmlNode testCase) : base(testCase)
+ {
+ if (Node.ParentNode != null)
+ Parent = new NUnitEventTestCase(Node.ParentNode);
}
+
+ public NUnitEventTestCase Parent { get; }
}
\ No newline at end of file
diff --git a/src/NUnitTestAdapter/NUnitEngine/NUnitResults.cs b/src/NUnitTestAdapter/NUnitEngine/NUnitResults.cs
index ba432c02..1ea5db32 100644
--- a/src/NUnitTestAdapter/NUnitEngine/NUnitResults.cs
+++ b/src/NUnitTestAdapter/NUnitEngine/NUnitResults.cs
@@ -25,49 +25,48 @@
using System.Xml;
using NUnit.VisualStudio.TestAdapter.Dump;
-namespace NUnit.VisualStudio.TestAdapter.NUnitEngine
+namespace NUnit.VisualStudio.TestAdapter.NUnitEngine;
+
+public class NUnitResults
{
- public class NUnitResults
+ public enum SkipReason
{
- public enum SkipReason
- {
- NoNUnitTests,
- LoadFailure
- }
+ NoNUnitTests,
+ LoadFailure
+ }
- public XmlNode TopNode { get; }
+ public XmlNode TopNode { get; }
- public bool IsRunnable { get; }
+ public bool IsRunnable { get; }
- public string AsString() => FullTopNode.AsString();
+ public string AsString() => FullTopNode.AsString();
- public XmlNode FullTopNode { get; }
- public NUnitResults(XmlNode results)
- {
- FullTopNode = results;
- // Currently, this will always be the case but it might change
- TopNode = results.Name == "test-run" ? results.FirstChild : results;
- // ReSharper disable once StringLiteralTypo
- IsRunnable = TopNode.GetAttribute("runstate") == "Runnable";
- }
+ public XmlNode FullTopNode { get; }
+ public NUnitResults(XmlNode results)
+ {
+ FullTopNode = results;
+ // Currently, this will always be the case but it might change
+ TopNode = results.Name == "test-run" ? results.FirstChild : results;
+ // ReSharper disable once StringLiteralTypo
+ IsRunnable = TopNode.GetAttribute("runstate") == "Runnable";
+ }
- public SkipReason WhatSkipReason()
- {
- var msgNode = TopNode.SelectSingleNode("properties/property[@name='_SKIPREASON']");
- return msgNode != null &&
- new[] { "contains no tests", "Has no TestFixtures" }.Any(msgNode.GetAttribute("value")
- .Contains)
- ? SkipReason.NoNUnitTests
- : SkipReason.LoadFailure;
- }
+ public SkipReason WhatSkipReason()
+ {
+ var msgNode = TopNode.SelectSingleNode("properties/property[@name='_SKIPREASON']");
+ return msgNode != null &&
+ new[] { "contains no tests", "Has no TestFixtures" }.Any(msgNode.GetAttribute("value")
+ .Contains)
+ ? SkipReason.NoNUnitTests
+ : SkipReason.LoadFailure;
+ }
- public bool HasNoNUnitTests => WhatSkipReason() == SkipReason.NoNUnitTests;
+ public bool HasNoNUnitTests => WhatSkipReason() == SkipReason.NoNUnitTests;
- public XmlNodeList TestCases()
- {
- return TopNode.SelectNodes("//test-case");
- }
+ public XmlNodeList TestCases()
+ {
+ return TopNode.SelectNodes("//test-case");
}
}
\ No newline at end of file
diff --git a/src/NUnitTestAdapter/NUnitEngine/NUnitTestEvent.cs b/src/NUnitTestAdapter/NUnitEngine/NUnitTestEvent.cs
index 7cbed4e0..f95da627 100644
--- a/src/NUnitTestAdapter/NUnitEngine/NUnitTestEvent.cs
+++ b/src/NUnitTestAdapter/NUnitEngine/NUnitTestEvent.cs
@@ -28,222 +28,221 @@
using System.Xml;
using System.Xml.Linq;
-namespace NUnit.VisualStudio.TestAdapter.NUnitEngine
+namespace NUnit.VisualStudio.TestAdapter.NUnitEngine;
+
+public interface INUnitTestEventForXml
{
- public interface INUnitTestEventForXml
- {
- XmlNode Node { get; }
- }
+ XmlNode Node { get; }
+}
- public interface INUnitTestEvent : INUnitTestNode
- {
- string Output { get; }
- TimeSpan Duration { get; }
- IEnumerable NUnitAttachments { get; }
- NUnitTestEvent.CheckedTime StartTime();
- NUnitTestEvent.CheckedTime EndTime();
+public interface INUnitTestEvent : INUnitTestNode
+{
+ string Output { get; }
+ TimeSpan Duration { get; }
+ IEnumerable NUnitAttachments { get; }
+ NUnitTestEvent.CheckedTime StartTime();
+ NUnitTestEvent.CheckedTime EndTime();
+
+ bool IsIgnored { get; }
+ NUnitTestEvent.ResultType Result();
+ bool IsFailed { get; }
+ NUnitTestEvent.SiteType Site();
+}
- bool IsIgnored { get; }
- NUnitTestEvent.ResultType Result();
- bool IsFailed { get; }
- NUnitTestEvent.SiteType Site();
+public abstract class NUnitTestEvent : NUnitTestNode, INUnitTestEvent
+{
+ public enum ResultType
+ {
+ Failed,
+ Success,
+ Skipped,
+ Warning,
+ NoIdea
}
- public abstract class NUnitTestEvent : NUnitTestNode, INUnitTestEvent
+ public enum SiteType
{
- public enum ResultType
- {
- Failed,
- Success,
- Skipped,
- Warning,
- NoIdea
- }
-
- public enum SiteType
- {
- NoIdea,
- Test,
- Setup,
- TearDown
- }
- public enum TestTypes
- {
- NoIdea,
- TestFixture,
- TestMethod
- }
+ NoIdea,
+ Test,
+ Setup,
+ TearDown
+ }
+ public enum TestTypes
+ {
+ NoIdea,
+ TestFixture,
+ TestMethod
+ }
- public TestTypes TestType()
+ public TestTypes TestType()
+ {
+ string type = Node.GetAttribute("type");
+ return type switch
{
- string type = Node.GetAttribute("type");
- return type switch
- {
- "TestFixture" => TestTypes.TestFixture,
- "TestMethod" => TestTypes.TestMethod,
- _ => TestTypes.NoIdea
- };
- }
+ "TestFixture" => TestTypes.TestFixture,
+ "TestMethod" => TestTypes.TestMethod,
+ _ => TestTypes.NoIdea
+ };
+ }
- public ResultType Result()
- {
- string res = Node.GetAttribute("result");
- return res switch
- {
- "Failed" => ResultType.Failed,
- "Passed" => ResultType.Success,
- "Skipped" => ResultType.Skipped,
- "Warning" => ResultType.Warning,
- _ => ResultType.NoIdea
- };
- }
+ public ResultType Result()
+ {
+ string res = Node.GetAttribute("result");
+ return res switch
+ {
+ "Failed" => ResultType.Failed,
+ "Passed" => ResultType.Success,
+ "Skipped" => ResultType.Skipped,
+ "Warning" => ResultType.Warning,
+ _ => ResultType.NoIdea
+ };
+ }
- public bool IsFailed => Result() == ResultType.Failed;
+ public bool IsFailed => Result() == ResultType.Failed;
- public SiteType Site()
+ public SiteType Site()
+ {
+ string site = Node.GetAttribute("site");
+ return site switch
{
- string site = Node.GetAttribute("site");
- return site switch
- {
- "SetUp" => SiteType.Setup,
- "TearDown" => SiteType.TearDown,
- _ => SiteType.NoIdea
- };
- }
+ "SetUp" => SiteType.Setup,
+ "TearDown" => SiteType.TearDown,
+ _ => SiteType.NoIdea
+ };
+ }
- public string Label => Node.GetAttribute("label");
+ public string Label => Node.GetAttribute("label");
- public bool IsIgnored => Label == "Ignored";
+ public bool IsIgnored => Label == "Ignored";
- public TimeSpan Duration => TimeSpan.FromSeconds(Node.GetAttribute("duration", 0.0));
+ public TimeSpan Duration => TimeSpan.FromSeconds(Node.GetAttribute("duration", 0.0));
- protected NUnitTestEvent(string testEvent) : this(XmlHelper.CreateXmlNode(testEvent))
- { }
+ protected NUnitTestEvent(string testEvent) : this(XmlHelper.CreateXmlNode(testEvent))
+ { }
- protected NUnitTestEvent(XmlNode node) : base(node)
- {
- }
+ protected NUnitTestEvent(XmlNode node) : base(node)
+ {
+ }
- public string MethodName => Node.GetAttribute("methodname");
- public string ClassName => Node.GetAttribute("classname");
- public string Output => Node.SelectSingleNode("output")?.InnerText.UnEscapeUnicodeCharacters();
+ public string MethodName => Node.GetAttribute("methodname");
+ public string ClassName => Node.GetAttribute("classname");
+ public string Output => Node.SelectSingleNode("output")?.InnerText.UnEscapeUnicodeCharacters();
- public CheckedTime StartTime()
- {
- string startTime = Node.GetAttribute("start-time");
- return startTime != null
- ? new CheckedTime { Ok = true, Time = DateTimeOffset.Parse(startTime, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal) }
- : new CheckedTime { Ok = false, Time = DateTimeOffset.Now };
- }
+ public CheckedTime StartTime()
+ {
+ string startTime = Node.GetAttribute("start-time");
+ return startTime != null
+ ? new CheckedTime { Ok = true, Time = DateTimeOffset.Parse(startTime, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal) }
+ : new CheckedTime { Ok = false, Time = DateTimeOffset.Now };
+ }
- public CheckedTime EndTime()
- {
- string endTime = Node.GetAttribute("end-time");
- return endTime != null
- ? new CheckedTime { Ok = true, Time = DateTimeOffset.Parse(endTime, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal) }
- : new CheckedTime { Ok = false, Time = DateTimeOffset.Now };
- }
+ public CheckedTime EndTime()
+ {
+ string endTime = Node.GetAttribute("end-time");
+ return endTime != null
+ ? new CheckedTime { Ok = true, Time = DateTimeOffset.Parse(endTime, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal) }
+ : new CheckedTime { Ok = false, Time = DateTimeOffset.Now };
+ }
- public struct CheckedTime
- {
- public bool Ok;
- public DateTimeOffset Time;
- }
+ public struct CheckedTime
+ {
+ public bool Ok;
+ public DateTimeOffset Time;
+ }
- private List nUnitAttachments;
+ private List nUnitAttachments;
- public IEnumerable NUnitAttachments
+ public IEnumerable NUnitAttachments
+ {
+ get
{
- get
- {
- if (nUnitAttachments != null)
- return nUnitAttachments;
- nUnitAttachments = new List();
- foreach (XmlNode attachment in Node.SelectNodes("attachments/attachment"))
- {
- var path = attachment.SelectSingleNode("filePath")?.InnerText ?? string.Empty;
- var description = attachment.SelectSingleNode("description")?.InnerText.UnEscapeUnicodeCharacters();
- nUnitAttachments.Add(new NUnitAttachment(path, description));
- }
+ if (nUnitAttachments != null)
return nUnitAttachments;
+ nUnitAttachments = new List();
+ foreach (XmlNode attachment in Node.SelectNodes("attachments/attachment"))
+ {
+ var path = attachment.SelectSingleNode("filePath")?.InnerText ?? string.Empty;
+ var description = attachment.SelectSingleNode("description")?.InnerText.UnEscapeUnicodeCharacters();
+ nUnitAttachments.Add(new NUnitAttachment(path, description));
}
+ return nUnitAttachments;
}
}
+}
- public class NUnitAttachment
+public class NUnitAttachment
+{
+ public NUnitAttachment(string path, string description)
{
- public NUnitAttachment(string path, string description)
- {
- FilePath = path;
- Description = description;
- }
-
- public string FilePath { get; }
-
- public string Description { get; }
+ FilePath = path;
+ Description = description;
}
- public class NUnitProperty
- {
- public string Name { get; }
- public string Value { get; }
+ public string FilePath { get; }
- public bool IsInternal => Name.StartsWith("_", StringComparison.Ordinal);
+ public string Description { get; }
+}
- public NUnitProperty(string name, string value)
- {
- Name = name;
- Value = value;
- }
+public class NUnitProperty
+{
+ public string Name { get; }
+ public string Value { get; }
- public NUnitProperty(XElement node)
- {
- Name = node.Attribute("name").Value;
- Value = node.Attribute("value").Value;
- }
- }
+ public bool IsInternal => Name.StartsWith("_", StringComparison.Ordinal);
- public class NUnitFailure
+ public NUnitProperty(string name, string value)
{
- public string Message { get; }
- public string Stacktrace { get; }
+ Name = name;
+ Value = value;
+ }
- public NUnitFailure(string message, string stacktrace)
- {
- Message = message;
- Stacktrace = stacktrace;
- }
+ public NUnitProperty(XElement node)
+ {
+ Name = node.Attribute("name").Value;
+ Value = node.Attribute("value").Value;
}
+}
+public class NUnitFailure
+{
+ public string Message { get; }
+ public string Stacktrace { get; }
- [Serializable]
- public class NUnitEventWrongTypeException : Exception
+ public NUnitFailure(string message, string stacktrace)
{
- // For guidelines regarding the creation of new exception types, see
- // https://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpgenref/html/cpconerrorraisinghandlingguidelines.asp
- // and
- // https://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncscol/html/csharp07192001.asp
+ Message = message;
+ Stacktrace = stacktrace;
+ }
+}
- public NUnitEventWrongTypeException()
- {
- }
- public NUnitEventWrongTypeException(string message) : base(message)
- {
- }
+[Serializable]
+public class NUnitEventWrongTypeException : Exception
+{
+ // For guidelines regarding the creation of new exception types, see
+ // https://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpgenref/html/cpconerrorraisinghandlingguidelines.asp
+ // and
+ // https://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncscol/html/csharp07192001.asp
- public NUnitEventWrongTypeException(string message, Exception inner) : base(message, inner)
- {
- }
+ public NUnitEventWrongTypeException()
+ {
+ }
- protected NUnitEventWrongTypeException(
- SerializationInfo info,
- StreamingContext context) : base(info, context)
- {
- }
+ public NUnitEventWrongTypeException(string message) : base(message)
+ {
}
-}
+
+ public NUnitEventWrongTypeException(string message, Exception inner) : base(message, inner)
+ {
+ }
+
+ protected NUnitEventWrongTypeException(
+ SerializationInfo info,
+ StreamingContext context) : base(info, context)
+ {
+ }
+}
\ No newline at end of file
diff --git a/src/NUnitTestAdapter/NUnitEngine/NUnitTestEventHeader.cs b/src/NUnitTestAdapter/NUnitEngine/NUnitTestEventHeader.cs
index 4080b55d..335825d2 100644
--- a/src/NUnitTestAdapter/NUnitEngine/NUnitTestEventHeader.cs
+++ b/src/NUnitTestAdapter/NUnitEngine/NUnitTestEventHeader.cs
@@ -24,27 +24,27 @@
using System.Xml;
using NUnit.VisualStudio.TestAdapter.Dump;
-namespace NUnit.VisualStudio.TestAdapter.NUnitEngine
+namespace NUnit.VisualStudio.TestAdapter.NUnitEngine;
+
+public class NUnitTestEventHeader : INUnitTestEventForXml
{
- public class NUnitTestEventHeader : INUnitTestEventForXml
+ public enum EventType
+ {
+ NoIdea,
+ StartTest, // Match: A test was started
+ TestCase, // Match: A test was finished
+ TestSuite, // Match: A suite was finished
+ TestOutput, // Match: Test output, not part of test results, but should be added to it
+ StartRun, // Currently not used
+ StartSuite // Currently not used
+ }
+ public XmlNode Node { get; }
+ public string AsString() => Node.AsString();
+ public string FullName => Node.GetAttribute("fullname");
+ public string Name => Node.GetAttribute("name");
+ public EventType Type { get; }
+ public NUnitTestEventHeader(string sNode)
{
- public enum EventType
- {
- NoIdea,
- StartTest, // Match: A test was started
- TestCase, // Match: A test was finished
- TestSuite, // Match: A suite was finished
- TestOutput, // Match: Test output, not part of test results, but should be added to it
- StartRun, // Currently not used
- StartSuite // Currently not used
- }
- public XmlNode Node { get; }
- public string AsString() => Node.AsString();
- public string FullName => Node.GetAttribute("fullname");
- public string Name => Node.GetAttribute("name");
- public EventType Type { get; }
- public NUnitTestEventHeader(string sNode)
- {
Node = XmlHelper.CreateXmlNode(sNode);
Type = Node.Name switch
{
@@ -57,5 +57,4 @@ public NUnitTestEventHeader(string sNode)
_ => EventType.NoIdea
};
}
- }
}
\ No newline at end of file
diff --git a/src/NUnitTestAdapter/NUnitEngine/NUnitTestEventStartTest.cs b/src/NUnitTestAdapter/NUnitEngine/NUnitTestEventStartTest.cs
index f756302f..0a087725 100644
--- a/src/NUnitTestAdapter/NUnitEngine/NUnitTestEventStartTest.cs
+++ b/src/NUnitTestAdapter/NUnitEngine/NUnitTestEventStartTest.cs
@@ -1,25 +1,24 @@
using System.Xml;
-namespace NUnit.VisualStudio.TestAdapter.NUnitEngine
+namespace NUnit.VisualStudio.TestAdapter.NUnitEngine;
+
+public interface INUnitTestEventStartTest : INUnitTestEvent
{
- public interface INUnitTestEventStartTest : INUnitTestEvent
- {
- }
+}
- ///
- /// Handles the NUnit 'start-test' event.
- ///
- public class NUnitTestEventStartTest : NUnitTestEvent, INUnitTestEventStartTest
- {
- public NUnitTestEventStartTest(INUnitTestEventForXml node) : this(node.Node)
- { }
- public NUnitTestEventStartTest(string testEvent) : this(XmlHelper.CreateXmlNode(testEvent))
- { }
+///
+/// Handles the NUnit 'start-test' event.
+///
+public class NUnitTestEventStartTest : NUnitTestEvent, INUnitTestEventStartTest
+{
+ public NUnitTestEventStartTest(INUnitTestEventForXml node) : this(node.Node)
+ { }
+ public NUnitTestEventStartTest(string testEvent) : this(XmlHelper.CreateXmlNode(testEvent))
+ { }
- public NUnitTestEventStartTest(XmlNode node) : base(node)
- {
- if (node.Name != "start-test")
- throw new NUnitEventWrongTypeException($"Expected 'start-test', got {node.Name}");
- }
+ public NUnitTestEventStartTest(XmlNode node) : base(node)
+ {
+ if (node.Name != "start-test")
+ throw new NUnitEventWrongTypeException($"Expected 'start-test', got {node.Name}");
}
}
\ No newline at end of file
diff --git a/src/NUnitTestAdapter/NUnitEngine/NUnitTestEventSuiteFinished.cs b/src/NUnitTestAdapter/NUnitEngine/NUnitTestEventSuiteFinished.cs
index c1ecb9f2..6f0a900f 100644
--- a/src/NUnitTestAdapter/NUnitEngine/NUnitTestEventSuiteFinished.cs
+++ b/src/NUnitTestAdapter/NUnitEngine/NUnitTestEventSuiteFinished.cs
@@ -1,46 +1,45 @@
using System.Xml;
-namespace NUnit.VisualStudio.TestAdapter.NUnitEngine
+namespace NUnit.VisualStudio.TestAdapter.NUnitEngine;
+
+public interface INUnitTestEventSuiteFinished : INUnitTestEvent
{
- public interface INUnitTestEventSuiteFinished : INUnitTestEvent
- {
- string ReasonMessage { get; }
- bool HasReason { get; }
- string FailureMessage { get; }
- bool HasFailure { get; }
- string StackTrace { get; }
- }
+ string ReasonMessage { get; }
+ bool HasReason { get; }
+ string FailureMessage { get; }
+ bool HasFailure { get; }
+ string StackTrace { get; }
+}
- ///
- /// Handles the NUnit 'test-suite' event.
- ///
- public class NUnitTestEventSuiteFinished : NUnitTestEvent, INUnitTestEventSuiteFinished
- {
- public NUnitTestEventSuiteFinished(INUnitTestEventForXml node) : this(node.Node)
- { }
- public NUnitTestEventSuiteFinished(string testEvent) : this(XmlHelper.CreateXmlNode(testEvent))
- { }
+///
+/// Handles the NUnit 'test-suite' event.
+///
+public class NUnitTestEventSuiteFinished : NUnitTestEvent, INUnitTestEventSuiteFinished
+{
+ public NUnitTestEventSuiteFinished(INUnitTestEventForXml node) : this(node.Node)
+ { }
+ public NUnitTestEventSuiteFinished(string testEvent) : this(XmlHelper.CreateXmlNode(testEvent))
+ { }
- public NUnitTestEventSuiteFinished(XmlNode node) : base(node)
+ public NUnitTestEventSuiteFinished(XmlNode node) : base(node)
+ {
+ if (node.Name != "test-suite")
+ throw new NUnitEventWrongTypeException($"Expected 'test-suite', got {node.Name}");
+ var failureNode = Node.SelectSingleNode("failure");
+ if (failureNode != null)
{
- if (node.Name != "test-suite")
- throw new NUnitEventWrongTypeException($"Expected 'test-suite', got {node.Name}");
- var failureNode = Node.SelectSingleNode("failure");
- if (failureNode != null)
- {
- FailureMessage = failureNode.SelectSingleNode("message")?.InnerText.UnEscapeUnicodeCharacters();
- StackTrace = failureNode.SelectSingleNode("stack-trace")?.InnerText.UnEscapeUnicodeCharacters();
- }
- ReasonMessage = Node.SelectSingleNode("reason/message")?.InnerText.UnEscapeUnicodeCharacters();
+ FailureMessage = failureNode.SelectSingleNode("message")?.InnerText.UnEscapeUnicodeCharacters();
+ StackTrace = failureNode.SelectSingleNode("stack-trace")?.InnerText.UnEscapeUnicodeCharacters();
}
+ ReasonMessage = Node.SelectSingleNode("reason/message")?.InnerText.UnEscapeUnicodeCharacters();
+ }
- public string ReasonMessage { get; }
+ public string ReasonMessage { get; }
- public bool HasReason => !string.IsNullOrEmpty(ReasonMessage);
- public string FailureMessage { get; } = "";
+ public bool HasReason => !string.IsNullOrEmpty(ReasonMessage);
+ public string FailureMessage { get; } = "";
- public string StackTrace { get; } = "";
+ public string StackTrace { get; } = "";
- public bool HasFailure => !string.IsNullOrEmpty(FailureMessage);
- }
+ public bool HasFailure => !string.IsNullOrEmpty(FailureMessage);
}
\ No newline at end of file
diff --git a/src/NUnitTestAdapter/NUnitEngine/NUnitTestEventTestCase.cs b/src/NUnitTestAdapter/NUnitEngine/NUnitTestEventTestCase.cs
index 0b30f12d..4b079cf5 100644
--- a/src/NUnitTestAdapter/NUnitEngine/NUnitTestEventTestCase.cs
+++ b/src/NUnitTestAdapter/NUnitEngine/NUnitTestEventTestCase.cs
@@ -1,47 +1,47 @@
using System.Xml;
-namespace NUnit.VisualStudio.TestAdapter.NUnitEngine
-{
- public interface INUnitTestEventTestCase : INUnitTestEvent
- {
- NUnitFailure Failure { get; }
- string ReasonMessage { get; }
- bool HasReason { get; }
-
- bool HasFailure { get; }
+namespace NUnit.VisualStudio.TestAdapter.NUnitEngine;
- ///
- /// Find stacktrace in assertion nodes if not defined.
- ///
- string StackTrace { get; }
+public interface INUnitTestEventTestCase : INUnitTestEvent
+{
+ NUnitFailure Failure { get; }
+ string ReasonMessage { get; }
+ bool HasReason { get; }
- ///
- /// Complete formatted stacktrace
- ///
- string FailureStackTrace { get; }
- }
+ bool HasFailure { get; }
+ ///
+ /// Find stacktrace in assertion nodes if not defined.
+ ///
+ string StackTrace { get; }
///
- /// Handles the NUnit 'test-case' event.
+ /// Complete formatted stacktrace.
///
- public class NUnitTestEventTestCase : NUnitTestEvent, INUnitTestEventTestCase
+ string FailureStackTrace { get; }
+}
+
+
+///
+/// Handles the NUnit 'test-case' event.
+///
+public class NUnitTestEventTestCase : NUnitTestEvent, INUnitTestEventTestCase
+{
+ public NUnitTestEventTestCase(INUnitTestEventForXml node)
+ : this(node.Node)
{
- public NUnitTestEventTestCase(INUnitTestEventForXml node)
- : this(node.Node)
- {
}
- public NUnitTestEventTestCase(string testEvent)
- : this(XmlHelper.CreateXmlNode(testEvent))
- {
+ public NUnitTestEventTestCase(string testEvent)
+ : this(XmlHelper.CreateXmlNode(testEvent))
+ {
}
- public NUnitFailure Failure { get; }
+ public NUnitFailure Failure { get; }
- public NUnitTestEventTestCase(XmlNode node)
- : base(node)
- {
+ public NUnitTestEventTestCase(XmlNode node)
+ : base(node)
+ {
if (node.Name != "test-case")
throw new NUnitEventWrongTypeException($"Expected 'test-case', got {node.Name}");
var failureNode = Node.SelectSingleNode("failure");
@@ -54,21 +54,21 @@ public NUnitTestEventTestCase(XmlNode node)
ReasonMessage = Node.SelectSingleNode("reason/message")?.InnerText.UnEscapeUnicodeCharacters();
}
- public string ReasonMessage { get; }
+ public string ReasonMessage { get; }
- public bool HasReason => !string.IsNullOrEmpty(ReasonMessage);
- public bool HasFailure => Failure != null;
+ public bool HasReason => !string.IsNullOrEmpty(ReasonMessage);
+ public bool HasFailure => Failure != null;
- public string FailureStackTrace => $"{Failure?.Stacktrace ?? ""}\n{StackTrace}";
+ public string FailureStackTrace => $"{Failure?.Stacktrace ?? ""}\n{StackTrace}";
- ///
- /// Find stacktrace in assertion nodes if not defined.
- ///
- public string StackTrace
+ ///
+ /// Find stacktrace in assertion nodes if not defined.
+ ///
+ public string StackTrace
+ {
+ get
{
- get
- {
string stackTrace = string.Empty;
int i = 1;
foreach (XmlNode assertionStacktraceNode in Node.SelectNodes("assertions/assertion/stack-trace"))
@@ -79,6 +79,5 @@ public string StackTrace
return stackTrace;
}
- }
}
}
\ No newline at end of file
diff --git a/src/NUnitTestAdapter/NUnitEngine/NUnitTestEventTestOutput.cs b/src/NUnitTestAdapter/NUnitEngine/NUnitTestEventTestOutput.cs
index 21a6cc7c..78b9f1bc 100644
--- a/src/NUnitTestAdapter/NUnitEngine/NUnitTestEventTestOutput.cs
+++ b/src/NUnitTestAdapter/NUnitEngine/NUnitTestEventTestOutput.cs
@@ -23,69 +23,65 @@
using System.Xml;
-namespace NUnit.VisualStudio.TestAdapter.NUnitEngine
+namespace NUnit.VisualStudio.TestAdapter.NUnitEngine;
+
+public interface INUnitTestEventTestOutput
{
- public interface INUnitTestEventTestOutput
- {
- NUnitTestEventTestOutput.Streams Stream { get; }
- string TestId { get; }
- string TestName { get; }
+ NUnitTestEventTestOutput.Streams Stream { get; }
+ string TestId { get; }
+ string TestName { get; }
- ///
- /// Returns the output information.
- ///
- string Content { get; }
+ ///
+ /// Returns the output information.
+ ///
+ string Content { get; }
- bool IsProgressStream { get; }
- bool IsErrorStream { get; }
- bool IsNullOrEmptyStream { get; }
+ bool IsProgressStream { get; }
+ bool IsErrorStream { get; }
+ bool IsNullOrEmptyStream { get; }
+}
+
+///
+/// Handles the 'test-output' event.
+///
+public class NUnitTestEventTestOutput(XmlNode node) : NUnitTestEvent(node), INUnitTestEventTestOutput
+{
+ public enum Streams
+ {
+ NoIdea,
+ Error,
+ Progress
}
- ///
- /// Handles the 'test-output' event.
- ///
- public class NUnitTestEventTestOutput : NUnitTestEvent, INUnitTestEventTestOutput
+ public Streams Stream { get; } = node.GetAttribute("stream") switch
{
- public enum Streams
- {
- NoIdea,
- Error,
- Progress
- }
+ "Error" => Streams.Error,
+ "Progress" => Streams.Progress,
+ _ => Streams.NoIdea
+ };
- public Streams Stream { get; }
- public string TestId => Node.GetAttribute("testid");
+ public string TestId => Node.GetAttribute("testid");
- public string TestName => Node.GetAttribute("testname");
+ public string TestName => Node.GetAttribute("testname");
- public NUnitTestEventTestOutput(INUnitTestEventForXml theEvent) : this(theEvent.Node)
- {
- if (theEvent.Node.Name != "test-output")
- throw new NUnitEventWrongTypeException($"Expected 'test-output', got {theEvent.Node.Name}");
- }
- public NUnitTestEventTestOutput(XmlNode node) : base(node)
- {
- Stream = node.GetAttribute("stream") switch
- {
- "Error" => Streams.Error,
- "Progress" => Streams.Progress,
- _ => Streams.NoIdea
- };
- }
+ public NUnitTestEventTestOutput(INUnitTestEventForXml theEvent) : this(theEvent.Node)
+ {
+ if (theEvent.Node.Name != "test-output")
+ throw new NUnitEventWrongTypeException($"Expected 'test-output', got {theEvent.Node.Name}");
+ }
- public bool IsProgressStream => Stream == Streams.Progress;
- public bool IsErrorStream => Stream == Streams.Error;
+ public bool IsProgressStream => Stream == Streams.Progress;
+ public bool IsErrorStream => Stream == Streams.Error;
- public bool IsNullOrEmptyStream => Stream == Streams.NoIdea;
+ public bool IsNullOrEmptyStream => Stream == Streams.NoIdea;
- ///
- /// Returns the output information.
- ///
- public string Content => Node.InnerText;
+ ///
+ /// Returns the output information.
+ ///
+ public string Content => Node.InnerText;
- // Notes:
- // The input doesnt have any id, but used testid instead.
- // Properties FullName and Name is not in use
- }
+ // Notes:
+ // The input doesnt have any id, but used testid instead.
+ // Properties FullName and Name is not in use
}
\ No newline at end of file
diff --git a/src/NUnitTestAdapter/NUnitEngine/NUnitTestNode.cs b/src/NUnitTestAdapter/NUnitEngine/NUnitTestNode.cs
index 9f0e07f2..a2cd0bc1 100644
--- a/src/NUnitTestAdapter/NUnitEngine/NUnitTestNode.cs
+++ b/src/NUnitTestAdapter/NUnitEngine/NUnitTestNode.cs
@@ -1,40 +1,39 @@
using System.Collections.Generic;
using System.Xml;
-namespace NUnit.VisualStudio.TestAdapter.NUnitEngine
+namespace NUnit.VisualStudio.TestAdapter.NUnitEngine;
+
+public interface INUnitTestNode
{
- public interface INUnitTestNode
- {
- string Id { get; }
- string FullName { get; }
- string Name { get; }
- IEnumerable Properties { get; }
- string Seed { get; }
- }
+ string Id { get; }
+ string FullName { get; }
+ string Name { get; }
+ IEnumerable Properties { get; }
+ string Seed { get; }
+}
- public abstract class NUnitTestNode : INUnitTestNode
- {
- protected XmlNode Node { get; set; } // Need to be protected, but still the outputnodes are XmlNode
- public virtual string Id => Node.GetAttribute("id");
- public string FullName => Node.GetAttribute("fullname");
- public string Name => Node.GetAttribute("name");
+public abstract class NUnitTestNode : INUnitTestNode
+{
+ protected XmlNode Node { get; set; } // Need to be protected, but still the outputnodes are XmlNode
+ public virtual string Id => Node.GetAttribute("id");
+ public string FullName => Node.GetAttribute("fullname");
+ public string Name => Node.GetAttribute("name");
- public bool IsNull => Node == null;
+ public bool IsNull => Node == null;
- private readonly List properties = new ();
- public IEnumerable Properties => properties;
- public string Seed => Node.GetAttribute("seed");
+ private readonly List properties = new ();
+ public IEnumerable Properties => properties;
+ public string Seed => Node.GetAttribute("seed");
- protected NUnitTestNode(XmlNode node)
+ protected NUnitTestNode(XmlNode node)
+ {
+ Node = node;
+ var propertyNodes = Node.SelectNodes("properties/property");
+ if (propertyNodes != null)
{
- Node = node;
- var propertyNodes = Node.SelectNodes("properties/property");
- if (propertyNodes != null)
+ foreach (XmlNode prop in propertyNodes)
{
- foreach (XmlNode prop in propertyNodes)
- {
- properties.Add(new NUnitProperty(prop.GetAttribute("name"), prop.GetAttribute("value")));
- }
+ properties.Add(new NUnitProperty(prop.GetAttribute("name"), prop.GetAttribute("value")));
}
}
}
diff --git a/src/NUnitTestAdapter/NUnitEngine/UnicodeEscapeHelper.cs b/src/NUnitTestAdapter/NUnitEngine/UnicodeEscapeHelper.cs
index 95a17cc4..5949e930 100644
--- a/src/NUnitTestAdapter/NUnitEngine/UnicodeEscapeHelper.cs
+++ b/src/NUnitTestAdapter/NUnitEngine/UnicodeEscapeHelper.cs
@@ -2,12 +2,12 @@
using System.Globalization;
using System.Text;
-namespace NUnit.VisualStudio.TestAdapter.NUnitEngine
+namespace NUnit.VisualStudio.TestAdapter.NUnitEngine;
+
+internal static class UnicodeEscapeHelper
{
- internal static class UnicodeEscapeHelper
+ public static string UnEscapeUnicodeCharacters(this string text)
{
- public static string UnEscapeUnicodeCharacters(this string text)
- {
if (text == null)
return null;
@@ -34,8 +34,8 @@ public static string UnEscapeUnicodeCharacters(this string text)
return stringBuilder.ToString();
}
- private static bool TryUnEscapeOneCharacter(string text, int position, out char escapedChar, out int extraCharacterRead)
- {
+ private static bool TryUnEscapeOneCharacter(string text, int position, out char escapedChar, out int extraCharacterRead)
+ {
const string unicodeEscapeSample = "u0000";
extraCharacterRead = 0;
@@ -52,5 +52,4 @@ private static bool TryUnEscapeOneCharacter(string text, int position, out char
return true;
}
- }
}
\ No newline at end of file
diff --git a/src/NUnitTestAdapter/NUnitEventListener.cs b/src/NUnitTestAdapter/NUnitEventListener.cs
index aa884e2f..0e07de39 100644
--- a/src/NUnitTestAdapter/NUnitEventListener.cs
+++ b/src/NUnitTestAdapter/NUnitEventListener.cs
@@ -35,226 +35,217 @@
using NUnit.VisualStudio.TestAdapter.Internal;
using NUnit.VisualStudio.TestAdapter.NUnitEngine;
-namespace NUnit.VisualStudio.TestAdapter
-{
- ///
- /// NUnitEventListener implements the EventListener interface and
- /// translates each event into a message for the VS test platform.
- ///
- public class NUnitEventListener :
+namespace NUnit.VisualStudio.TestAdapter;
+
+///
+/// NUnitEventListener implements the EventListener interface and
+/// translates each event into a message for the VS test platform.
+///
+public class NUnitEventListener(ITestConverterCommon testConverter, INUnit3TestExecutor executor)
+ :
#if NET462
MarshalByRefObject,
#endif
ITestEventListener, IDisposable // Public for testing
- {
- private static readonly ICollection EmptyNodes = new List();
- private ITestExecutionRecorder Recorder { get; }
- private ITestConverterCommon TestConverter { get; }
- private IAdapterSettings Settings { get; }
- private Dictionary> OutputNodes { get; } = new();
+{
+ private static readonly ICollection EmptyNodes = new List();
+ private ITestExecutionRecorder Recorder { get; } = executor.FrameworkHandle;
+ private ITestConverterCommon TestConverter { get; } = testConverter;
+ private IAdapterSettings Settings { get; } = executor.Settings;
+ private Dictionary> OutputNodes { get; } = [];
#if NET462
- public override object InitializeLifetimeService()
- {
- // Give the listener an infinite lease lifetime by returning null
- // https://msdn.microsoft.com/en-us/magazine/cc300474.aspx#edupdate
- // This also means RemotingServices.Disconnect() must be called to prevent memory leaks
- // https://nbevans.wordpress.com/2011/04/17/memory-leaks-with-an-infinite-lifetime-instance-of-marshalbyrefobject/
- return null;
- }
+ public override object InitializeLifetimeService()
+ {
+ // Give the listener an infinite lease lifetime by returning null
+ // https://msdn.microsoft.com/en-us/magazine/cc300474.aspx#edupdate
+ // This also means RemotingServices.Disconnect() must be called to prevent memory leaks
+ // https://nbevans.wordpress.com/2011/04/17/memory-leaks-with-an-infinite-lifetime-instance-of-marshalbyrefobject/
+ return null;
+ }
#endif
- private INUnit3TestExecutor Executor { get; }
-
- public NUnitEventListener(ITestConverterCommon testConverter, INUnit3TestExecutor executor)
- {
- Executor = executor;
- dumpXml = executor.Dump;
- Settings = executor.Settings;
- Recorder = executor.FrameworkHandle;
- TestConverter = testConverter;
- }
+ private INUnit3TestExecutor Executor { get; } = executor;
- #region ITestEventListener
+ #region ITestEventListener
- public void OnTestEvent(string report)
+ public void OnTestEvent(string report)
+ {
+ var node = new NUnitTestEventHeader(report);
+ dumpXml?.AddTestEvent(node.AsString());
+ try
{
- var node = new NUnitTestEventHeader(report);
- dumpXml?.AddTestEvent(node.AsString());
- try
- {
- switch (node.Type)
- {
- case NUnitTestEventHeader.EventType.StartTest:
- TestStarted(new NUnitTestEventStartTest(node));
- break;
-
- case NUnitTestEventHeader.EventType.TestCase:
- TestFinished(new NUnitTestEventTestCase(node));
- break;
-
- case NUnitTestEventHeader.EventType.TestSuite:
- SuiteFinished(new NUnitTestEventSuiteFinished(node));
- break;
-
- case NUnitTestEventHeader.EventType.TestOutput:
- TestOutput(new NUnitTestEventTestOutput(node));
- break;
- }
- }
- catch (Exception ex)
+ switch (node.Type)
{
- Recorder.SendMessage(TestMessageLevel.Warning, $"Error processing {node.Name} event for {node.FullName}");
- Recorder.SendMessage(TestMessageLevel.Warning, ex.ToString());
- }
- }
+ case NUnitTestEventHeader.EventType.StartTest:
+ TestStarted(new NUnitTestEventStartTest(node));
+ break;
- #endregion
+ case NUnitTestEventHeader.EventType.TestCase:
+ TestFinished(new NUnitTestEventTestCase(node));
+ break;
- #region IDisposable
- private bool disposed;
+ case NUnitTestEventHeader.EventType.TestSuite:
+ SuiteFinished(new NUnitTestEventSuiteFinished(node));
+ break;
- public void Dispose()
+ case NUnitTestEventHeader.EventType.TestOutput:
+ TestOutput(new NUnitTestEventTestOutput(node));
+ break;
+ }
+ }
+ catch (Exception ex)
{
- Dispose(true);
- GC.SuppressFinalize(this);
+ Recorder.SendMessage(TestMessageLevel.Warning, $"Error processing {node.Name} event for {node.FullName}");
+ Recorder.SendMessage(TestMessageLevel.Warning, ex.ToString());
}
+ }
- protected virtual void Dispose(bool disposing)
+ #endregion
+
+ #region IDisposable
+ private bool disposed;
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!disposed)
{
- if (!disposed)
+ if (disposing)
{
- if (disposing)
- {
#if NET462
- RemotingServices.Disconnect(this);
+ RemotingServices.Disconnect(this);
#endif
- }
}
- disposed = true;
}
+ disposed = true;
+ }
- ~NUnitEventListener()
- {
- Dispose(false);
- }
- #endregion
+ ~NUnitEventListener()
+ {
+ Dispose(false);
+ }
+ #endregion
- public void TestStarted(INUnitTestEventStartTest testNode)
- {
- var ourCase = TestConverter.GetCachedTestCase(testNode.Id);
+ public void TestStarted(INUnitTestEventStartTest testNode)
+ {
+ var ourCase = TestConverter.GetCachedTestCase(testNode.Id);
+
+ // Simply ignore any TestCase not found in the cache
+ if (ourCase != null)
+ Recorder.RecordStart(ourCase);
+ }
- // Simply ignore any TestCase not found in the cache
- if (ourCase != null)
- Recorder.RecordStart(ourCase);
+ ///
+ /// Collects up all text output messages in the current test, and outputs them here.
+ /// Note: Error and Progress are handled in TestOutput.
+ ///
+ /// resultNode.
+ public void TestFinished(INUnitTestEventTestCase resultNode)
+ {
+ var testId = resultNode.Id;
+ if (OutputNodes.TryGetValue(testId, out var outputNodes))
+ {
+ OutputNodes.Remove(testId);
}
- ///
- /// Collects up all text output messages in the current test, and outputs them here.
- /// Note: Error and Progress are handled in TestOutput.
- ///
- ///
- public void TestFinished(INUnitTestEventTestCase resultNode)
+ var result = TestConverter.GetVsTestResults(resultNode, outputNodes ?? EmptyNodes);
+ if (Settings.ConsoleOut >= 1)
{
- var testId = resultNode.Id;
- if (OutputNodes.TryGetValue(testId, out var outputNodes))
+ if (!result.ConsoleOutput.IsNullOrWhiteSpace() && result.ConsoleOutput != Nl)
{
- OutputNodes.Remove(testId);
+ string msg = result.ConsoleOutput;
+ if (Settings.UseTestNameInConsoleOutput)
+ msg = $"{resultNode.Name}: {msg}";
+ var messageLevel = Settings.ConsoleOut == 1
+ ? TestMessageLevel.Informational
+ : TestMessageLevel.Warning;
+ Recorder.SendMessage(messageLevel, msg);
}
+ if (!resultNode.ReasonMessage.IsNullOrWhiteSpace())
+ {
+ Recorder.SendMessage(TestMessageLevel.Informational, $"{resultNode.Name}: {resultNode.ReasonMessage}");
+ }
+ }
- var result = TestConverter.GetVsTestResults(resultNode, outputNodes ?? EmptyNodes);
- if (Settings.ConsoleOut >= 1)
+ if (result.TestCaseResult != null)
+ {
+ Recorder.RecordEnd(result.TestCaseResult.TestCase, result.TestCaseResult.Outcome);
+ foreach (var vsResult in result.TestResults)
{
- if (!result.ConsoleOutput.IsNullOrWhiteSpace() && result.ConsoleOutput != NL)
- {
- string msg = result.ConsoleOutput;
- if (Settings.UseTestNameInConsoleOutput)
- msg = $"{resultNode.Name}: {msg}";
- var messageLevel = Settings.ConsoleOut == 1
- ? TestMessageLevel.Informational
- : TestMessageLevel.Warning;
- Recorder.SendMessage(messageLevel, msg);
- }
- if (!resultNode.ReasonMessage.IsNullOrWhiteSpace())
- {
- Recorder.SendMessage(TestMessageLevel.Informational, $"{resultNode.Name}: {resultNode.ReasonMessage}");
- }
+ Recorder.RecordResult(vsResult);
}
- if (result.TestCaseResult != null)
+ if (result.TestCaseResult.Outcome == TestOutcome.Failed && Settings.StopOnError)
{
- Recorder.RecordEnd(result.TestCaseResult.TestCase, result.TestCaseResult.Outcome);
- foreach (var vsResult in result.TestResults)
- {
- Recorder.RecordResult(vsResult);
- }
-
- if (result.TestCaseResult.Outcome == TestOutcome.Failed && Settings.StopOnError)
- {
- Executor.StopRun();
- }
+ Executor.StopRun();
}
}
+ }
- public void SuiteFinished(INUnitTestEventSuiteFinished resultNode)
+ public void SuiteFinished(INUnitTestEventSuiteFinished resultNode)
+ {
+ if (!resultNode.IsFailed)
+ return;
+ var site = resultNode.Site();
+ if (site != NUnitTestEvent.SiteType.Setup && site != NUnitTestEvent.SiteType.TearDown)
+ return;
+ Recorder.SendMessage(TestMessageLevel.Warning, $"{site} failed for test fixture {resultNode.FullName}");
+
+ if (resultNode.HasFailure)
{
- if (!resultNode.IsFailed)
- return;
- var site = resultNode.Site();
- if (site != NUnitTestEvent.SiteType.Setup && site != NUnitTestEvent.SiteType.TearDown)
- return;
- Recorder.SendMessage(TestMessageLevel.Warning, $"{site} failed for test fixture {resultNode.FullName}");
-
- if (resultNode.HasFailure)
- {
- string msg = resultNode.FailureMessage;
- var stackNode = resultNode.StackTrace;
- if (!string.IsNullOrEmpty(stackNode) && Settings.IncludeStackTraceForSuites)
- msg += $"\nStackTrace: {stackNode}";
- Recorder.SendMessage(TestMessageLevel.Warning, msg);
- }
+ string msg = resultNode.FailureMessage;
+ var stackNode = resultNode.StackTrace;
+ if (!string.IsNullOrEmpty(stackNode) && Settings.IncludeStackTraceForSuites)
+ msg += $"\nStackTrace: {stackNode}";
+ Recorder.SendMessage(TestMessageLevel.Warning, msg);
}
+ }
- private static readonly string NL = Environment.NewLine;
- private static readonly int NL_LENGTH = NL.Length;
- private readonly IDumpXml dumpXml;
+ private static readonly string Nl = Environment.NewLine;
+ private static readonly int NlLength = Nl.Length;
+ private readonly IDumpXml dumpXml = executor.Dump;
- ///
- /// Error stream and Progress stream are both sent here.
- ///
- ///
- public void TestOutput(INUnitTestEventTestOutput outputNodeEvent)
- {
- if (Settings.ConsoleOut == 0)
- return;
- string text = outputNodeEvent.Content;
+ ///
+ /// Error stream and Progress stream are both sent here.
+ ///
+ /// outputNodeEvent.
+ public void TestOutput(INUnitTestEventTestOutput outputNodeEvent)
+ {
+ if (Settings.ConsoleOut == 0)
+ return;
+ string text = outputNodeEvent.Content;
- // Remove final newline since logger will add one
- if (text.EndsWith(NL))
- text = text.Substring(0, text.Length - NL_LENGTH);
+ // Remove final newline since logger will add one
+ if (text.EndsWith(Nl))
+ text = text.Substring(0, text.Length - NlLength);
- if (text.IsNullOrWhiteSpace())
- {
- return;
- }
+ if (text.IsNullOrWhiteSpace())
+ {
+ return;
+ }
- string testId = outputNodeEvent.TestId;
- if (!string.IsNullOrEmpty(testId))
+ string testId = outputNodeEvent.TestId;
+ if (!string.IsNullOrEmpty(testId))
+ {
+ if (!OutputNodes.TryGetValue(testId, out var outputNodes))
{
- if (!OutputNodes.TryGetValue(testId, out var outputNodes))
- {
- outputNodes = new List();
- OutputNodes.Add(testId, outputNodes);
- }
-
- outputNodes.Add(outputNodeEvent);
+ outputNodes = new List();
+ OutputNodes.Add(testId, outputNodes);
}
- var testMessageLevel = outputNodeEvent.IsErrorStream
- ? TestMessageLevel.Warning
- : TestMessageLevel.Informational;
-
- Recorder.SendMessage(testMessageLevel, text);
+ outputNodes.Add(outputNodeEvent);
}
+
+ var testMessageLevel = outputNodeEvent.IsErrorStream
+ ? TestMessageLevel.Warning
+ : TestMessageLevel.Informational;
+
+ Recorder.SendMessage(testMessageLevel, text);
}
-}
+}
\ No newline at end of file
diff --git a/src/NUnitTestAdapter/NUnitTestAdapter.cs b/src/NUnitTestAdapter/NUnitTestAdapter.cs
index 4446d108..14666e7a 100644
--- a/src/NUnitTestAdapter/NUnitTestAdapter.cs
+++ b/src/NUnitTestAdapter/NUnitTestAdapter.cs
@@ -39,294 +39,293 @@
using NUnit.VisualStudio.TestAdapter.NUnitEngine;
-namespace NUnit.VisualStudio.TestAdapter
+namespace NUnit.VisualStudio.TestAdapter;
+
+///
+/// NUnitTestAdapter is the common base for the
+/// NUnit discoverer and executor classes.
+///
+public abstract class NUnitTestAdapter
{
+ #region Constants
+
///
- /// NUnitTestAdapter is the common base for the
- /// NUnit discoverer and executor classes.
+ /// The Uri used to identify the NUnitExecutor.
///
- public abstract class NUnitTestAdapter
- {
- #region Constants
+ public const string ExecutorUri = "executor://NUnit3TestExecutor";
- ///
- /// The Uri used to identify the NUnitExecutor.
- ///
- public const string ExecutorUri = "executor://NUnit3TestExecutor";
+ public const string SettingsName = "NUnitAdapterSettings";
- public const string SettingsName = "NUnitAdapterSettings";
+ #endregion
- #endregion
+ #region Constructor
- #region Constructor
-
- protected NUnitTestAdapter()
- {
+ protected NUnitTestAdapter()
+ {
#if !NET462
- AdapterVersion = typeof(NUnitTestAdapter).GetTypeInfo().Assembly.GetName().Version.ToString();
+ AdapterVersion = typeof(NUnitTestAdapter).GetTypeInfo().Assembly.GetName().Version.ToString();
#else
- AdapterVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString();
+ AdapterVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString();
#endif
- NUnitEngineAdapter = new NUnitEngineAdapter();
- }
+ NUnitEngineAdapter = new NUnitEngineAdapter();
+ }
- #endregion
+ #endregion
- #region Properties
+ #region Properties
- public IAdapterSettings Settings { get; private set; }
+ public IAdapterSettings Settings { get; private set; }
- // The adapter version
- protected string AdapterVersion { get; set; }
+ // The adapter version
+ protected string AdapterVersion { get; set; }
- private NUnitEngineAdapter nUnitEngineAdapter;
+ private NUnitEngineAdapter nUnitEngineAdapter;
- public NUnitEngineAdapter NUnitEngineAdapter
- {
- get => nUnitEngineAdapter ??= new NUnitEngineAdapter();
- private set => nUnitEngineAdapter = value;
- }
+ public NUnitEngineAdapter NUnitEngineAdapter
+ {
+ get => nUnitEngineAdapter ??= new NUnitEngineAdapter();
+ private set => nUnitEngineAdapter = value;
+ }
- // Our logger used to display messages
- protected TestLogger TestLog { get; private set; }
+ // Our logger used to display messages
+ protected TestLogger TestLog { get; private set; }
- protected string WorkDir { get; private set; }
+ protected string WorkDir { get; private set; }
- private static string entryExeName;
+ private static string entryExeName;
- private static string whoIsCallingUsEntry;
+ private static string whoIsCallingUsEntry;
- public static string WhoIsCallingUsEntry
+ public static string WhoIsCallingUsEntry
+ {
+ get
{
- get
- {
- if (whoIsCallingUsEntry != null)
- return whoIsCallingUsEntry;
- if (entryExeName == null)
- {
- var entryAssembly = Assembly.GetEntryAssembly();
- if (entryAssembly != null)
- entryExeName = entryAssembly.Location;
- }
- whoIsCallingUsEntry = entryExeName;
+ if (whoIsCallingUsEntry != null)
return whoIsCallingUsEntry;
+ if (entryExeName == null)
+ {
+ var entryAssembly = Assembly.GetEntryAssembly();
+ if (entryAssembly != null)
+ entryExeName = entryAssembly.Location;
}
+ whoIsCallingUsEntry = entryExeName;
+ return whoIsCallingUsEntry;
}
+ }
- public static bool IsRunningUnderIde
+ public static bool IsRunningUnderIde
+ {
+ get
{
- get
- {
- var exe = WhoIsCallingUsEntry;
- return exe != null && (
- exe.Contains("vstest.executionengine") ||
- exe.Contains("vstest.discoveryengine") ||
- exe.Contains("TE.ProcessHost"));
- }
+ var exe = WhoIsCallingUsEntry;
+ return exe != null && (
+ exe.Contains("vstest.executionengine") ||
+ exe.Contains("vstest.discoveryengine") ||
+ exe.Contains("TE.ProcessHost"));
}
+ }
- public List ForbiddenFolders { get; private set; }
+ public List ForbiddenFolders { get; private set; }
- #endregion
+ #endregion
- #region Protected Helper Methods
+ #region Protected Helper Methods
- // The Adapter is constructed using the default constructor.
- // We don't have any info to initialize it until one of the
- // ITestDiscovery or ITestExecutor methods is called. Each
- // Discover or Execute method must call this method.
- protected void Initialize(IDiscoveryContext context, IMessageLogger messageLogger)
+ // The Adapter is constructed using the default constructor.
+ // We don't have any info to initialize it until one of the
+ // ITestDiscovery or ITestExecutor methods is called. Each
+ // Discover or Execute method must call this method.
+ protected void Initialize(IDiscoveryContext context, IMessageLogger messageLogger)
+ {
+ NUnitEngineAdapter.Initialize();
+ TestLog = new TestLogger(messageLogger);
+ Settings = new AdapterSettings(TestLog);
+ NUnitEngineAdapter.InitializeSettingsAndLogging(Settings, TestLog);
+ TestLog.InitSettings(Settings);
+ try
{
- NUnitEngineAdapter.Initialize();
- TestLog = new TestLogger(messageLogger);
- Settings = new AdapterSettings(TestLog);
- NUnitEngineAdapter.InitializeSettingsAndLogging(Settings, TestLog);
- TestLog.InitSettings(Settings);
- try
- {
- Settings.Load(context, TestLog);
- TestLog.Verbosity = Settings.Verbosity;
- InitializeForbiddenFolders();
- SetCurrentWorkingDirectory();
- }
- catch (Exception e)
- {
- TestLog.Warning("Error initializing RunSettings. Default settings will be used");
- TestLog.Warning(e.ToString());
- }
- finally
- {
- TestLog.DebugRunfrom();
- }
+ Settings.Load(context, TestLog);
+ TestLog.Verbosity = Settings.Verbosity;
+ InitializeForbiddenFolders();
+ SetCurrentWorkingDirectory();
}
-
- public void InitializeForbiddenFolders()
+ catch (Exception e)
{
- ForbiddenFolders = new[]
- {
- Environment.GetEnvironmentVariable("ProgramW6432"),
- Environment.GetEnvironmentVariable("ProgramFiles(x86)"),
- Environment.GetEnvironmentVariable("windir"),
- }.Where(o => !string.IsNullOrEmpty(o)).Select(o => o.ToLower() + @"\").ToList();
+ TestLog.Warning("Error initializing RunSettings. Default settings will be used");
+ TestLog.Warning(e.ToString());
}
-
- private void SetCurrentWorkingDirectory()
+ finally
{
- string dir = Directory.GetCurrentDirectory();
- bool foundForbiddenFolder = CheckDirectory(dir);
- if (foundForbiddenFolder)
- Directory.SetCurrentDirectory(Path.GetTempPath());
+ TestLog.DebugRunfrom();
}
+ }
+
+ public void InitializeForbiddenFolders()
+ {
+ ForbiddenFolders = new[]
+ {
+ Environment.GetEnvironmentVariable("ProgramW6432"),
+ Environment.GetEnvironmentVariable("ProgramFiles(x86)"),
+ Environment.GetEnvironmentVariable("windir"),
+ }.Where(o => !string.IsNullOrEmpty(o)).Select(o => o.ToLower() + @"\").ToList();
+ }
+
+ private void SetCurrentWorkingDirectory()
+ {
+ string dir = Directory.GetCurrentDirectory();
+ bool foundForbiddenFolder = CheckDirectory(dir);
+ if (foundForbiddenFolder)
+ Directory.SetCurrentDirectory(Path.GetTempPath());
+ }
- ///
- /// If a directory matches one of the forbidden folders, then we should reroute, so we return true in that case.
- ///
- public bool CheckDirectory(string dir)
+ ///
+ /// If a directory matches one of the forbidden folders, then we should reroute, so we return true in that case.
+ ///
+ public bool CheckDirectory(string dir)
+ {
+ string checkDir = (dir.EndsWith("\\") ? dir : dir + "\\");
+ return ForbiddenFolders.Any(o => checkDir.StartsWith(o, StringComparison.OrdinalIgnoreCase));
+ }
+
+ protected TestPackage CreateTestPackage(string assemblyName, IGrouping testCases)
+ {
+ var package = new TestPackage(assemblyName);
+
+ if (Settings.ShadowCopyFiles)
{
- string checkDir = (dir.EndsWith("\\") ? dir : dir + "\\");
- return ForbiddenFolders.Any(o => checkDir.StartsWith(o, StringComparison.OrdinalIgnoreCase));
+ package.Settings[PackageSettings.ShadowCopyFiles] = true;
+ TestLog.Debug(" Setting ShadowCopyFiles to true");
}
- protected TestPackage CreateTestPackage(string assemblyName, IGrouping testCases)
+ if (Debugger.IsAttached && !Settings.AllowParallelWithDebugger)
{
- var package = new TestPackage(assemblyName);
-
- if (Settings.ShadowCopyFiles)
- {
- package.Settings[PackageSettings.ShadowCopyFiles] = true;
- TestLog.Debug(" Setting ShadowCopyFiles to true");
- }
+ package.Settings[PackageSettings.NumberOfTestWorkers] = 0;
+ TestLog.Debug(" Setting NumberOfTestWorkers to zero for Debugging");
+ }
+ else
+ {
+ int workers = Settings.NumberOfTestWorkers;
+ if (workers >= 0)
+ package.Settings[PackageSettings.NumberOfTestWorkers] = workers;
+ }
- if (Debugger.IsAttached && !Settings.AllowParallelWithDebugger)
- {
- package.Settings[PackageSettings.NumberOfTestWorkers] = 0;
- TestLog.Debug(" Setting NumberOfTestWorkers to zero for Debugging");
- }
- else
- {
- int workers = Settings.NumberOfTestWorkers;
- if (workers >= 0)
- package.Settings[PackageSettings.NumberOfTestWorkers] = workers;
- }
+ if (Settings.PreFilter && testCases != null)
+ {
+ var prefilters = new List();
- if (Settings.PreFilter && testCases != null)
+ foreach (var testCase in testCases)
{
- var prefilters = new List();
-
- foreach (var testCase in testCases)
- {
- int end = testCase.FullyQualifiedName.IndexOfAny(new[] { '(', '<' });
- prefilters.Add(
- end > 0 ? testCase.FullyQualifiedName.Substring(0, end) : testCase.FullyQualifiedName);
- }
-
- package.Settings[PackageSettings.LOAD] = prefilters;
+ int end = testCase.FullyQualifiedName.IndexOfAny(new[] { '(', '<' });
+ prefilters.Add(
+ end > 0 ? testCase.FullyQualifiedName.Substring(0, end) : testCase.FullyQualifiedName);
}
- package.Settings[PackageSettings.SynchronousEvents] = Settings.SynchronousEvents;
+ package.Settings[PackageSettings.LOAD] = prefilters;
+ }
- int timeout = Settings.DefaultTimeout;
- if (timeout > 0)
- package.Settings[PackageSettings.DefaultTimeout] = timeout;
+ package.Settings[PackageSettings.SynchronousEvents] = Settings.SynchronousEvents;
- package.Settings[PackageSettings.InternalTraceLevel] = Settings.InternalTraceLevelEnum.ToString();
+ int timeout = Settings.DefaultTimeout;
+ if (timeout > 0)
+ package.Settings[PackageSettings.DefaultTimeout] = timeout;
- if (Settings.BasePath != null)
- package.Settings[PackageSettings.BasePath] = Settings.BasePath;
+ package.Settings[PackageSettings.InternalTraceLevel] = Settings.InternalTraceLevelEnum.ToString();
- if (Settings.PrivateBinPath != null)
- package.Settings[PackageSettings.PrivateBinPath] = Settings.PrivateBinPath;
+ if (Settings.BasePath != null)
+ package.Settings[PackageSettings.BasePath] = Settings.BasePath;
- if (Settings.RandomSeed.HasValue)
- package.Settings[PackageSettings.RandomSeed] = Settings.RandomSeed;
+ if (Settings.PrivateBinPath != null)
+ package.Settings[PackageSettings.PrivateBinPath] = Settings.PrivateBinPath;
- if (Settings.TestProperties.Count > 0)
- SetTestParameters(package.Settings, Settings.TestProperties);
+ if (Settings.RandomSeed.HasValue)
+ package.Settings[PackageSettings.RandomSeed] = Settings.RandomSeed;
- if (Settings.StopOnError)
- package.Settings[PackageSettings.StopOnError] = true;
+ if (Settings.TestProperties.Count > 0)
+ SetTestParameters(package.Settings, Settings.TestProperties);
- if (Settings.SkipNonTestAssemblies)
- package.Settings[PackageSettings.SkipNonTestAssemblies] = true;
+ if (Settings.StopOnError)
+ package.Settings[PackageSettings.StopOnError] = true;
- // Always run one assembly at a time in process in its own domain
- package.Settings[PackageSettings.ProcessModel] = "InProcess";
+ if (Settings.SkipNonTestAssemblies)
+ package.Settings[PackageSettings.SkipNonTestAssemblies] = true;
- package.Settings[PackageSettings.DomainUsage] = Settings.DomainUsage ?? "Single";
+ // Always run one assembly at a time in process in its own domain
+ package.Settings[PackageSettings.ProcessModel] = "InProcess";
- if (Settings.DefaultTestNamePattern != null)
- {
- package.Settings[PackageSettings.DefaultTestNamePattern] = Settings.DefaultTestNamePattern;
- }
- else
- {
- // Force truncation of string arguments to test cases
- package.Settings[PackageSettings.DefaultTestNamePattern] = "{m}{a}";
- }
+ package.Settings[PackageSettings.DomainUsage] = Settings.DomainUsage ?? "Single";
- return SetWorkDir(assemblyName, package);
+ if (Settings.DefaultTestNamePattern != null)
+ {
+ package.Settings[PackageSettings.DefaultTestNamePattern] = Settings.DefaultTestNamePattern;
}
-
- private TestPackage SetWorkDir(string assemblyName, TestPackage package)
+ else
{
- // Set the work directory to the assembly location unless a setting is provided
- string workDir = Settings.WorkDirectory;
- if (workDir == null)
- workDir = Path.GetDirectoryName(assemblyName);
- else if (!Path.IsPathRooted(workDir))
- workDir = Path.Combine(Path.GetDirectoryName(assemblyName), workDir);
- if (!Directory.Exists(workDir))
- Directory.CreateDirectory(workDir);
- package.Settings[PackageSettings.WorkDirectory] = workDir;
- WorkDir = workDir;
- Directory.SetCurrentDirectory(workDir);
- TestLog.Debug($"Workdir set to: {WorkDir}");
- return package;
+ // Force truncation of string arguments to test cases
+ package.Settings[PackageSettings.DefaultTestNamePattern] = "{m}{a}";
}
- ///
- /// Sets test parameters, handling backwards compatibility.
- ///
- private static void SetTestParameters(
- IDictionary runSettings,
- IDictionary testParameters)
- {
- runSettings[PackageSettings.TestParametersDictionary] = testParameters;
+ return SetWorkDir(assemblyName, package);
+ }
- if (testParameters.Count == 0)
- return;
- // Kept for backwards compatibility with old frameworks.
- // Reserializes the way old frameworks understand, even if the parsing above is changed.
- // This reserialization cannot be changed without breaking compatibility with old frameworks.
+ private TestPackage SetWorkDir(string assemblyName, TestPackage package)
+ {
+ // Set the work directory to the assembly location unless a setting is provided
+ string workDir = Settings.WorkDirectory;
+ if (workDir == null)
+ workDir = Path.GetDirectoryName(assemblyName);
+ else if (!Path.IsPathRooted(workDir))
+ workDir = Path.Combine(Path.GetDirectoryName(assemblyName), workDir);
+ if (!Directory.Exists(workDir))
+ Directory.CreateDirectory(workDir);
+ package.Settings[PackageSettings.WorkDirectory] = workDir;
+ WorkDir = workDir;
+ Directory.SetCurrentDirectory(workDir);
+ TestLog.Debug($"Workdir set to: {WorkDir}");
+ return package;
+ }
- var oldFrameworkSerializedParameters = new StringBuilder();
- foreach (var parameter in testParameters)
- oldFrameworkSerializedParameters.Append(parameter.Key).Append('=').Append(parameter.Value).Append(';');
+ ///
+ /// Sets test parameters, handling backwards compatibility.
+ ///
+ private static void SetTestParameters(
+ IDictionary runSettings,
+ IDictionary testParameters)
+ {
+ runSettings[PackageSettings.TestParametersDictionary] = testParameters;
- runSettings[PackageSettings.TestParameters] =
- oldFrameworkSerializedParameters.ToString(0, oldFrameworkSerializedParameters.Length - 1);
- }
+ if (testParameters.Count == 0)
+ return;
+ // Kept for backwards compatibility with old frameworks.
+ // Reserializes the way old frameworks understand, even if the parsing above is changed.
+ // This reserialization cannot be changed without breaking compatibility with old frameworks.
- ///
- /// Ensure any channels registered by other adapters are unregistered.
- ///
- protected static void CleanUpRegisteredChannels()
- {
+ var oldFrameworkSerializedParameters = new StringBuilder();
+ foreach (var parameter in testParameters)
+ oldFrameworkSerializedParameters.Append(parameter.Key).Append('=').Append(parameter.Value).Append(';');
+
+ runSettings[PackageSettings.TestParameters] =
+ oldFrameworkSerializedParameters.ToString(0, oldFrameworkSerializedParameters.Length - 1);
+ }
+
+ ///
+ /// Ensure any channels registered by other adapters are unregistered.
+ ///
+ protected static void CleanUpRegisteredChannels()
+ {
#if NET462
- foreach (var chan in ChannelServices.RegisteredChannels)
- ChannelServices.UnregisterChannel(chan);
+ foreach (var chan in ChannelServices.RegisteredChannels)
+ ChannelServices.UnregisterChannel(chan);
#endif
- }
-
- protected void Unload()
- {
- if (NUnitEngineAdapter == null)
- return;
- NUnitEngineAdapter.Dispose();
- NUnitEngineAdapter = null;
- }
+ }
- #endregion
+ protected void Unload()
+ {
+ if (NUnitEngineAdapter == null)
+ return;
+ NUnitEngineAdapter.Dispose();
+ NUnitEngineAdapter = null;
}
+
+ #endregion
}
\ No newline at end of file
diff --git a/src/NUnitTestAdapter/NUnitTestFilterBuilder.cs b/src/NUnitTestAdapter/NUnitTestFilterBuilder.cs
index 38c1c855..0cca18e5 100644
--- a/src/NUnitTestAdapter/NUnitTestFilterBuilder.cs
+++ b/src/NUnitTestAdapter/NUnitTestFilterBuilder.cs
@@ -28,93 +28,85 @@
using NUnit.VisualStudio.TestAdapter.NUnitEngine;
using NUnit.VisualStudio.TestAdapter.TestFilterConverter;
-namespace NUnit.VisualStudio.TestAdapter
+namespace NUnit.VisualStudio.TestAdapter;
+
+public class NUnitTestFilterBuilder(ITestFilterService filterService, IAdapterSettings settings)
{
- public class NUnitTestFilterBuilder
- {
- private readonly ITestFilterService _filterService;
+ private readonly ITestFilterService _filterService = filterService ?? throw new NUnitEngineException("TestFilterService is not available. Engine in use is incorrect version.");
- // ReSharper disable once StringLiteralTypo
- public static readonly TestFilter NoTestsFound = new ("");
- private readonly IAdapterSettings settings;
+ // ReSharper disable once StringLiteralTypo
+ public static readonly TestFilter NoTestsFound = new ("");
- public NUnitTestFilterBuilder(ITestFilterService filterService, IAdapterSettings settings)
- {
- this.settings = settings;
- _filterService = filterService ?? throw new NUnitEngineException("TestFilterService is not available. Engine in use is incorrect version.");
- }
+ public TestFilter ConvertTfsFilterToNUnitFilter(IVsTestFilter vsFilter, IList loadedTestCases)
+ {
+ var filteredTestCases = vsFilter.CheckFilter(loadedTestCases);
+ var testCases = filteredTestCases as TestCase[] ?? filteredTestCases.ToArray();
+ // TestLog.Info(string.Format("TFS Filter detected: LoadedTestCases {0}, Filtered Test Cases {1}", loadedTestCases.Count, testCases.Count()));
+ return testCases.Any() ? FilterByList(testCases) : NoTestsFound;
+ }
- public TestFilter ConvertTfsFilterToNUnitFilter(IVsTestFilter vsFilter, IList loadedTestCases)
- {
- var filteredTestCases = vsFilter.CheckFilter(loadedTestCases);
- var testCases = filteredTestCases as TestCase[] ?? filteredTestCases.ToArray();
- // TestLog.Info(string.Format("TFS Filter detected: LoadedTestCases {0}, Filtered Test Cases {1}", loadedTestCases.Count, testCases.Count()));
- return testCases.Any() ? FilterByList(testCases) : NoTestsFound;
- }
+ public TestFilter ConvertVsTestFilterToNUnitFilter(IVsTestFilter vsFilter, IDiscoveryConverter discovery)
+ {
+ if (settings.DiscoveryMethod == DiscoveryMethod.Legacy)
+ return ConvertTfsFilterToNUnitFilter(vsFilter, discovery.LoadedTestCases);
+ if (!settings.UseNUnitFilter)
+ return ConvertTfsFilterToNUnitFilter(vsFilter, discovery);
+ var result = ConvertVsTestFilterToNUnitFilter(vsFilter);
+ return result ?? ConvertTfsFilterToNUnitFilter(vsFilter, discovery);
+ }
- public TestFilter ConvertVsTestFilterToNUnitFilter(IVsTestFilter vsFilter, IDiscoveryConverter discovery)
- {
- if (settings.DiscoveryMethod == DiscoveryMethod.Legacy)
- return ConvertTfsFilterToNUnitFilter(vsFilter, discovery.LoadedTestCases);
- if (!settings.UseNUnitFilter)
- return ConvertTfsFilterToNUnitFilter(vsFilter, discovery);
- var result = ConvertVsTestFilterToNUnitFilter(vsFilter);
- return result ?? ConvertTfsFilterToNUnitFilter(vsFilter, discovery);
- }
+ ///