Skip to content

Commit 77d79aa

Browse files
committed
Added ability for the test runner to notify test about its result
1 parent 9059ff2 commit 77d79aa

File tree

1 file changed

+82
-18
lines changed

1 file changed

+82
-18
lines changed

src/xunit.execution/Sdk/Frameworks/XunitTestCase.cs

+82-18
Original file line numberDiff line numberDiff line change
@@ -421,8 +421,8 @@ protected async Task<decimal> RunTestWithArgumentsAsync(IMessageBus messageBus,
421421
List<BeforeAfterTestAttribute> beforeAfterAttributes,
422422
ExceptionAggregator parentAggregator,
423423
CancellationTokenSource cancellationTokenSource)
424-
{
425-
var executionTimeInSeconds = 0.0m;
424+
{
425+
var executionTime = new ExecutionTime();
426426
var aggregator = new ExceptionAggregator(parentAggregator);
427427
var output = String.Empty; // TODO: Add output facilities for v2
428428

@@ -438,7 +438,6 @@ protected async Task<decimal> RunTestWithArgumentsAsync(IMessageBus messageBus,
438438
else
439439
{
440440
var beforeAttributesRun = new Stack<BeforeAfterTestAttribute>();
441-
var executionTime = new ExecutionTime();
442441

443442
if (!aggregator.HasExceptions)
444443
await aggregator.RunAsync(async () =>
@@ -503,7 +502,7 @@ await aggregator.RunAsync(async () =>
503502

504503
await aggregator.RunAsync(async () =>
505504
{
506-
executionTime.MeassureStep(async () =>
505+
await executionTime.MeassureStepAsync(async () =>
507506
{
508507
var result = methodUnderTest.Invoke(testClass, Reflector.ConvertArguments(testMethodArguments, parameterTypes));
509508
var task = result as Task;
@@ -549,7 +548,11 @@ await aggregator.RunAsync(async () =>
549548

550549
try
551550
{
552-
executionTime.MeassureStep(disposable.Dispose);
551+
executionTime.MeassureStep(() =>
552+
{
553+
NotifyTestIfRequired(displayName, disposable, executionTime, aggregator, output);
554+
disposable.Dispose();
555+
});
553556
}
554557
finally
555558
{
@@ -562,21 +565,57 @@ await aggregator.RunAsync(async () =>
562565

563566
if (!cancellationTokenSource.IsCancellationRequested)
564567
{
565-
executionTimeInSeconds = (decimal)executionTime.Total.TotalSeconds;
566-
567-
var exception = aggregator.ToException();
568-
var testResult = exception == null ? (TestResultMessage)new TestPassed(this, displayName, executionTimeInSeconds, output)
569-
: new TestFailed(this, displayName, executionTimeInSeconds, output, exception);
568+
var testResult = DetermineCurrentTestResult(displayName, executionTime, aggregator, output);
570569
if (!messageBus.QueueMessage(testResult))
571570
cancellationTokenSource.Cancel();
572571
}
573572
}
574573
}
575574

576-
if (!messageBus.QueueMessage(new TestFinished(this, displayName, executionTimeInSeconds, output)))
575+
if (!messageBus.QueueMessage(new TestFinished(this, displayName, executionTime.TotalSeconds, output)))
577576
cancellationTokenSource.Cancel();
578577

579-
return executionTimeInSeconds;
578+
return executionTime.TotalSeconds;
579+
}
580+
581+
private void NotifyTestIfRequired(string displayName, object test, ExecutionTime executionTime,
582+
ExceptionAggregator aggregator, string output)
583+
{
584+
var iNeedToKnowTestResult = test as INeedToKnowTestResult;
585+
586+
if (iNeedToKnowTestResult != null)
587+
{
588+
var testResult = DetermineCurrentTestResult(displayName, executionTime, aggregator, output);
589+
590+
var testPassed = testResult as TestPassed;
591+
if (testPassed != null)
592+
{
593+
var iNeedToKnowTestSuccess = iNeedToKnowTestResult as INeedToKnowTestSuccess;
594+
if (iNeedToKnowTestSuccess != null)
595+
{
596+
iNeedToKnowTestSuccess.Handle(testPassed);
597+
}
598+
}
599+
600+
var testFailed = testResult as TestFailed;
601+
if (testFailed != null)
602+
{
603+
var iNeedToKnowTestFailure = iNeedToKnowTestResult as INeedToKnowTestFailure;
604+
if (iNeedToKnowTestFailure != null)
605+
{
606+
iNeedToKnowTestFailure.Handle(testFailed);
607+
}
608+
}
609+
}
610+
}
611+
612+
private TestResultMessage DetermineCurrentTestResult(string displayName, ExecutionTime executionTime,
613+
ExceptionAggregator aggregator, string output)
614+
{
615+
var exception = aggregator.ToException();
616+
var testResult = exception == null ? (TestResultMessage)new TestPassed(this, displayName, executionTime.TotalSeconds, output)
617+
: new TestFailed(this, displayName, executionTime.TotalSeconds, output, exception);
618+
return testResult;
580619
}
581620

582621
[SecuritySafeCritical]
@@ -585,18 +624,38 @@ static void SetSynchronizationContext(SynchronizationContext context)
585624
SynchronizationContext.SetSynchronizationContext(context);
586625
}
587626
}
588-
589-
/// <summary>
627+
628+
629+
public interface INeedToKnowTestSuccess : INeedToKnowTestResult
630+
{
631+
void Handle(TestPassed result);
632+
}
633+
634+
public interface INeedToKnowTestFailure : INeedToKnowTestResult
635+
{
636+
void Handle(TestFailed result);
637+
}
638+
639+
640+
public interface INeedToKnowTestResult
641+
{
642+
}
643+
644+
/// <summary>
590645
/// Meassurs execution time of a processes made out of set of steps
591646
/// </summary>
592647
public class ExecutionTime
593648
{
594649
private TimeSpan total;
595650

596-
/// <summary>
597-
/// Executes a step, meassures its execution time and adds it to the current value of the total execution time.
598-
/// </summary>
599-
/// <param name="step"></param>
651+
public async Task MeassureStepAsync(Func<Task> step)
652+
{
653+
var stopwatch = Stopwatch.StartNew();
654+
await step();
655+
stopwatch.Stop();
656+
total = total + stopwatch.Elapsed;
657+
}
658+
600659
public void MeassureStep(Action step)
601660
{
602661
var stopwatch = Stopwatch.StartNew();
@@ -609,5 +668,10 @@ public TimeSpan Total
609668
{
610669
get { return total; }
611670
}
671+
672+
public decimal TotalSeconds
673+
{
674+
get { return (decimal)total.TotalSeconds; }
675+
}
612676
}
613677
}

0 commit comments

Comments
 (0)