diff --git a/TUnit.Core/TestContext.cs b/TUnit.Core/TestContext.cs index bbba3b183a..c4df246afc 100644 --- a/TUnit.Core/TestContext.cs +++ b/TUnit.Core/TestContext.cs @@ -17,6 +17,7 @@ namespace TUnit.Core; [DebuggerDisplay("{TestDetails.ClassType.Name}.{GetDisplayName(),nq}")] public class TestContext : Context { + private static readonly Dictionary _testContextsById = new(1000); private readonly TestBuilderContext _testBuilderContext; private string? _cachedDisplayName; @@ -27,8 +28,12 @@ public TestContext(string testName, IServiceProvider serviceProvider, ClassHookC CancellationToken = cancellationToken; ServiceProvider = serviceProvider; ClassContext = classContext; + + _testContextsById[_testBuilderContext.Id] = this; } + public Guid Id => _testBuilderContext.Id; + private static readonly AsyncLocal TestContexts = new(); internal static readonly Dictionary> InternalParametersDictionary = new(); @@ -47,6 +52,8 @@ internal set } } + public static TestContext? GetById(Guid id) => _testContextsById.GetValueOrDefault(id); + public static IReadOnlyDictionary> Parameters => InternalParametersDictionary; public static IConfiguration Configuration { get; internal set; } = null!; @@ -96,21 +103,21 @@ public static string WorkingDirectory // New: Support multiple parallel constraints private readonly List _parallelConstraints = []; - + /// /// Gets the collection of parallel constraints applied to this test. /// Multiple constraints can be combined (e.g., ParallelGroup + NotInParallel). /// public IReadOnlyList ParallelConstraints => _parallelConstraints; - + /// /// Gets or sets the primary parallel constraint for backward compatibility. /// When setting, this replaces all existing constraints. /// When getting, returns the first constraint or null if none exist. /// [Obsolete("Use ParallelConstraints collection instead. This property is maintained for backward compatibility.")] - public IParallelConstraint? ParallelConstraint - { + public IParallelConstraint? ParallelConstraint + { get => _parallelConstraints.FirstOrDefault(); set { @@ -121,7 +128,7 @@ public IParallelConstraint? ParallelConstraint } } } - + /// /// Adds a parallel constraint to this test context. /// Multiple constraints can be combined to create complex parallelization rules. diff --git a/TUnit.PublicAPI/Tests.Core_Library_Has_No_API_Changes.DotNet8_0.verified.txt b/TUnit.PublicAPI/Tests.Core_Library_Has_No_API_Changes.DotNet8_0.verified.txt index 3426da1bdd..cb21dfb793 100644 --- a/TUnit.PublicAPI/Tests.Core_Library_Has_No_API_Changes.DotNet8_0.verified.txt +++ b/TUnit.PublicAPI/Tests.Core_Library_Has_No_API_Changes.DotNet8_0.verified.txt @@ -1234,6 +1234,7 @@ namespace public ? DisplayNameFormatter { get; set; } public .TestContextEvents Events { get; } public . ExecutionPriority { get; set; } + public Id { get; } public .CancellationTokenSource? LinkedCancellationTokens { get; set; } public object Lock { get; } public . ObjectBag { get; } @@ -1277,6 +1278,7 @@ namespace public void SetParallelLimiter(. parallelLimit) { } public void WriteError(string message) { } public void WriteLine(string message) { } + public static .TestContext? GetById( id) { } } public class TestContextEvents { diff --git a/TUnit.PublicAPI/Tests.Core_Library_Has_No_API_Changes.DotNet9_0.verified.txt b/TUnit.PublicAPI/Tests.Core_Library_Has_No_API_Changes.DotNet9_0.verified.txt index ecc1c7250d..eb19a61c58 100644 --- a/TUnit.PublicAPI/Tests.Core_Library_Has_No_API_Changes.DotNet9_0.verified.txt +++ b/TUnit.PublicAPI/Tests.Core_Library_Has_No_API_Changes.DotNet9_0.verified.txt @@ -1234,6 +1234,7 @@ namespace public ? DisplayNameFormatter { get; set; } public .TestContextEvents Events { get; } public . ExecutionPriority { get; set; } + public Id { get; } public .CancellationTokenSource? LinkedCancellationTokens { get; set; } public object Lock { get; } public . ObjectBag { get; } @@ -1277,6 +1278,7 @@ namespace public void SetParallelLimiter(. parallelLimit) { } public void WriteError(string message) { } public void WriteLine(string message) { } + public static .TestContext? GetById( id) { } } public class TestContextEvents { diff --git a/TUnit.PublicAPI/Tests.Core_Library_Has_No_API_Changes.Net4_7.verified.txt b/TUnit.PublicAPI/Tests.Core_Library_Has_No_API_Changes.Net4_7.verified.txt index ff5dcf7e9b..1fc1c8f869 100644 --- a/TUnit.PublicAPI/Tests.Core_Library_Has_No_API_Changes.Net4_7.verified.txt +++ b/TUnit.PublicAPI/Tests.Core_Library_Has_No_API_Changes.Net4_7.verified.txt @@ -1160,6 +1160,7 @@ namespace public ? DisplayNameFormatter { get; set; } public .TestContextEvents Events { get; } public . ExecutionPriority { get; set; } + public Id { get; } public .CancellationTokenSource? LinkedCancellationTokens { get; set; } public object Lock { get; } public . ObjectBag { get; } @@ -1202,6 +1203,7 @@ namespace public void SetParallelLimiter(. parallelLimit) { } public void WriteError(string message) { } public void WriteLine(string message) { } + public static .TestContext? GetById( id) { } } public class TestContextEvents { diff --git a/TUnit.TestProject/TestContextTests.cs b/TUnit.TestProject/TestContextTests.cs new file mode 100644 index 0000000000..28de2481a5 --- /dev/null +++ b/TUnit.TestProject/TestContextTests.cs @@ -0,0 +1,17 @@ +using TUnit.TestProject.Attributes; + +namespace TUnit.TestProject; + +[EngineTest(ExpectedResult.Pass)] +public class TestContextTests +{ + [Test] + public async Task Test() + { + var id = TestContext.Current!.Id; + + var context = TestContext.GetById(id); + + await Assert.That(context).IsNotNull(); + } +}