/// <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")})");
            }
        }
예제 #4
0
        /// <inheritdoc/>
        public bool OnMessage(_MessageSinkMessage message)
        {
            if (message is _MessageSinkMessage v3Message)
            {
                logger.LogImportantMessage(Encoding.UTF8.GetString(v3Message.ToJson()));
            }

            return(true);
        }
예제 #5
0
        /// <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);
        }
예제 #6
0
        /// <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']");
            }
        }
예제 #8
0
 protected virtual bool Visit(ITestProgressMessage message)
 {
     _logger.LogImportantMessage($"##teamcity[progressMessage '{_escape(message.Message)}' ]");
     return(true);
 }
예제 #9
0
        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)));
        }
예제 #11
0
        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")})");
            }
        }
예제 #13
0
        protected override bool Visit(IErrorMessage error)
        {
            logger.LogImportantMessage(error.ToJson());

            return(base.Visit(error));
        }
예제 #14
0
 /// <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));
 }
예제 #15
0
 /// <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);
 }