/// <summary> /// Writes the default summary to the given logger. Can be used by other reporters who also wish to write the /// standard summary information. /// </summary> /// <param name="logger">The logger used to send result messages to.</param> /// <param name="executionSummary">The execution summary to display.</param> public static void WriteDefaultSummary(IRunnerLogger logger, ITestExecutionSummary executionSummary) { logger.LogImportantMessage("=== TEST EXECUTION SUMMARY ==="); var totalTestsRun = executionSummary.Summaries.Sum(summary => summary.Value.Total); var totalTestsFailed = executionSummary.Summaries.Sum(summary => summary.Value.Failed); var totalTestsSkipped = executionSummary.Summaries.Sum(summary => summary.Value.Skipped); var totalTime = executionSummary.Summaries.Sum(summary => summary.Value.Time).ToString("0.000s"); var totalErrors = executionSummary.Summaries.Sum(summary => summary.Value.Errors); var longestAssemblyName = executionSummary.Summaries.Max(summary => summary.Key.Length); var longestTotal = totalTestsRun.ToString().Length; var longestFailed = totalTestsFailed.ToString().Length; var longestSkipped = totalTestsSkipped.ToString().Length; var longestTime = totalTime.Length; var longestErrors = totalErrors.ToString().Length; foreach (var summary in executionSummary.Summaries) { if (summary.Value.Total == 0) { logger.LogImportantMessage($" {summary.Key.PadRight(longestAssemblyName)} Total: {"0".PadLeft(longestTotal)}"); } else { logger.LogImportantMessage($" {summary.Key.PadRight(longestAssemblyName)} Total: {summary.Value.Total.ToString().PadLeft(longestTotal)}, Errors: {summary.Value.Errors.ToString().PadLeft(longestErrors)}, Failed: {summary.Value.Failed.ToString().PadLeft(longestFailed)}, Skipped: {summary.Value.Skipped.ToString().PadLeft(longestSkipped)}, Time: {summary.Value.Time.ToString("0.000s").PadLeft(longestTime)}"); } } if (executionSummary.Summaries.Count > 1) { logger.LogImportantMessage($" {" ".PadRight(longestAssemblyName)} {"-".PadRight(longestTotal, '-')} {"-".PadRight(longestErrors, '-')} {"-".PadRight(longestFailed, '-')} {"-".PadRight(longestSkipped, '-')} {"-".PadRight(longestTime, '-')}"); logger.LogImportantMessage($" {"GRAND TOTAL:".PadLeft(longestAssemblyName + 8)} {totalTestsRun} {totalErrors} {totalTestsFailed} {totalTestsSkipped} {totalTime} ({executionSummary.ElapsedClockTime.TotalSeconds.ToString("0.000s")})"); } }
protected override bool Visit(ITestCollectionFinished testCollectionFinished) { logger.LogImportantMessage("##teamcity[testSuiteFinished name='{0}' flowId='{1}']", Escape(displayNameFormatter.DisplayName(testCollectionFinished.TestCollection)), ToFlowId(testCollectionFinished.TestCollection.DisplayName)); return(base.Visit(testCollectionFinished)); }
/// <summary> /// Writes the default summary to the given logger. Can be used by other reporters who also wish to write the /// standard summary information. /// </summary> /// <param name="logger">The logger used to send result messages to.</param> /// <param name="summaries">The execution summary to display.</param> public void WriteDefaultSummary(IRunnerLogger logger, TestExecutionSummaries summaries) { Guard.ArgumentNotNull(nameof(logger), logger); Guard.ArgumentNotNull(nameof(summaries), summaries); logger.LogImportantMessage("=== TEST EXECUTION SUMMARY ==="); var assemblyDisplayNames = summaries .SummariesByAssemblyUniqueID .ToDictionary( kvp => kvp.AssemblyUniqueID, kvp => Path.GetFileNameWithoutExtension(MetadataCache.TryGetAssemblyMetadata(kvp.AssemblyUniqueID)?.AssemblyPath) ?? "<unknown assembly>" ); var totalTestsRun = summaries.SummariesByAssemblyUniqueID.Sum(summary => summary.Summary.Total); var totalTestsFailed = summaries.SummariesByAssemblyUniqueID.Sum(summary => summary.Summary.Failed); var totalTestsSkipped = summaries.SummariesByAssemblyUniqueID.Sum(summary => summary.Summary.Skipped); var totalTime = summaries.SummariesByAssemblyUniqueID.Sum(summary => summary.Summary.Time).ToString("0.000s"); var totalErrors = summaries.SummariesByAssemblyUniqueID.Sum(summary => summary.Summary.Errors); var longestAssemblyName = assemblyDisplayNames.Max(summary => summary.Value.Length); var longestTotal = totalTestsRun.ToString().Length; var longestFailed = totalTestsFailed.ToString().Length; var longestSkipped = totalTestsSkipped.ToString().Length; var longestTime = totalTime.Length; var longestErrors = totalErrors.ToString().Length; foreach (var summary in summaries.SummariesByAssemblyUniqueID) { var assemblyDisplayName = assemblyDisplayNames[summary.AssemblyUniqueID]; if (summary.Summary.Total == 0) { logger.LogImportantMessage($" {assemblyDisplayName.PadRight(longestAssemblyName)} Total: {"0".PadLeft(longestTotal)}"); } else { logger.LogImportantMessage($" {assemblyDisplayName.PadRight(longestAssemblyName)} Total: {summary.Summary.Total.ToString().PadLeft(longestTotal)}, Errors: {summary.Summary.Errors.ToString().PadLeft(longestErrors)}, Failed: {summary.Summary.Failed.ToString().PadLeft(longestFailed)}, Skipped: {summary.Summary.Skipped.ToString().PadLeft(longestSkipped)}, Time: {summary.Summary.Time.ToString("0.000s").PadLeft(longestTime)}"); } } if (summaries.SummariesByAssemblyUniqueID.Count > 1) { logger.LogImportantMessage($" {" ".PadRight(longestAssemblyName)} {"-".PadRight(longestTotal, '-')} {"-".PadRight(longestErrors, '-')} {"-".PadRight(longestFailed, '-')} {"-".PadRight(longestSkipped, '-')} {"-".PadRight(longestTime, '-')}"); logger.LogImportantMessage($" {"GRAND TOTAL:".PadLeft(longestAssemblyName + 8)} {totalTestsRun} {totalErrors} {totalTestsFailed} {totalTestsSkipped} {totalTime} ({summaries.ElapsedClockTime.TotalSeconds.ToString("0.000s")})"); } }
/// <inheritdoc/> public bool OnMessage(_MessageSinkMessage message) { if (message is _MessageSinkMessage v3Message) { logger.LogImportantMessage(Encoding.UTF8.GetString(v3Message.ToJson())); } return(true); }
/// <summary> /// Logs a high-priority message. /// </summary> /// <param name="logger">The logger</param> /// <param name="message">The message to be logged</param> public static void LogImportantMessage( this IRunnerLogger logger, string message) { Guard.ArgumentNotNull(logger); Guard.ArgumentNotNull(message); logger.LogImportantMessage(StackFrameInfo.None, message); }
/// <summary> /// Logs a high-priority formatted message. /// </summary> /// <param name="logger">The logger</param> /// <param name="messageFormat">The format of the message to be logged</param> /// <param name="args">The format arguments</param> public static void LogImportantMessage( this IRunnerLogger logger, string messageFormat, params object?[] args) { Guard.ArgumentNotNull(logger); Guard.ArgumentNotNull(messageFormat); logger.LogImportantMessage(StackFrameInfo.None, string.Format(messageFormat, args)); }
/// <summary> /// Handles instances of <see cref="_TestCollectionFinished" />. /// </summary> protected virtual void HandleTestCollectionFinished(MessageHandlerArgs <_TestCollectionFinished> args) { Guard.ArgumentNotNull(nameof(args), args); var testCollectionFinished = args.Message; var metadata = metadataCache.TryRemove(testCollectionFinished); if (metadata != null) { logger.LogImportantMessage($"##teamcity[testSuiteFinished name='{metadata.TestCollectionDisplayName} ({testCollectionFinished.TestCollectionUniqueID})' flowId='{testCollectionFinished.TestCollectionUniqueID}']"); } else { // TODO: Can we still report testSuiteFinished with an incorrect name, if the flow ID is correct? logger.LogImportantMessage($"##teamcity[message status='ERROR' text='Tried to report a completed test collection that was never reported as starting']"); } }
protected virtual bool Visit(ITestProgressMessage message) { _logger.LogImportantMessage($"##teamcity[progressMessage '{_escape(message.Message)}' ]"); return(true); }
public JsonReporterMessageHandler(IRunnerLogger logger, Func <string, string> flowIdMapper) { this.flowIdMapper = flowIdMapper; Diagnostics.ErrorMessageEvent += args => logger.LogImportantMessage(args.Message.ToJson()); Execution.TestAssemblyCleanupFailureEvent += args => logger.LogImportantMessage(args.Message.ToJson()); Execution.TestClassCleanupFailureEvent += args => logger.LogImportantMessage(args.Message.ToJson()); Execution.TestCaseCleanupFailureEvent += args => logger.LogImportantMessage(args.Message.ToJson()); Execution.TestCollectionCleanupFailureEvent += args => logger.LogImportantMessage(args.Message.ToJson()); Execution.TestCleanupFailureEvent += args => logger.LogImportantMessage(args.Message.ToJson()); Execution.TestMethodCleanupFailureEvent += args => logger.LogImportantMessage(args.Message.ToJson()); Execution.TestCollectionFinishedEvent += args => logger.LogImportantMessage(args.Message.ToJson(ToFlowId(args.Message.TestCollection.DisplayName))); Execution.TestCollectionStartingEvent += args => logger.LogImportantMessage(args.Message.ToJson(ToFlowId(args.Message.TestCollection.DisplayName))); Execution.TestFailedEvent += args => logger.LogImportantMessage(args.Message.ToJson(ToFlowId(args.Message.TestCollection.DisplayName))); Execution.TestPassedEvent += args => logger.LogImportantMessage(args.Message.ToJson(ToFlowId(args.Message.TestCollection.DisplayName))); Execution.TestSkippedEvent += args => logger.LogImportantMessage(args.Message.ToJson(ToFlowId(args.Message.TestCollection.DisplayName))); Execution.TestStartingEvent += args => logger.LogImportantMessage(args.Message.ToJson(ToFlowId(args.Message.TestCollection.DisplayName))); }
public JsonReporterMessageHandler(IRunnerLogger logger, Func<string, string> flowIdMapper) { this.flowIdMapper = flowIdMapper; Diagnostics.ErrorMessageEvent += args => logger.LogImportantMessage(args.Message.ToJson()); Execution.TestAssemblyCleanupFailureEvent += args => logger.LogImportantMessage(args.Message.ToJson()); Execution.TestClassCleanupFailureEvent += args => logger.LogImportantMessage(args.Message.ToJson()); Execution.TestCaseCleanupFailureEvent += args => logger.LogImportantMessage(args.Message.ToJson()); Execution.TestCollectionCleanupFailureEvent += args => logger.LogImportantMessage(args.Message.ToJson()); Execution.TestCleanupFailureEvent += args => logger.LogImportantMessage(args.Message.ToJson()); Execution.TestMethodCleanupFailureEvent += args => logger.LogImportantMessage(args.Message.ToJson()); Execution.TestCollectionFinishedEvent += args => logger.LogImportantMessage(args.Message.ToJson(ToFlowId(args.Message.TestCollection.DisplayName))); Execution.TestCollectionStartingEvent += args => logger.LogImportantMessage(args.Message.ToJson(ToFlowId(args.Message.TestCollection.DisplayName))); Execution.TestFailedEvent += args => logger.LogImportantMessage(args.Message.ToJson(ToFlowId(args.Message.TestCollection.DisplayName))); Execution.TestPassedEvent += args => logger.LogImportantMessage(args.Message.ToJson(ToFlowId(args.Message.TestCollection.DisplayName))); Execution.TestSkippedEvent += args => logger.LogImportantMessage(args.Message.ToJson(ToFlowId(args.Message.TestCollection.DisplayName))); Execution.TestStartingEvent += args => logger.LogImportantMessage(args.Message.ToJson(ToFlowId(args.Message.TestCollection.DisplayName))); }
protected virtual void HandleTestCollectionFinished(MessageHandlerArgs <ITestCollectionFinished> args) { var testCollectionFinished = args.Message; logger.LogImportantMessage($"##teamcity[testSuiteFinished name='{Escape(displayNameFormatter.DisplayName(testCollectionFinished.TestCollection))}' flowId='{ToFlowId(testCollectionFinished.TestCollection.DisplayName)}']"); }
/// <summary> /// Writes the default summary to the given logger. Can be used by other reporters who also wish to write the /// standard summary information. /// </summary> /// <param name="logger">The logger used to send result messages to.</param> /// <param name="executionSummary">The execution summary to display.</param> public static void WriteDefaultSummary(IRunnerLogger logger, ITestExecutionSummary executionSummary) { logger.LogImportantMessage("=== TEST EXECUTION SUMMARY ==="); var totalTestsRun = executionSummary.Summaries.Sum(summary => summary.Value.Total); var totalTestsFailed = executionSummary.Summaries.Sum(summary => summary.Value.Failed); var totalTestsSkipped = executionSummary.Summaries.Sum(summary => summary.Value.Skipped); var totalTime = executionSummary.Summaries.Sum(summary => summary.Value.Time).ToString("0.000s"); var totalErrors = executionSummary.Summaries.Sum(summary => summary.Value.Errors); var longestAssemblyName = executionSummary.Summaries.Max(summary => summary.Key.Length); var longestTotal = totalTestsRun.ToString().Length; var longestFailed = totalTestsFailed.ToString().Length; var longestSkipped = totalTestsSkipped.ToString().Length; var longestTime = totalTime.Length; var longestErrors = totalErrors.ToString().Length; foreach (var summary in executionSummary.Summaries) { if (summary.Value.Total == 0) logger.LogImportantMessage($" {summary.Key.PadRight(longestAssemblyName)} Total: {"0".PadLeft(longestTotal)}"); else logger.LogImportantMessage($" {summary.Key.PadRight(longestAssemblyName)} Total: {summary.Value.Total.ToString().PadLeft(longestTotal)}, Errors: {summary.Value.Errors.ToString().PadLeft(longestErrors)}, Failed: {summary.Value.Failed.ToString().PadLeft(longestFailed)}, Skipped: {summary.Value.Skipped.ToString().PadLeft(longestSkipped)}, Time: {summary.Value.Time.ToString("0.000s").PadLeft(longestTime)}"); } if (executionSummary.Summaries.Count > 1) { logger.LogImportantMessage($" {" ".PadRight(longestAssemblyName)} {"-".PadRight(longestTotal, '-')} {"-".PadRight(longestErrors, '-')} {"-".PadRight(longestFailed, '-')} {"-".PadRight(longestSkipped, '-')} {"-".PadRight(longestTime, '-')}"); logger.LogImportantMessage($" {"GRAND TOTAL:".PadLeft(longestAssemblyName + 8)} {totalTestsRun} {totalErrors} {totalTestsFailed} {totalTestsSkipped} {totalTime} ({executionSummary.ElapsedClockTime.TotalSeconds.ToString("0.000s")})"); } }
protected override bool Visit(IErrorMessage error) { logger.LogImportantMessage(error.ToJson()); return(base.Visit(error)); }
/// <summary> /// Logs a high-priority formatted message with stack frame. /// </summary> /// <param name="logger">The logger</param> /// <param name="stackFrame">The stack frame information</param> /// <param name="messageFormat">The format of the message to be logged</param> /// <param name="args">The format arguments</param> public static void LogImportantMessage(this IRunnerLogger logger, StackFrameInfo stackFrame, string messageFormat, params object[] args) { logger.LogImportantMessage(stackFrame, string.Format(messageFormat, args)); }
/// <summary> /// Logs a high-priority message. /// </summary> /// <param name="logger">The logger</param> /// <param name="message">The message to be logged</param> public static void LogImportantMessage(this IRunnerLogger logger, string message) { logger.LogImportantMessage(StackFrameInfo.None, message); }