Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ internal static class MtpConstants
public const string TimeDurationMs = "time.duration-ms";
public const string ErrorMessage = "error.message";
public const string ErrorStackTrace = "error.stacktrace";
public const string StandardOutput = "standardOutput";
public const string StandardError = "standardError";
public const string LocationFile = "location.file";
public const string LocationLineStart = "location.line-start";
public const string Traits = "traits";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,21 @@ public static TestResult ToTestResult(JsonObject node, string source)
result.Duration = TimeSpan.FromMilliseconds(durationMs);
}

// Surface the test's captured standard output/error (when the MTP node carries it) as result
// messages so the console and TRX loggers show it, matching the classic path where a test's
// stdout/stderr is attached to its result.
string? standardOutput = MtpJson.GetString(node, MtpConstants.StandardOutput);
if (!string.IsNullOrEmpty(standardOutput))
{
result.Messages.Add(new TestResultMessage(TestResultMessage.StandardOutCategory, standardOutput));
}

string? standardError = MtpJson.GetString(node, MtpConstants.StandardError);
if (!string.IsNullOrEmpty(standardError))
{
result.Messages.Add(new TestResultMessage(TestResultMessage.StandardErrorCategory, standardError));
}

return result;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,4 +122,35 @@ public void RunMtpApplicationWithBlameCompletesRun(RunnerInfo runnerInfo)

ValidateSummaryStatus(2, 1, 1);
}

[TestMethod]
// A test's captured standard output/error must be surfaced to the loggers. The MTP node carries the
// per-test standardOutput/standardError; MtpTestNodeConverter now maps them onto the vstest result so
// the console and TRX show them. Before this the markers appeared nowhere. TestPassesToo writes the
// markers; the run produces a TRX that must contain them.
[TestMatrix(testHost: Target.Net)]
public void RunMtpApplicationSurfacesPerTestStandardOutput(RunnerInfo runnerInfo)
{
SetTestEnvironment(_testEnvironment, runnerInfo);

var trxFileName = "stdout.trx";
var arguments = PrepareArguments(
GetAssetFullPath(MtpApp),
testAdapterPath: null,
runSettings: string.Empty,
FrameworkArgValue,
runnerInfo.InIsolationValue,
resultsDirectory: TempDirectory.Path);
arguments = string.Concat(arguments, $" /logger:trx;LogFileName={trxFileName}");

InvokeVsTest(arguments);

ValidateSummaryStatus(2, 1, 1);

var trxPath = Path.Combine(TempDirectory.Path, trxFileName);
Assert.IsTrue(File.Exists(trxPath), "Expected a TRX at '{0}'.", trxPath);
var trx = File.ReadAllText(trxPath);
Assert.Contains("MTP_STDOUT_MARKER", trx, "Expected the test's standard output to be surfaced into the TRX.");
Assert.Contains("MTP_STDERR_MARKER", trx, "Expected the test's standard error to be surfaced into the TRX.");
}
}
4 changes: 4 additions & 0 deletions test/TestAssets/MtpMSTestProject/UnitTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ public void TestPasses()
[TestMethod]
public void TestPassesToo()
{
// Writes to stdout and stderr (and still passes) so the MTP-under-vstest stdout acceptance test can
// assert the captured per-test output is surfaced to the console and TRX loggers.
System.Console.WriteLine("MTP_STDOUT_MARKER");
System.Console.Error.WriteLine("MTP_STDERR_MARKER");
Assert.AreEqual(2, Add(1, 1));
}

Expand Down