Skip to content

Commit 04218c7

Browse files
authored
[MTP AzDO] Display TFM and test name (#7412)
2 parents 54f88b9 + 0b158f4 commit 04218c7

4 files changed

Lines changed: 18 additions & 28 deletions

File tree

src/Platform/Microsoft.Testing.Extensions.AzureDevOpsReport/AzureDevOpsReporter.cs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ internal sealed class AzureDevOpsReporter :
2727
private readonly ICommandLineOptions _commandLine;
2828
private readonly IEnvironment _environment;
2929
private readonly IFileSystem _fileSystem;
30+
private readonly string _targetFrameworkMoniker;
3031
private string _severity = "error";
3132

3233
public AzureDevOpsReporter(
@@ -41,6 +42,7 @@ public AzureDevOpsReporter(
4142
_fileSystem = fileSystem;
4243
_outputDisplay = outputDisplay;
4344
_logger = loggerFactory.CreateLogger<AzureDevOpsReporter>();
45+
_targetFrameworkMoniker = GetTargetFrameworkMoniker();
4446
}
4547

4648
public Type[] DataTypesConsumed { get; } =
@@ -144,7 +146,7 @@ private async Task WriteExceptionAsync(string testDisplayName, string? explanati
144146
_logger.LogTrace("Failure received.");
145147
}
146148

147-
string? line = GetErrorText(testDisplayName, explanation, exception, _severity, _fileSystem, _logger);
149+
string? line = GetErrorText(testDisplayName, explanation, exception, _severity, _fileSystem, _logger, _targetFrameworkMoniker);
148150
if (line == null)
149151
{
150152
if (_logger.IsEnabled(LogLevel.Trace))
@@ -163,7 +165,7 @@ private async Task WriteExceptionAsync(string testDisplayName, string? explanati
163165
await _outputDisplay.DisplayAsync(this, new FormattedTextOutputDeviceData(line), cancellationToken).ConfigureAwait(false);
164166
}
165167

166-
internal static /* for testing */ string? GetErrorText(string? testDisplayName, string? explanation, Exception? exception, string severity, IFileSystem fileSystem, ILogger logger)
168+
internal static /* for testing */ string? GetErrorText(string testDisplayName, string? explanation, Exception? exception, string severity, IFileSystem fileSystem, ILogger logger, string targetFrameworkMoniker)
167169
{
168170
if (exception == null || exception.StackTrace == null)
169171
{
@@ -286,10 +288,7 @@ private async Task WriteExceptionAsync(string testDisplayName, string? explanati
286288
logger.LogTrace($"Normalized path for GitHub '{relativeNormalizedPath}'.");
287289
}
288290

289-
string formattedMessage = RoslynString.IsNullOrEmpty(testDisplayName)
290-
? message
291-
: $"[{testDisplayName}] {message}";
292-
291+
string formattedMessage = $"[{testDisplayName}] [{targetFrameworkMoniker}] {message}";
293292
string line = $"##vso[task.logissue type={severity};sourcepath={relativeNormalizedPath};linenumber={location.Value.LineNumber};columnnumber=1]{AzDoEscaper.Escape(formattedMessage)}";
294293
if (logger.IsEnabled(LogLevel.Trace))
295294
{
@@ -308,6 +307,10 @@ private async Task WriteExceptionAsync(string testDisplayName, string? explanati
308307
return null;
309308
}
310309

310+
private static string GetTargetFrameworkMoniker()
311+
=> TargetFrameworkParser.GetShortTargetFramework(Assembly.GetEntryAssembly()?.GetCustomAttribute<TargetFrameworkAttribute>()?.FrameworkDisplayName)
312+
?? TargetFrameworkParser.GetShortTargetFramework(RuntimeInformation.FrameworkDescription);
313+
311314
private static (string Code, string File, int LineNumber)? GetStackFrameLocation(string stackTraceLine)
312315
{
313316
Match match = StackTraceHelper.GetFrameRegex().Match(stackTraceLine);

src/Platform/Microsoft.Testing.Platform/OutputDevice/TargetFrameworkParser.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ namespace Microsoft.Testing.Platform.OutputDevice;
55

66
internal static class TargetFrameworkParser
77
{
8+
[return: NotNullIfNotNull(nameof(frameworkDescription))]
89
public static string? GetShortTargetFramework(string? frameworkDescription)
910
{
1011
if (frameworkDescription == null)

test/UnitTests/Microsoft.Testing.Extensions.UnitTests/AzureDevOpsTests.cs

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
33

4-
#if !NETFRAMEWORK || NET472_OR_GREATER
54
using Microsoft.Testing.Extensions.AzureDevOpsReport;
65
using Microsoft.Testing.Platform.Helpers;
7-
#endif
86
using Microsoft.Testing.Platform.Logging;
97

108
namespace Microsoft.Testing.Extensions.UnitTests;
@@ -15,12 +13,6 @@ public sealed class AzureDevOpsTests
1513
[TestMethod]
1614
public void ReportsTheFirstExistingFileInStackTraceWithTheRightLineNumberAndEscaping()
1715
{
18-
#if NETFRAMEWORK && !NET472_OR_GREATER
19-
// We rely on code file paths that are present in pdb for this project. We use portable PDBs, which don't report the code location for
20-
// .NET Framework <4.7.2, so we won't get the path and the test will fail.
21-
// https://learn.microsoft.com/en-us/dotnet/core/diagnostics/symbols#support-for-portable-pdbs
22-
return;
23-
#else
2416
Exception error;
2517
try
2618
{
@@ -33,24 +25,17 @@ public void ReportsTheFirstExistingFileInStackTraceWithTheRightLineNumberAndEsca
3325

3426
// Trim ##. If we keep it, then when the test fails, the assertion failure will get printed to screen and picked up incorrectly by AzDO, because it scans all output for the ##vso... pattern
3527
var logger = new TextLogger();
36-
string? text = AzureDevOpsReporter.GetErrorText("MyTestDisplayName", null, error, "severity", new SystemFileSystem(), logger)?.TrimStart('#');
37-
Assert.AreEqual("vso[task.logissue type=severity;sourcepath=test/UnitTests/Microsoft.Testing.Extensions.UnitTests/AzureDevOpsTests.cs;linenumber=27;columnnumber=1][MyTestDisplayName] this is an error%0Awith%0Dnewline", text, $"\nLogs:\n{string.Join("\n", logger.Logs)}");
38-
#endif
28+
string? text = AzureDevOpsReporter.GetErrorText("MyTestDisplayName", null, error, "severity", new SystemFileSystem(), logger, "net9.0")?.TrimStart('#');
29+
Assert.AreEqual("vso[task.logissue type=severity;sourcepath=test/UnitTests/Microsoft.Testing.Extensions.UnitTests/AzureDevOpsTests.cs;linenumber=19;columnnumber=1][MyTestDisplayName] [net9.0] this is an error%0Awith%0Dnewline", text, $"\nLogs:\n{string.Join("\n", logger.Logs)}");
3930
}
4031

4132
[TestMethod]
42-
public void ReportsWithoutDisplayNameWhenNull()
33+
public void ReportsTheFirstExistingFileInStackTraceWithTheRightLineNumberAndEscapingAndOverrideExceptionMessage()
4334
{
44-
#if NETFRAMEWORK && !NET472_OR_GREATER
45-
// We rely on code file paths that are present in pdb for this project. We use portable PDBs, which don't report the code location for
46-
// .NET Framework <4.7.2, so we won't get the path and the test will fail.
47-
// https://learn.microsoft.com/en-us/dotnet/core/diagnostics/symbols#support-for-portable-pdbs
48-
return;
49-
#else
5035
Exception error;
5136
try
5237
{
53-
throw new Exception("this is an error");
38+
throw new Exception("this is an error\nwith\rnewline");
5439
}
5540
catch (Exception ex)
5641
{
@@ -59,9 +44,8 @@ public void ReportsWithoutDisplayNameWhenNull()
5944

6045
// Trim ##. If we keep it, then when the test fails, the assertion failure will get printed to screen and picked up incorrectly by AzDO, because it scans all output for the ##vso... pattern
6146
var logger = new TextLogger();
62-
string? text = AzureDevOpsReporter.GetErrorText(null, null, error, "severity", new SystemFileSystem(), logger)?.TrimStart('#');
63-
Assert.AreEqual("vso[task.logissue type=severity;sourcepath=test/UnitTests/Microsoft.Testing.Extensions.UnitTests/AzureDevOpsTests.cs;linenumber=53;columnnumber=1]this is an error", text, $"\nLogs:\n{string.Join("\n", logger.Logs)}");
64-
#endif
47+
string? text = AzureDevOpsReporter.GetErrorText("MyTestDisplayName", "Some custom reason\nwith\rnewline", error, "severity", new SystemFileSystem(), logger, "net9.0")?.TrimStart('#');
48+
Assert.AreEqual("vso[task.logissue type=severity;sourcepath=test/UnitTests/Microsoft.Testing.Extensions.UnitTests/AzureDevOpsTests.cs;linenumber=38;columnnumber=1][MyTestDisplayName] [net9.0] Some custom reason%0Awith%0Dnewline", text, $"\nLogs:\n{string.Join("\n", logger.Logs)}");
6549
}
6650

6751
private class TextLogger : ILogger

test/UnitTests/Microsoft.Testing.Extensions.UnitTests/Microsoft.Testing.Extensions.UnitTests.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT' ">$(TargetFrameworks);net462;net472</TargetFrameworks>
1010
<EnableMSTestRunner>true</EnableMSTestRunner>
1111
<OutputType>Exe</OutputType>
12+
<!-- Use full PDBs on .NET Framework so that stack traces include file paths and line numbers even on net462 -->
13+
<DebugType Condition="$([MSBuild]::GetTargetFrameworkIdentifier('$(TargetFramework)')) == '.NETFramework'">full</DebugType>
1214
</PropertyGroup>
1315

1416
<ItemGroup>

0 commit comments

Comments
 (0)