diff --git a/src/Adapter/PlatformServices.Desktop/Services/DesktopTestContextImplementation.cs b/src/Adapter/PlatformServices.Desktop/Services/DesktopTestContextImplementation.cs
index 365dd15478..3fc57d069f 100644
--- a/src/Adapter/PlatformServices.Desktop/Services/DesktopTestContextImplementation.cs
+++ b/src/Adapter/PlatformServices.Desktop/Services/DesktopTestContextImplementation.cs
@@ -249,6 +249,53 @@ public override void EndTimer(string timerName)
throw new NotSupportedException();
}
+ ///
+ /// When overridden in a derived class, used to write trace messages while the
+ /// test is running.
+ ///
+ /// The formatted string that contains the trace message.
+ public override void Write(string message)
+ {
+ if (this.stringWriterDisposed)
+ {
+ return;
+ }
+
+ try
+ {
+ var msg = message?.Replace("\0", "\\0");
+ this.stringWriter.Write(msg);
+ }
+ catch (ObjectDisposedException)
+ {
+ this.stringWriterDisposed = true;
+ }
+ }
+
+ ///
+ /// When overridden in a derived class, used to write trace messages while the
+ /// test is running.
+ ///
+ /// The string that contains the trace message.
+ /// Arguments to add to the trace message.
+ public override void Write(string format, params object[] args)
+ {
+ if (this.stringWriterDisposed)
+ {
+ return;
+ }
+
+ try
+ {
+ string message = string.Format(CultureInfo.CurrentCulture, format?.Replace("\0", "\\0"), args);
+ this.stringWriter.Write(message);
+ }
+ catch (ObjectDisposedException)
+ {
+ this.stringWriterDisposed = true;
+ }
+ }
+
///
/// When overridden in a derived class, used to write trace messages while the
/// test is running.
diff --git a/src/Adapter/PlatformServices.NetCore/Services/NetCoreTestContextImplementation.cs b/src/Adapter/PlatformServices.NetCore/Services/NetCoreTestContextImplementation.cs
index b1f11a2dc9..40595a6bee 100644
--- a/src/Adapter/PlatformServices.NetCore/Services/NetCoreTestContextImplementation.cs
+++ b/src/Adapter/PlatformServices.NetCore/Services/NetCoreTestContextImplementation.cs
@@ -289,6 +289,53 @@ public IList GetResultFiles()
return results;
}
+ ///
+ /// When overridden in a derived class, used to write trace messages while the
+ /// test is running.
+ ///
+ /// The formatted string that contains the trace message.
+ public override void Write(string message)
+ {
+ if (this.stringWriterDisposed)
+ {
+ return;
+ }
+
+ try
+ {
+ var msg = message?.Replace("\0", "\\0");
+ this.stringWriter.Write(msg);
+ }
+ catch (ObjectDisposedException)
+ {
+ this.stringWriterDisposed = true;
+ }
+ }
+
+ ///
+ /// When overridden in a derived class, used to write trace messages while the
+ /// test is running.
+ ///
+ /// The string that contains the trace message.
+ /// Arguments to add to the trace message.
+ public override void Write(string format, params object[] args)
+ {
+ if (this.stringWriterDisposed)
+ {
+ return;
+ }
+
+ try
+ {
+ string message = string.Format(CultureInfo.CurrentCulture, format?.Replace("\0", "\\0"), args);
+ this.stringWriter.Write(message);
+ }
+ catch (ObjectDisposedException)
+ {
+ this.stringWriterDisposed = true;
+ }
+ }
+
///
/// When overridden in a derived class, used to write trace messages while the
/// test is running.
diff --git a/src/Adapter/PlatformServices.Shared/netstandard1.0/Services/ns10TestContextImplementation.cs b/src/Adapter/PlatformServices.Shared/netstandard1.0/Services/ns10TestContextImplementation.cs
index 7018ad4550..acdc11a496 100644
--- a/src/Adapter/PlatformServices.Shared/netstandard1.0/Services/ns10TestContextImplementation.cs
+++ b/src/Adapter/PlatformServices.Shared/netstandard1.0/Services/ns10TestContextImplementation.cs
@@ -187,6 +187,53 @@ public void AddProperty(string propertyName, string propertyValue)
this.properties.Add(propertyName, propertyValue);
}
+ ///
+ /// When overridden in a derived class, used to write trace messages while the
+ /// test is running.
+ ///
+ /// The formatted string that contains the trace message.
+ public override void Write(string message)
+ {
+ if (this.stringWriterDisposed)
+ {
+ return;
+ }
+
+ try
+ {
+ var msg = message?.Replace("\0", "\\0");
+ this.stringWriter.Write(msg);
+ }
+ catch (ObjectDisposedException)
+ {
+ this.stringWriterDisposed = true;
+ }
+ }
+
+ ///
+ /// When overridden in a derived class, used to write trace messages while the
+ /// test is running.
+ ///
+ /// The string that contains the trace message.
+ /// Arguments to add to the trace message.
+ public override void Write(string format, params object[] args)
+ {
+ if (this.stringWriterDisposed)
+ {
+ return;
+ }
+
+ try
+ {
+ string message = string.Format(CultureInfo.CurrentCulture, format?.Replace("\0", "\\0"), args);
+ this.stringWriter.Write(message);
+ }
+ catch (ObjectDisposedException)
+ {
+ this.stringWriterDisposed = true;
+ }
+ }
+
///
/// When overridden in a derived class, used to write trace messages while the
/// test is running.
diff --git a/src/TestFramework/Extension.Core/NetCoreTestContext.cs b/src/TestFramework/Extension.Core/NetCoreTestContext.cs
index ebecd7fb76..140116e780 100644
--- a/src/TestFramework/Extension.Core/NetCoreTestContext.cs
+++ b/src/TestFramework/Extension.Core/NetCoreTestContext.cs
@@ -105,6 +105,19 @@ public abstract class TestContext
///
public abstract void AddResultFile(string fileName);
+ ///
+ /// Used to write trace messages while the test is running
+ ///
+ /// formatted message string
+ public abstract void Write(string message);
+
+ ///
+ /// Used to write trace messages while the test is running
+ ///
+ /// format string
+ /// the arguments
+ public abstract void Write(string format, params object[] args);
+
///
/// Used to write trace messages while the test is running
///
diff --git a/src/TestFramework/Extension.Desktop/DesktopTestContext.cs b/src/TestFramework/Extension.Desktop/DesktopTestContext.cs
index 1b95acd060..6829575609 100644
--- a/src/TestFramework/Extension.Desktop/DesktopTestContext.cs
+++ b/src/TestFramework/Extension.Desktop/DesktopTestContext.cs
@@ -111,6 +111,19 @@ public abstract class TestContext
///
public virtual UnitTestOutcome CurrentTestOutcome => UnitTestOutcome.Unknown;
+ ///
+ /// Used to write trace messages while the test is running
+ ///
+ /// formatted message string
+ public abstract void Write(string message);
+
+ ///
+ /// Used to write trace messages while the test is running
+ ///
+ /// format string
+ /// the arguments
+ public abstract void Write(string format, params object[] args);
+
///
/// Used to write trace messages while the test is running
///
diff --git a/src/TestFramework/Extension.Shared/TestContext.cs b/src/TestFramework/Extension.Shared/TestContext.cs
index 73996020eb..4de71f3bf4 100644
--- a/src/TestFramework/Extension.Shared/TestContext.cs
+++ b/src/TestFramework/Extension.Shared/TestContext.cs
@@ -48,6 +48,19 @@ public abstract class TestContext
///
public virtual UnitTestOutcome CurrentTestOutcome => UnitTestOutcome.Unknown;
+ ///
+ /// Used to write trace messages while the test is running
+ ///
+ /// formatted message string
+ public abstract void Write(string message);
+
+ ///
+ /// Used to write trace messages while the test is running
+ ///
+ /// format string
+ /// the arguments
+ public abstract void Write(string format, params object[] args);
+
///
/// Used to write trace messages while the test is running
///
diff --git a/test/UnitTests/PlatformServices.Desktop.Unit.Tests/Services/DesktopTestContextImplTests.cs b/test/UnitTests/PlatformServices.Desktop.Unit.Tests/Services/DesktopTestContextImplTests.cs
index e5d26ae794..e164d16f5b 100644
--- a/test/UnitTests/PlatformServices.Desktop.Unit.Tests/Services/DesktopTestContextImplTests.cs
+++ b/test/UnitTests/PlatformServices.Desktop.Unit.Tests/Services/DesktopTestContextImplTests.cs
@@ -25,7 +25,7 @@ namespace MSTestAdapter.PlatformServices.Desktop.UnitTests.Services
using UnitTestOutcome = FrameworkV2::Microsoft.VisualStudio.TestTools.UnitTesting.UnitTestOutcome;
[TestClass]
- public class DEsktopTestContextImplTests
+ public class DesktopTestContextImplTests
{
private Mock testMethod;
@@ -215,6 +215,76 @@ public void AddResultFileShouldAddMultipleFilestoResultsFiles()
CollectionAssert.Contains(resultsFiles.ToList(), "C:\\temp2.txt");
}
+ [TestMethod]
+ public void WriteShouldWriteToStringWriter()
+ {
+ var stringWriter = new StringWriter();
+ this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, stringWriter, this.properties);
+ this.testContextImplementation.Write("{0} Testing write", 1);
+ StringAssert.Contains(stringWriter.ToString(), "1 Testing write");
+ }
+
+ [TestMethod]
+ public void WriteShouldWriteToStringWriterForNullCharacters()
+ {
+ var stringWriter = new StringWriter();
+ this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, stringWriter, this.properties);
+ this.testContextImplementation.Write("{0} Testing \0 write \0", 1);
+ StringAssert.Contains(stringWriter.ToString(), "1 Testing \\0 write \\0");
+ }
+
+ [TestMethod]
+ public void WriteShouldNotThrowIfStringWriterIsDisposed()
+ {
+ var stringWriter = new StringWriter();
+ this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, stringWriter, this.properties);
+ stringWriter.Dispose();
+ this.testContextImplementation.Write("{0} Testing write", 1);
+
+ // Calling it twice to cover the direct return when we know the object has been disposed.
+ this.testContextImplementation.Write("{0} Testing write", 1);
+ }
+
+ [TestMethod]
+ public void WriteWithMessageShouldWriteToStringWriter()
+ {
+ var stringWriter = new StringWriter();
+ this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, stringWriter, this.properties);
+ this.testContextImplementation.Write("1 Testing write");
+ StringAssert.Contains(stringWriter.ToString(), "1 Testing write");
+ }
+
+ [TestMethod]
+ public void WriteWithMessageShouldWriteToStringWriterForNullCharacters()
+ {
+ var stringWriter = new StringWriter();
+ this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, stringWriter, this.properties);
+ this.testContextImplementation.Write("1 Testing \0 write \0");
+ StringAssert.Contains(stringWriter.ToString(), "1 Testing \\0 write \\0");
+ }
+
+ [TestMethod]
+ public void WriteWithMessageShouldNotThrowIfStringWriterIsDisposed()
+ {
+ var stringWriter = new StringWriter();
+ this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, stringWriter, this.properties);
+ stringWriter.Dispose();
+ this.testContextImplementation.Write("1 Testing write");
+
+ // Calling it twice to cover the direct return when we know the object has been disposed.
+ this.testContextImplementation.Write("1 Testing write");
+ }
+
+ [TestMethod]
+ public void WriteWithMessageShouldWriteToStringWriterForReturnCharacters()
+ {
+ var stringWriter = new StringWriter();
+ this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, stringWriter, this.properties);
+ this.testContextImplementation.Write("2 Testing write \n\r");
+ this.testContextImplementation.Write("3 Testing write\n\r");
+ StringAssert.Equals(stringWriter.ToString(), "2 Testing write 3 Testing write");
+ }
+
[TestMethod]
public void WriteLineShouldWriteToStringWriter()
{
diff --git a/test/UnitTests/PlatformServices.NetCore.Unit.Tests/Services/NetCoreTestContextImplementationTests.cs b/test/UnitTests/PlatformServices.NetCore.Unit.Tests/Services/NetCoreTestContextImplementationTests.cs
index b375b9470c..4c06dfba8f 100644
--- a/test/UnitTests/PlatformServices.NetCore.Unit.Tests/Services/NetCoreTestContextImplementationTests.cs
+++ b/test/UnitTests/PlatformServices.NetCore.Unit.Tests/Services/NetCoreTestContextImplementationTests.cs
@@ -164,6 +164,76 @@ public void AddPropertyShouldAddPropertiesToThePropertyBag()
new KeyValuePair("SomeNewProperty", "SomeValue"));
}
+ [TestMethod]
+ public void WriteShouldWriteToStringWriter()
+ {
+ var stringWriter = new StringWriter();
+ this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, stringWriter, this.properties);
+ this.testContextImplementation.Write("{0} Testing write", 1);
+ StringAssert.Contains(stringWriter.ToString(), "1 Testing write");
+ }
+
+ [TestMethod]
+ public void WriteShouldWriteToStringWriterForNullCharacters()
+ {
+ var stringWriter = new StringWriter();
+ this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, stringWriter, this.properties);
+ this.testContextImplementation.Write("{0} Testing \0 write \0", 1);
+ StringAssert.Contains(stringWriter.ToString(), "1 Testing \\0 write \\0");
+ }
+
+ [TestMethod]
+ public void WriteShouldNotThrowIfStringWriterIsDisposed()
+ {
+ var stringWriter = new StringWriter();
+ this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, stringWriter, this.properties);
+ stringWriter.Dispose();
+ this.testContextImplementation.Write("{0} Testing write", 1);
+
+ // Calling it twice to cover the direct return when we know the object has been disposed.
+ this.testContextImplementation.Write("{0} Testing write", 1);
+ }
+
+ [TestMethod]
+ public void WriteWithMessageShouldWriteToStringWriter()
+ {
+ var stringWriter = new StringWriter();
+ this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, stringWriter, this.properties);
+ this.testContextImplementation.Write("1 Testing write");
+ StringAssert.Contains(stringWriter.ToString(), "1 Testing write");
+ }
+
+ [TestMethod]
+ public void WriteWithMessageShouldWriteToStringWriterForNullCharacters()
+ {
+ var stringWriter = new StringWriter();
+ this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, stringWriter, this.properties);
+ this.testContextImplementation.Write("1 Testing \0 write \0");
+ StringAssert.Contains(stringWriter.ToString(), "1 Testing \\0 write \\0");
+ }
+
+ [TestMethod]
+ public void WriteWithMessageShouldNotThrowIfStringWriterIsDisposed()
+ {
+ var stringWriter = new StringWriter();
+ this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, stringWriter, this.properties);
+ stringWriter.Dispose();
+ this.testContextImplementation.Write("1 Testing write");
+
+ // Calling it twice to cover the direct return when we know the object has been disposed.
+ this.testContextImplementation.Write("1 Testing write");
+ }
+
+ [TestMethod]
+ public void WriteWithMessageShouldWriteToStringWriterForReturnCharacters()
+ {
+ var stringWriter = new StringWriter();
+ this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, stringWriter, this.properties);
+ this.testContextImplementation.Write("2 Testing write \n\r");
+ this.testContextImplementation.Write("3 Testing write\n\r");
+ StringAssert.Equals(stringWriter.ToString(), "2 Testing write 3 Testing write");
+ }
+
[TestMethod]
public void WriteLineShouldWriteToStringWriter()
{
diff --git a/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/ns10TestContextImplementationTests.cs b/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/ns10TestContextImplementationTests.cs
index e0c26889da..e29c15dda9 100644
--- a/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/ns10TestContextImplementationTests.cs
+++ b/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/ns10TestContextImplementationTests.cs
@@ -161,6 +161,76 @@ public void AddPropertyShouldAddPropertiesToThePropertyBag()
new KeyValuePair("SomeNewProperty", "SomeValue"));
}
+ [TestMethod]
+ public void WriteShouldWriteToStringWriter()
+ {
+ var stringWriter = new StringWriter();
+ this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, stringWriter, this.properties);
+ this.testContextImplementation.Write("{0} Testing write", 1);
+ StringAssert.Contains(stringWriter.ToString(), "1 Testing write");
+ }
+
+ [TestMethod]
+ public void WriteShouldWriteToStringWriterForNullCharacters()
+ {
+ var stringWriter = new StringWriter();
+ this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, stringWriter, this.properties);
+ this.testContextImplementation.Write("{0} Testing \0 write \0", 1);
+ StringAssert.Contains(stringWriter.ToString(), "1 Testing \\0 write \\0");
+ }
+
+ [TestMethod]
+ public void WriteShouldNotThrowIfStringWriterIsDisposed()
+ {
+ var stringWriter = new StringWriter();
+ this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, stringWriter, this.properties);
+ stringWriter.Dispose();
+ this.testContextImplementation.Write("{0} Testing write", 1);
+
+ // Calling it twice to cover the direct return when we know the object has been disposed.
+ this.testContextImplementation.Write("{0} Testing write", 1);
+ }
+
+ [TestMethod]
+ public void WriteWithMessageShouldWriteToStringWriter()
+ {
+ var stringWriter = new StringWriter();
+ this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, stringWriter, this.properties);
+ this.testContextImplementation.Write("1 Testing write");
+ StringAssert.Contains(stringWriter.ToString(), "1 Testing write");
+ }
+
+ [TestMethod]
+ public void WriteWithMessageShouldWriteToStringWriterForNullCharacters()
+ {
+ var stringWriter = new StringWriter();
+ this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, stringWriter, this.properties);
+ this.testContextImplementation.Write("1 Testing \0 write \0");
+ StringAssert.Contains(stringWriter.ToString(), "1 Testing \\0 write \\0");
+ }
+
+ [TestMethod]
+ public void WriteWithMessageShouldNotThrowIfStringWriterIsDisposed()
+ {
+ var stringWriter = new StringWriter();
+ this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, stringWriter, this.properties);
+ stringWriter.Dispose();
+ this.testContextImplementation.Write("1 Testing write");
+
+ // Calling it twice to cover the direct return when we know the object has been disposed.
+ this.testContextImplementation.Write("1 Testing write");
+ }
+
+ [TestMethod]
+ public void WriteWithMessageShouldWriteToStringWriterForReturnCharacters()
+ {
+ var stringWriter = new StringWriter();
+ this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, stringWriter, this.properties);
+ this.testContextImplementation.Write("2 Testing write \n\r");
+ this.testContextImplementation.Write("3 Testing write\n\r");
+ StringAssert.Equals(stringWriter.ToString(), "2 Testing write 3 Testing write");
+ }
+
[TestMethod]
public void WriteLineShouldWriteToStringWriter()
{