/// <inheritdoc /> protected override void Initialize() { writer = new ServiceMessageWriter(output => Logger.Log(LogSeverity.Important, output)); Events.InitializeStarted += delegate(object sender, InitializeStartedEventArgs e) { writer.WriteProgressMessage(flowId, "Initializing test runner."); }; Events.ExploreStarted += delegate(object sender, ExploreStartedEventArgs e) { writer.WriteProgressStart(flowId, "Exploring tests."); }; Events.ExploreFinished += delegate(object sender, ExploreFinishedEventArgs e) { writer.WriteProgressFinish(flowId, "Exploring tests."); // nb: message must be same as specified in progress start }; Events.RunStarted += delegate(object sender, RunStartedEventArgs e) { writer.WriteProgressStart(flowId, "Running tests."); }; Events.RunFinished += delegate(object sender, RunFinishedEventArgs e) { ClearStep(); writer.WriteProgressFinish(flowId, "Running tests."); // nb: message must be same as specified in progress start }; Events.DisposeFinished += delegate(object sender, DisposeFinishedEventArgs e) { writer.WriteProgressMessage(flowId, "Disposed test runner."); }; Events.TestStepStarted += delegate(object sender, TestStepStartedEventArgs e) { TestStepData step = e.TestStepRun.Step; BeginStep(step, () => { string name = step.Name; if (step.FullName.Length != 0 && name.Length != 0) { if (step.IsTestCase) { writer.WriteTestStarted(flowId, name, false); } else if (step.IsPrimary) { writer.WriteTestSuiteStarted(flowId, name); } } }); }; Events.TestStepFinished += delegate(object sender, TestStepFinishedEventArgs e) { TestStepRun stepRun = e.TestStepRun; TestStepData step = e.TestStepRun.Step; EndStep(step, () => { string name = step.Name; if (step.FullName.Length != 0 && name.Length != 0) { if (step.IsTestCase) { TestOutcome outcome = stepRun.Result.Outcome; var outputText = new StringBuilder(); var errorText = new StringBuilder(); var warningText = new StringBuilder(); var failureText = new StringBuilder(); foreach (StructuredStream stream in stepRun.TestLog.Streams) { switch (stream.Name) { default: case MarkupStreamNames.ConsoleInput: case MarkupStreamNames.ConsoleOutput: case MarkupStreamNames.DebugTrace: case MarkupStreamNames.Default: AppendWithSeparator(outputText, stream.ToString()); break; case MarkupStreamNames.ConsoleError: AppendWithSeparator(errorText, stream.ToString()); break; case MarkupStreamNames.Failures: AppendWithSeparator(failureText, stream.ToString()); break; case MarkupStreamNames.Warnings: AppendWithSeparator(warningText, stream.ToString()); break; } } if (outcome.Status != TestStatus.Skipped && warningText.Length != 0) AppendWithSeparator(errorText, warningText.ToString()); if (outcome.Status != TestStatus.Failed && failureText.Length != 0) AppendWithSeparator(errorText, failureText.ToString()); if (outputText.Length != 0) writer.WriteTestStdOut(flowId, name, outputText.ToString()); if (errorText.Length != 0) writer.WriteTestStdErr(flowId, name, errorText.ToString()); // TODO: Handle inconclusive. if (outcome.Status == TestStatus.Failed) { writer.WriteTestFailed(flowId, name, outcome.ToString(), failureText.ToString()); } else if (outcome.Status == TestStatus.Skipped) { writer.WriteTestIgnored(flowId, name, warningText.ToString()); } writer.WriteTestFinished(flowId, name, stepRun.Result.Duration); } else if (step.IsPrimary) { writer.WriteTestSuiteFinished(flowId, name); } } }); }; }