Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Console output for minimal and quiet #2191

Merged
merged 33 commits into from Jul 22, 2020
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
795d3a8
added verbosity quiest
Sep 24, 2019
4da1046
removed source in printing
Sep 24, 2019
5bda2ee
added tests
Sep 26, 2019
103ee9e
added tests,changed private members of summary info to local members
Oct 3, 2019
afeda96
naming corrected
Oct 3, 2019
dbd9b7e
combined two for loops to one for loop
Oct 3, 2019
bfb5804
removed redundant code and fomatted
Oct 4, 2019
c952c42
modified resources
Oct 9, 2019
3391a72
added target framework in quiet case
Oct 21, 2019
ed14b11
added yellow colour to passed and skipped
Oct 23, 2019
3250de1
if cases formatted
Oct 24, 2019
d38829e
paased failed to localized
Oct 30, 2019
8ab3fa2
passed and failed in unit tests changed to localized
Oct 30, 2019
bf38a2e
summary added to verbosity minimal case also
Oct 30, 2019
c16c653
attachments added to minimal and quiet verbosity case
Nov 1, 2019
1b77242
Merge branch 'master' into ConsoleLoggerVerbosityQuietCase
singhsarab Nov 1, 2019
5075c6b
formatted
Nov 15, 2019
cae94bb
Merge branch 'ConsoleLoggerVerbosityQuietCase' of https://github.com/…
Nov 18, 2019
a742746
removed milliseconds unit when seconds unit is there
Nov 19, 2019
18c4022
Forward merge master
nohwnd Jan 8, 2020
a588684
Merge master again
nohwnd Jan 8, 2020
d22a535
Fix acceptance tests
nohwnd Jan 9, 2020
9ba8b23
Revert build changes
nohwnd Jan 9, 2020
6f3650a
Merge branch 'master' into ConsoleLoggerVerbosityQuietCase
nohwnd Apr 28, 2020
61859a5
Fix test
nohwnd May 28, 2020
75d50f2
Format output to align
nohwnd May 28, 2020
d36c66f
Fixing the output, not working adds new line
nohwnd May 28, 2020
b0ab8d4
Merge master
nohwnd Jul 13, 2020
8644107
check
nohwnd Jul 13, 2020
54aca6f
Minimal output
nohwnd Jul 13, 2020
6ad0add
Fix test
nohwnd Jul 13, 2020
c4a52e4
Write when aborting
nohwnd Jul 13, 2020
ea8b54b
Remove empty line
nohwnd Jul 13, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
99 changes: 71 additions & 28 deletions src/vstest.console/Internal/ConsoleLogger.cs
Expand Up @@ -4,6 +4,7 @@
namespace Microsoft.VisualStudio.TestPlatform.CommandLine.Internal
{
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
Expand All @@ -15,9 +16,8 @@ namespace Microsoft.VisualStudio.TestPlatform.CommandLine.Internal
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client;
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging;
using Microsoft.VisualStudio.TestPlatform.Utilities;

using NuGet.Frameworks;
using CommandLineResources = Resources.Resources;

/// <summary>
/// Logger for sending output to the console.
/// All the console logger messages prints to Standard Output with respective color, except OutputLevel.Error messages
Expand Down Expand Up @@ -107,12 +107,13 @@ internal enum Verbosity
private Verbosity verbosityLevel = Verbosity.Minimal;
#endif

private int testsTotal = 0;
private int testsPassed = 0;
private int testsFailed = 0;
private int testsSkipped = 0;
private bool testRunHasErrorMessages = false;

/// <summary>
/// Framework on which the test runs.
/// </summary>
private string targetFramework;

#endregion

#region Constructor
Expand Down Expand Up @@ -155,6 +156,11 @@ protected static IOutput Output
/// </summary>
public Verbosity VerbosityLevel => verbosityLevel;

/// <summary>
/// Source level summary of test result.
/// </summary>
private ConcurrentDictionary<string, SourceSummary> sourceSummaryDictionary { get; set; }

#endregion

#region ITestLoggerWithParameters
Expand Down Expand Up @@ -190,6 +196,7 @@ public void Initialize(TestLoggerEvents events, string testRunDirectory)

// Register for the discovery events.
events.DiscoveryMessage += this.TestMessageHandler;
this.sourceSummaryDictionary = new ConcurrentDictionary<string, SourceSummary>();

// TODO Get changes from https://github.com/Microsoft/vstest/pull/1111/
// events.DiscoveredTests += DiscoveredTestsHandler;
Expand Down Expand Up @@ -225,6 +232,9 @@ public void Initialize(TestLoggerEvents events, Dictionary<string, string> param
bool.TryParse(enableProgress, out EnableProgress);
}

parameters.TryGetValue(DefaultLoggerParameterNames.TargetFramework, out this.targetFramework);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TryGetValue [](start = 23, length = 11)

Why use TryGetValue when you are not using the bool ?

this.targetFramework = !string.IsNullOrEmpty(this.targetFramework) ? NuGetFramework.Parse(this.targetFramework).GetShortFolderName() : this.targetFramework;

Initialize(events, String.Empty);
}
#endregion
Expand Down Expand Up @@ -467,10 +477,16 @@ private void TestResultHandler(object sender, TestResultEventArgs e)
{
ValidateArg.NotNull<object>(sender, "sender");
ValidateArg.NotNull<TestResultEventArgs>(e, "e");
SourceSummary summary;
if (!this.sourceSummaryDictionary.TryGetValue(e.Result.TestCase.Source, out summary))
{
summary = new SourceSummary();
this.sourceSummaryDictionary.TryAdd(e.Result.TestCase.Source, summary);
}

// Update the test count statistics based on the result of the test.
this.testsTotal++;

summary.TotalTests++;
summary.Duration += e.Result.Duration;
var testDisplayName = e.Result.DisplayName;

if (string.IsNullOrWhiteSpace(e.Result.DisplayName))
Expand All @@ -488,7 +504,7 @@ private void TestResultHandler(object sender, TestResultEventArgs e)
{
case TestOutcome.Skipped:
{
this.testsSkipped++;
summary.SkippedTests++;
if (this.verbosityLevel == Verbosity.Quiet)
{
break;
Expand All @@ -512,7 +528,7 @@ private void TestResultHandler(object sender, TestResultEventArgs e)

case TestOutcome.Failed:
{
this.testsFailed++;
summary.FailedTests++;
if (this.verbosityLevel == Verbosity.Quiet)
{
break;
Expand All @@ -533,7 +549,7 @@ private void TestResultHandler(object sender, TestResultEventArgs e)

case TestOutcome.Passed:
{
this.testsPassed++;
summary.PassedTests++;
if (this.verbosityLevel == Verbosity.Normal || this.verbosityLevel == Verbosity.Detailed)
{
// Pause the progress indicator before displaying test result information
Expand Down Expand Up @@ -588,28 +604,28 @@ private string GetFormattedDurationString(TimeSpan duration)
var time = new List<string>();
if (duration.Hours > 0)
{
time.Add(duration.Hours + "h");
time.Add(duration.Hours + " h");
}

if (duration.Minutes > 0)
{
time.Add(duration.Minutes + "m");
time.Add(duration.Minutes + " m");
}

if (duration.Hours == 0)
{
if (duration.Seconds > 0)
{
time.Add(duration.Seconds + "s");
time.Add(duration.Seconds + " s");
}

if (duration.Milliseconds > 0 && duration.Minutes == 0)
if (duration.Milliseconds > 0 && duration.Minutes == 0 && duration.Seconds == 0)
{
time.Add(duration.Milliseconds + "ms");
time.Add(duration.Milliseconds + " ms");
}
}

return time.Count == 0 ? "< 1ms" : string.Join(" ", time);
return time.Count == 0 ? "< 1 ms" : string.Join(" ", time);
}

/// <summary>
Expand All @@ -619,6 +635,10 @@ private void TestRunCompleteHandler(object sender, TestRunCompleteEventArgs e)
{
// Stop the progress indicator as we are about to print the summary
this.progressIndicator?.Stop();
var passedTests = 0;
var failedTests = 0;
var skippedTests = 0;
var totalTests = 0;
Output.WriteLine(string.Empty, OutputLevel.Information);

// Printing Run-level Attachments
Expand All @@ -636,6 +656,29 @@ private void TestRunCompleteHandler(object sender, TestRunCompleteEventArgs e)
}
}

foreach (var sd in this.sourceSummaryDictionary.ToArray())
{
var summary = this.sourceSummaryDictionary[sd.Key];
passedTests += summary.PassedTests;
failedTests += summary.FailedTests;
skippedTests += summary.SkippedTests;
totalTests += summary.TotalTests;

if (verbosityLevel == Verbosity.Quiet || verbosityLevel == Verbosity.Minimal)
{
var frameworkString = string.IsNullOrEmpty(targetFramework) ? string.Empty : string.Concat('(', targetFramework, ')');
var resultString = summary.FailedTests > 0 ? CommandLineResources.Failed : CommandLineResources.Passed;
var color = summary.FailedTests > 0 ? ConsoleColor.Red : summary.SkippedTests > 0 ? ConsoleColor.Yellow : ConsoleColor.Green;
var outputLine = string.Format(CultureInfo.CurrentCulture, CommandLineResources.TestRunSummary, resultString, summary.TotalTests, summary.PassedTests, summary.FailedTests, summary.SkippedTests, GetFormattedDurationString(summary.Duration), sd.Key.Split('\\').Last(), frameworkString);
Output.Information(false, color, outputLine);
}
}

if (verbosityLevel == Verbosity.Quiet || verbosityLevel == Verbosity.Minimal)
nohwnd marked this conversation as resolved.
Show resolved Hide resolved
{
return;
}

if (e.IsCanceled)
{
Output.Error(false, CommandLineResources.TestRunCanceled);
Expand All @@ -644,36 +687,36 @@ private void TestRunCompleteHandler(object sender, TestRunCompleteEventArgs e)
{
Output.Error(false, CommandLineResources.TestRunAborted);
}
else if (this.testsFailed > 0 || this.testRunHasErrorMessages)
else if (failedTests > 0 || this.testRunHasErrorMessages)
{
Output.Error(false, CommandLineResources.TestRunFailed);
}
else if (testsTotal > 0)
else if (totalTests > 0)
{
Output.Information(false, ConsoleColor.Green, CommandLineResources.TestRunSuccessful);
}

// Output a summary.
if (testsTotal > 0)
if (totalTests > 0)
{
string totalTestsformat = (e.IsAborted || e.IsCanceled) ? CommandLineResources.TestRunSummaryForCanceledOrAbortedRun : CommandLineResources.TestRunSummaryTotalTests;
Output.Information(false, string.Format(CultureInfo.CurrentCulture, totalTestsformat, testsTotal));
Output.Information(false, string.Format(CultureInfo.CurrentCulture, totalTestsformat, totalTests));

if (testsPassed > 0)
if (passedTests > 0)
{
Output.Information(false, ConsoleColor.Green, string.Format(CultureInfo.CurrentCulture, CommandLineResources.TestRunSummaryPassedTests, testsPassed));
Output.Information(false, ConsoleColor.Green, string.Format(CultureInfo.CurrentCulture, CommandLineResources.TestRunSummaryPassedTests, passedTests));
}
if (testsFailed > 0)
if (failedTests > 0)
{
Output.Information(false, ConsoleColor.Red, string.Format(CultureInfo.CurrentCulture, CommandLineResources.TestRunSummaryFailedTests, testsFailed));
Output.Information(false, ConsoleColor.Red, string.Format(CultureInfo.CurrentCulture, CommandLineResources.TestRunSummaryFailedTests, failedTests));
}
if (testsSkipped > 0)
if (skippedTests > 0)
{
Output.Information(false, ConsoleColor.Yellow, string.Format(CultureInfo.CurrentCulture, CommandLineResources.TestRunSummarySkippedTests, testsSkipped));
Output.Information(false, ConsoleColor.Yellow, string.Format(CultureInfo.CurrentCulture, CommandLineResources.TestRunSummarySkippedTests, skippedTests));
}
}

if (testsTotal > 0)
if (totalTests > 0)
{
if (e.ElapsedTimeInRunningTests.Equals(TimeSpan.Zero))
{
Expand Down
38 changes: 38 additions & 0 deletions src/vstest.console/Internal/SourceSummary.cs
@@ -0,0 +1,38 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace Microsoft.VisualStudio.TestPlatform.CommandLine.Internal
{
using System;

/// <summary>
/// Summary of test results per source.
/// </summary>
internal class SourceSummary
{
/// <summary>
/// Total tests of a test run.
/// </summary>
public int TotalTests { get; set; }

/// <summary>
/// Passed tests of a test run.
/// </summary>
public int PassedTests { get; set; }

/// <summary>
/// Failed tests of a test run.
/// </summary>
public int FailedTests { get; set; }

/// <summary>
/// Skipped tests of a test run.
/// </summary>
public int SkippedTests { get; set; }

/// <summary>
/// Duration of the test run.
/// </summary>
public TimeSpan Duration { get; set; }
}
}
27 changes: 27 additions & 0 deletions src/vstest.console/Resources/Resources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions src/vstest.console/Resources/Resources.resx
Expand Up @@ -734,4 +734,13 @@
<data name="TestSourcesDiscovered" xml:space="preserve">
<value>A total of {0} test files matched the specified pattern.</value>
</data>
<data name="TestRunSummary" xml:space="preserve">
hvinett marked this conversation as resolved.
Show resolved Hide resolved
<value>{0}! Total: {1}. Pass: {2}. Fail: {3}. Skip: {4}. ({5}) {6} {7}.</value>
</data>
<data name="Failed" xml:space="preserve">
hvinett marked this conversation as resolved.
Show resolved Hide resolved
<value>Failed</value>
</data>
<data name="Passed" xml:space="preserve">
<value>Passed</value>
</data>
</root>
15 changes: 15 additions & 0 deletions src/vstest.console/Resources/xlf/Resources.cs.xlf
Expand Up @@ -1656,6 +1656,21 @@
<target state="translated">Celkový počet testovacích souborů, které odpovídají zadanému vzoru: {0}</target>
<note></note>
</trans-unit>
<trans-unit id="TestRunSummary">
<source>{0}! Total: {1}. Pass: {2}. Fail: {3}. Skip: {4}. ({5}) {6} {7}.</source>
<target state="new">{0}! Total: {1}. Pass: {2}. Fail: {3}. Skip: {4}. ({5}) {6} {7}.</target>
<note></note>
</trans-unit>
<trans-unit id="Failed">
<source>Failed</source>
<target state="new">Failed</target>
<note></note>
</trans-unit>
<trans-unit id="Passed">
<source>Passed</source>
<target state="new">Passed</target>
<note></note>
</trans-unit>
</body>
</file>
</xliff>
15 changes: 15 additions & 0 deletions src/vstest.console/Resources/xlf/Resources.de.xlf
Expand Up @@ -1656,6 +1656,21 @@
<target state="translated">Insgesamt {0} Testdateien stimmten mit dem angegebenen Muster überein.</target>
<note></note>
</trans-unit>
<trans-unit id="TestRunSummary">
<source>{0}! Total: {1}. Pass: {2}. Fail: {3}. Skip: {4}. ({5}) {6} {7}.</source>
<target state="new">{0}! Total: {1}. Pass: {2}. Fail: {3}. Skip: {4}. ({5}) {6} {7}.</target>
<note></note>
</trans-unit>
<trans-unit id="Failed">
<source>Failed</source>
<target state="new">Failed</target>
<note></note>
</trans-unit>
<trans-unit id="Passed">
<source>Passed</source>
<target state="new">Passed</target>
<note></note>
</trans-unit>
</body>
</file>
</xliff>