diff --git a/src/Adapter/MSTestAdapter.PlatformServices.Desktop/Services/DesktopTestContextImplementation.cs b/src/Adapter/MSTestAdapter.PlatformServices.Desktop/Services/DesktopTestContextImplementation.cs index a6f0a58669..a1ea30b48d 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices.Desktop/Services/DesktopTestContextImplementation.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices.Desktop/Services/DesktopTestContextImplementation.cs @@ -19,7 +19,7 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices using System.Linq; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Deployment; - + /// /// Internal implementation of TestContext exposed to the user. /// The virtual string properties of the TestContext are retreived from the property dictionary @@ -269,6 +269,32 @@ public override void EndTimer(string timerName) throw new NotSupportedException(); } + // + // Summary: + // When overridden in a derived class, used to write trace messages while the + // test is running. + // + // Parameters: + // message: + // The formatted string that contains the trace message. + public override void WriteLine(string message) + { + if (this.stringWriterDisposed) + { + return; + } + + try + { + var msg = message?.Replace("\0", "\\0"); + stringWriter.WriteLine(msg); + } + catch (ObjectDisposedException) + { + this.stringWriterDisposed = true; + } + } + // // Summary: // When overridden in a derived class, used to write trace messages while the diff --git a/src/TestFramework/UnitTestFramework.Extension.Desktop/TestContext.cs b/src/TestFramework/UnitTestFramework.Extension.Desktop/TestContext.cs index e3f06f039e..f109dd478b 100644 --- a/src/TestFramework/UnitTestFramework.Extension.Desktop/TestContext.cs +++ b/src/TestFramework/UnitTestFramework.Extension.Desktop/TestContext.cs @@ -15,6 +15,12 @@ namespace Microsoft.VisualStudio.TestTools.UnitTesting /// public abstract class TestContext { + /// + /// Used to write trace messages while the test is running + /// + /// formatted message string + public abstract void WriteLine(string message); + /// /// Used to write trace messages while the test is running /// diff --git a/test/UnitTests/MSTestAdapter.PlatformServices.Desktop.Tests/Services/DesktopTestContextImplTests.cs b/test/UnitTests/MSTestAdapter.PlatformServices.Desktop.Tests/Services/DesktopTestContextImplTests.cs index d060643ad8..4cef4a2070 100644 --- a/test/UnitTests/MSTestAdapter.PlatformServices.Desktop.Tests/Services/DesktopTestContextImplTests.cs +++ b/test/UnitTests/MSTestAdapter.PlatformServices.Desktop.Tests/Services/DesktopTestContextImplTests.cs @@ -251,5 +251,40 @@ public void WriteLineShouldNotThrowIfStringWriterIsDisposed() // Calling it twice to cover the direct return when we know the object has been disposed. this.testContextImplementation.WriteLine("{0} Testing write", 1); } + + [TestMethod] + public void WriteLineWithMessageShouldWriteToStringWriter() + { + var stringWriter = new StringWriter(); + this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, stringWriter, this.properties); + + this.testContextImplementation.WriteLine("1 Testing write"); + + StringAssert.Contains(stringWriter.ToString(), "1 Testing write"); + } + + [TestMethod] + public void WriteLineWithMessageShouldWriteToStringWriterForNullCharacters() + { + var stringWriter = new StringWriter(); + this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, stringWriter, this.properties); + + this.testContextImplementation.WriteLine("1 Testing \0 write \0"); + + StringAssert.Contains(stringWriter.ToString(), "1 Testing \\0 write \\0"); + } + + [TestMethod] + public void WriteLineWithMessageShouldNotThrowIfStringWriterIsDisposed() + { + var stringWriter = new StringWriter(); + this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, stringWriter, this.properties); + + stringWriter.Dispose(); + + this.testContextImplementation.WriteLine("1 Testing write"); + // Calling it twice to cover the direct return when we know the object has been disposed. + this.testContextImplementation.WriteLine("1 Testing write"); + } } }