Skip to content

Commit 8c156dd

Browse files
authored
update skipped test handling to include skip reason (#3443)
1 parent 782d7cb commit 8c156dd

File tree

2 files changed

+65
-4
lines changed

2 files changed

+65
-4
lines changed

TUnit.Engine/Services/TestExecution/TestCoordinator.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -146,13 +146,10 @@ await RetryHelper.ExecuteWithRetry(test.Context, async () =>
146146
}
147147
catch (SkipTestException ex)
148148
{
149+
test.Context.SkipReason = ex.Message;
149150
await _stateManager.MarkSkippedAsync(test, ex.Message);
150151

151-
// Invoke skipped event receivers
152152
await _eventReceiverOrchestrator.InvokeTestSkippedEventReceiversAsync(test.Context, cancellationToken);
153-
154-
// Invoke test end event receivers for skipped tests
155-
await _eventReceiverOrchestrator.InvokeTestEndEventReceiversAsync(test.Context, cancellationToken);
156153
}
157154
catch (Exception ex)
158155
{

TUnit.TestProject/LastTestEventReceiverTests.cs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using TUnit.Core;
12
using TUnit.Core.Interfaces;
23

34
namespace TUnit.TestProject;
@@ -163,3 +164,66 @@ public ValueTask OnTestEnd(TestContext context)
163164
return default;
164165
}
165166
}
167+
168+
// Test for runtime skip using Skip.Test()
169+
public class RuntimeSkipEventReceiverTests
170+
{
171+
public static readonly List<string> Events = [];
172+
public static string? CapturedSkipReason = null;
173+
174+
[Before(Test)]
175+
public void ClearEvents()
176+
{
177+
Events.Clear();
178+
CapturedSkipReason = null;
179+
}
180+
181+
[Test]
182+
[RuntimeSkipEventReceiverAttribute]
183+
public void RuntimeSkippedTestWithCustomReason()
184+
{
185+
Skip.Test("Custom runtime skip reason");
186+
}
187+
188+
[After(Test)]
189+
public async Task VerifyRuntimeSkipEventFired(TestContext context)
190+
{
191+
// Give some time for async event receivers to complete
192+
await Task.Delay(100);
193+
194+
if (context.GetDisplayName().Contains("RuntimeSkippedTestWithCustomReason"))
195+
{
196+
// Verify skip reason is preserved
197+
await Assert.That(CapturedSkipReason).IsEqualTo("Custom runtime skip reason");
198+
199+
// Verify both skipped and end events are fired
200+
await Assert.That(Events).Contains("TestSkipped");
201+
await Assert.That(Events).Contains("TestEnd");
202+
203+
// Verify TestEnd is called exactly once (not twice)
204+
var testEndCount = Events.Count(e => e == "TestEnd");
205+
await Assert.That(testEndCount).IsEqualTo(1);
206+
}
207+
}
208+
}
209+
210+
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false)]
211+
public class RuntimeSkipEventReceiverAttribute : Attribute,
212+
ITestSkippedEventReceiver,
213+
ITestEndEventReceiver
214+
{
215+
public int Order => 0;
216+
217+
public ValueTask OnTestSkipped(TestContext context)
218+
{
219+
RuntimeSkipEventReceiverTests.Events.Add("TestSkipped");
220+
RuntimeSkipEventReceiverTests.CapturedSkipReason = context.SkipReason;
221+
return default;
222+
}
223+
224+
public ValueTask OnTestEnd(TestContext context)
225+
{
226+
RuntimeSkipEventReceiverTests.Events.Add("TestEnd");
227+
return default;
228+
}
229+
}

0 commit comments

Comments
 (0)