public static async Task Invoke(this Func <Task> action, ExceptionAggregator aggregator, ExecutionTimer timer) { var oldSyncContext = SynchronizationContext.Current; try { var asyncSyncContext = new AsyncTestSyncContext(oldSyncContext); SetSynchronizationContext(asyncSyncContext); await aggregator?.RunAsync( () => timer.AggregateAsync( async() => { await action(); var ex = await asyncSyncContext.WaitForCompletionAsync(); if (ex != null) { aggregator.Add(ex); } })); } finally { SetSynchronizationContext(oldSyncContext); } }
/// <inheritdoc/> protected override async Task <RunSummary> RunTestAsync() { if (dataDiscoveryException != null) { return(RunTest_DataDiscoveryException()); } var runSummary = new RunSummary(); foreach (var testRunner in testRunners) { runSummary.Aggregate(await testRunner.RunAsync()); } // Run the cleanup here so we can include cleanup time in the run summary, // but save any exceptions so we can surface them during the cleanup phase, // so they get properly reported as test case cleanup failures. var timer = new ExecutionTimer(); foreach (var trackedObject in disposalTracker.TrackedObjects) { if (trackedObject is IAsyncDisposable asyncDisposable) { await timer.AggregateAsync(() => cleanupAggregator.RunAsync(asyncDisposable.DisposeAsync)); } if (trackedObject is IDisposable disposable) { timer.Aggregate(() => cleanupAggregator.Run(disposable.Dispose)); } } disposalTracker.Clear(); runSummary.Time += timer.Total; return(runSummary); }