void Fail(Case @case, ExecutionSummary summary) { var message = new CaseFailed(@case); summary.Add(message); bus.Publish(message); }
internal ExecutionSummary Run(IReadOnlyList <Type> candidateTypes, Discovery discovery, Execution execution) { bus.Publish(new AssemblyStarted(assembly)); var assemblySummary = new ExecutionSummary(); var stopwatch = Stopwatch.StartNew(); var classDiscoverer = new ClassDiscoverer(discovery); var classRunner = new ClassRunner(bus, discovery, execution); var testClasses = classDiscoverer.TestClasses(candidateTypes); bool isOnlyTestClass = testClasses.Count == 1; foreach (var testClass in testClasses) { var classSummary = classRunner.Run(testClass, isOnlyTestClass); assemblySummary.Add(classSummary); } stopwatch.Stop(); bus.Publish(new AssemblyCompleted(assembly, assemblySummary, stopwatch.Elapsed)); return(assemblySummary); }
void Fail(MethodInfo method, Exception exception, ExecutionSummary summary) { var @case = new Case(method); @case.Fail(exception); Fail(@case, summary); }
void Pass(Case @case, ExecutionSummary summary) { var message = new CasePassed(@case); summary.Add(message); bus.Publish(message); }
void Skip(Case @case, ExecutionSummary summary) { var message = new CaseSkipped(@case); summary.Add(message); bus.Publish(message); }
IEnumerable <Case> YieldCases(IReadOnlyList <MethodInfo> orderedMethods, ExecutionSummary summary) { foreach (var method in orderedMethods) { if (method.GetParameters().Length == 0) { yield return(new Case(method)); continue; } bool generatedInputParameters = false; bool parameterGenerationThrew = false; using (var resource = Parameters(method).GetEnumerator()) { while (true) { object[] parameters; try { if (!resource.MoveNext()) { break; } parameters = resource.Current; } catch (Exception exception) { parameterGenerationThrew = true; Fail(method, exception, summary); break; } generatedInputParameters = true; yield return(new Case(method, parameters)); } } if (parameterGenerationThrew || generatedInputParameters) { continue; } try { throw new Exception("This test case has declared parameters, but no parameter values have been provided to it."); } catch (Exception exception) { Fail(method, exception, summary); } } }
ExecutionSummary Run(Assembly assembly, Discovery discovery, Execution execution, Type[] candidateTypes) { bus.Publish(new AssemblyStarted(assembly)); var assemblySummary = new ExecutionSummary(); var stopwatch = Stopwatch.StartNew(); Run(discovery, execution, candidateTypes, assemblySummary); stopwatch.Stop(); bus.Publish(new AssemblyCompleted(assembly, assemblySummary, stopwatch.Elapsed)); return(assemblySummary); }
void Run(Discovery discovery, Execution execution, Type[] candidateTypes, ExecutionSummary assemblySummary) { var classDiscoverer = new ClassDiscoverer(discovery); var classRunner = new ClassRunner(bus, discovery, execution); var testClasses = classDiscoverer.TestClasses(candidateTypes); bool isOnlyTestClass = testClasses.Count == 1; foreach (var testClass in testClasses) { var classSummary = classRunner.Run(testClass, isOnlyTestClass); assemblySummary.Add(classSummary); } }
public ClassCompleted(Type @class, ExecutionSummary summary, TimeSpan duration) { Class = @class; Duration = duration; this.summary = summary; }
public ExecutionSummary Run(Type testClass, bool isOnlyTestClass) { var methods = methodDiscoverer.TestMethods(testClass); var summary = new ExecutionSummary(); if (!methods.Any()) { return(summary); } Start(testClass); var classStopwatch = Stopwatch.StartNew(); var orderedMethods = OrderedMethods(methods, summary); bool classLifecycleFailed = false; bool runCasesInvokedByLifecycle = false; try { Action <Action <Case> > runCases = caseLifecycle => { runCasesInvokedByLifecycle = true; foreach (var @case in YieldCases(orderedMethods, summary)) { Start(@case); Exception caseLifecycleException = null; string consoleOutput; using (var console = new RedirectedConsole()) { var caseStopwatch = Stopwatch.StartNew(); try { caseLifecycle(@case); } catch (Exception exception) { caseLifecycleException = exception; } caseStopwatch.Stop(); @case.Duration += caseStopwatch.Elapsed; consoleOutput = console.Output; @case.Output += consoleOutput; } Console.Write(consoleOutput); var caseHasNormalResult = @case.State == CaseState.Failed || @case.State == CaseState.Passed; var caseLifecycleFailed = caseLifecycleException != null; if (caseHasNormalResult) { if (@case.State == CaseState.Failed) { Fail(@case, summary); } else if (!caseLifecycleFailed) { Pass(@case, summary); } } if (caseLifecycleFailed) { Fail(new Case(@case, caseLifecycleException), summary); } else if (!caseHasNormalResult) { Skip(@case, summary); } } }; var runContext = isOnlyTestClass && methods.Count == 1 ? new TestClass(testClass, runCases, methods.Single()) : new TestClass(testClass, runCases); execution.Execute(runContext); } catch (Exception exception) { classLifecycleFailed = true; foreach (var method in orderedMethods) { Fail(method, exception, summary); } } if (!runCasesInvokedByLifecycle && !classLifecycleFailed) { //No cases ran, and we didn't already emit a general //failure for each method, so emit a general skip for //each method. foreach (var method in orderedMethods) { var @case = new Case(method); Skip(@case, summary); } } classStopwatch.Stop(); Complete(testClass, summary, classStopwatch.Elapsed); return(summary); }
void Complete(Type testClass, ExecutionSummary summary, TimeSpan duration) { bus.Publish(new ClassCompleted(testClass, summary, duration)); }
IReadOnlyList <MethodInfo> OrderedMethods(IReadOnlyList <MethodInfo> methods, ExecutionSummary summary) { try { return(orderMethods(methods)); } catch (Exception orderException) { foreach (var method in methods) { Fail(method, orderException, summary); } return(methods); } }
public AssemblyCompleted(Assembly assembly, ExecutionSummary summary, TimeSpan duration) { Assembly = assembly; Duration = duration; this.summary = summary; }