Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion TUnit.Engine/Scheduling/TestRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ private async ValueTask ExecuteTestInternalAsync(AbstractExecutableTest test, Ca
}
finally
{
test.EndTime = DateTimeOffset.UtcNow;
test.EndTime ??= DateTimeOffset.UtcNow;
}
}

Expand Down
1 change: 1 addition & 0 deletions TUnit.Engine/Services/TestExecution/RetryHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public static async Task ExecuteWithRetry(TestContext testContext, Func<Task> ac
testContext.Execution.Result = null;
testContext.TestStart = null;
testContext.Execution.TestEnd = null;
testContext.Timings.Clear();
continue;
}

Expand Down
1 change: 1 addition & 0 deletions TUnit.Engine/Services/TestExecution/TestCoordinator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ private async ValueTask ExecuteTestInternalAsync(AbstractExecutableTest test, Ca
test.Context.Execution.Result = null;
test.Context.TestStart = null;
test.Context.Execution.TestEnd = null;
test.Context.Timings.Clear();

TestContext.Current = test.Context;

Expand Down
4 changes: 2 additions & 2 deletions TUnit.Engine/Services/TestExecution/TestStateManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public void MarkCompleted(AbstractExecutableTest test)
};

test.State = test.Result.State;
test.EndTime = now;
test.EndTime ??= now;
}

public void MarkFailed(AbstractExecutableTest test, Exception exception)
Expand All @@ -45,7 +45,7 @@ public void MarkFailed(AbstractExecutableTest test, Exception exception)
else
{
test.State = TestState.Failed;
test.EndTime = DateTimeOffset.UtcNow;
test.EndTime ??= DateTimeOffset.UtcNow;
test.Result = new TestResult
{
State = TestState.Failed,
Expand Down
19 changes: 16 additions & 3 deletions TUnit.Engine/TestExecutor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using TUnit.Core.Exceptions;
using TUnit.Core.Interfaces;
using TUnit.Core.Services;
using TUnit.Engine.Helpers;
using TUnit.Engine.Services;

namespace TUnit.Engine;
Expand Down Expand Up @@ -123,15 +124,23 @@ await _eventReceiverOrchestrator.InvokeFirstTestInClassEventReceiversAsync(

executableTest.Context.RestoreExecutionContext();

await _hookExecutor.ExecuteBeforeTestHooksAsync(executableTest, cancellationToken).ConfigureAwait(false);
await Timings.Record("BeforeTest", executableTest.Context,
() => _hookExecutor.ExecuteBeforeTestHooksAsync(executableTest, cancellationToken)).ConfigureAwait(false);

// Late stage test start receivers run after instance-level hooks (default behavior)
await _eventReceiverOrchestrator.InvokeTestStartEventReceiversAsync(executableTest.Context, cancellationToken, EventReceiverStage.Late).ConfigureAwait(false);

executableTest.Context.RestoreExecutionContext();

// Timeout is now enforced at TestCoordinator level (wrapping entire lifecycle)
await ExecuteTestAsync(executableTest, cancellationToken).ConfigureAwait(false);
try
{
await ExecuteTestAsync(executableTest, cancellationToken).ConfigureAwait(false);
}
finally
{
executableTest.Context.Execution.TestEnd ??= DateTimeOffset.UtcNow;
}

executableTest.SetResult(TestState.Passed);
}
Expand All @@ -153,7 +162,11 @@ await _eventReceiverOrchestrator.InvokeFirstTestInClassEventReceiversAsync(
// Early stage test end receivers run before instance-level hooks
var earlyStageExceptions = await _eventReceiverOrchestrator.InvokeTestEndEventReceiversAsync(executableTest.Context, CancellationToken.None, EventReceiverStage.Early).ConfigureAwait(false);

var hookExceptions = await _hookExecutor.ExecuteAfterTestHooksAsync(executableTest, CancellationToken.None).ConfigureAwait(false);
IReadOnlyList<Exception> hookExceptions = [];
await Timings.Record("AfterTest", executableTest.Context, (Func<Task>)(async () =>
{
hookExceptions = await _hookExecutor.ExecuteAfterTestHooksAsync(executableTest, CancellationToken.None).ConfigureAwait(false);
})).ConfigureAwait(false);

// Late stage test end receivers run after instance-level hooks (default behavior)
var lateStageExceptions = await _eventReceiverOrchestrator.InvokeTestEndEventReceiversAsync(executableTest.Context, CancellationToken.None, EventReceiverStage.Late).ConfigureAwait(false);
Expand Down
Loading