/// <summary> /// Executes the test case, returning 0 or more result messages through the message sink. /// </summary> /// <param name="messageSink">The message sink to report results to.</param> /// <param name="constructorArguments">The arguments to pass to the constructor.</param> /// <param name="aggregator">The error aggregator to use for catching exception.</param> /// <param name="cancellationTokenSource">The cancellation token source that indicates whether cancellation has been requested.</param> public virtual void Run(IMessageSink messageSink, object[] constructorArguments, ExceptionAggregator aggregator, CancellationTokenSource cancellationTokenSource) { int totalFailed = 0; int totalRun = 0; int totalSkipped = 0; decimal executionTime = 0M; if (!messageSink.OnMessage(new TestCaseStarting(this))) cancellationTokenSource.Cancel(); else { var delegatingSink = new DelegatingMessageSink(messageSink, msg => { if (msg is ITestResultMessage) { totalRun++; executionTime += ((ITestResultMessage)msg).ExecutionTime; } if (msg is ITestFailed) totalFailed++; if (msg is ITestSkipped) totalSkipped++; }); RunTests(delegatingSink, constructorArguments, aggregator, cancellationTokenSource); } if (!messageSink.OnMessage(new TestCaseFinished(this, executionTime, totalRun, totalFailed, totalSkipped))) cancellationTokenSource.Cancel(); }
private static bool RunTestMethod(IMessageSink messageSink, object[] constructorArguments, IEnumerable<XunitTestCase> testCases, RunSummary classSummary, ExceptionAggregator aggregator) { bool cancelled = false; foreach (XunitTestCase testCase in testCases) { var delegatingSink = new DelegatingMessageSink<ITestCaseFinished>(messageSink); // REVIEW: testCase.Run() returning bool implies synchronous behavior, which will probably // not be true once we start supporting parallelization. This could be achieved by always // using a delegating sink (like above) and watching for cancellation there, then checking // for the cancellation result in the delegating sink after work is finished. cancelled = testCase.Run(delegatingSink, constructorArguments, aggregator); delegatingSink.Finished.WaitOne(); classSummary.Total += delegatingSink.FinalMessage.TestsRun; classSummary.Failed += delegatingSink.FinalMessage.TestsFailed; classSummary.Skipped += delegatingSink.FinalMessage.TestsSkipped; classSummary.Time += delegatingSink.FinalMessage.ExecutionTime; if (cancelled) break; } return cancelled; }
private static void RunTestMethod(IMessageSink messageSink, object[] constructorArguments, IEnumerable<XunitTestCase> testCases, RunSummary classSummary, ExceptionAggregator aggregator, CancellationTokenSource cancellationTokenSource) { foreach (XunitTestCase testCase in testCases) { var delegatingSink = new DelegatingMessageSink<ITestCaseFinished>(messageSink); testCase.Run(delegatingSink, constructorArguments, aggregator, cancellationTokenSource); delegatingSink.Finished.WaitOne(); classSummary.Total += delegatingSink.FinalMessage.TestsRun; classSummary.Failed += delegatingSink.FinalMessage.TestsFailed; classSummary.Skipped += delegatingSink.FinalMessage.TestsSkipped; classSummary.Time += delegatingSink.FinalMessage.ExecutionTime; if (cancellationTokenSource.IsCancellationRequested) break; } }
/// <summary> /// Executes the test case, returning 0 or more result messages through the message sink. /// </summary> /// <param name="messageSink">The message sink to report results to.</param> /// <param name="constructorArguments">The arguments to pass to the constructor.</param> /// <param name="aggregator">The error aggregator to use for catching exception.</param> /// <returns>Returns <c>true</c> if the tests should continue to run; <c>false</c> otherwise.</returns> // REVIEW: Returning bool from this method may be bad design, as it dictates a synchronous execution pattern. public virtual bool Run(IMessageSink messageSink, object[] constructorArguments, ExceptionAggregator aggregator) { bool cancelled = false; int totalFailed = 0; int totalRun = 0; int totalSkipped = 0; decimal executionTime = 0M; if (!messageSink.OnMessage(new TestCaseStarting { TestCase = this })) cancelled = true; else { var delegatingSink = new DelegatingMessageSink(messageSink, msg => { if (msg is ITestResultMessage) { totalRun++; executionTime += ((ITestResultMessage)msg).ExecutionTime; } if (msg is ITestFailed) totalFailed++; if (msg is ITestSkipped) totalSkipped++; }); cancelled = RunTests(delegatingSink, constructorArguments, aggregator); } if (!messageSink.OnMessage(new TestCaseFinished { ExecutionTime = executionTime, TestCase = this, TestsRun = totalRun, TestsFailed = totalFailed, TestsSkipped = totalSkipped })) cancelled = true; return cancelled; }