Reputation: 16201
I have been trying to figure out a way to add some string output to NUnit test results. I did some research and came across this, but this is not what I want. I want to write the output to the result xml
generated by NUnit, but I cannot find a way to do it. Please suggest!
I aware that NUnit 3 will have a mechanism called TextContex to accomplish something similar, but I am using 2.6.3.
Upvotes: 2
Views: 4047
Reputation: 763
You could take advantage of PropertyAttribute
s to attach properties per test to the XML output. The example below assumes you really want to use Console.WriteLine
to produce string output, but you could always make your own TestConsole.WriteLine
or something if you don't want to mess with the console output.
E.g. this attribute says to attach an "Output" property to each test it's declared on:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class TestWriterAttribute : PropertyAttribute
{
public TestWriterAttribute() : base()
{
// Create a container for test output
Properties["Output"] = new StringBuilder();
}
}
And this attribute says to redirect Console.Out
to your "Output" property (again, you can use your own TestConsole
kind of class instead of using this attribute if you don't want to mess with Console.Out
).
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class ConsoleOutToTestWriterAttribute : TestActionAttribute
{
public override void BeforeTest(TestDetails testDetails)
{
// If the test has a [TestWriter], redirect Console.Out to its "Output" property
var output = TestContext.CurrentContext.Test.Properties["Output"] as StringBuilder;
if (output != null)
Console.SetOut(new System.IO.StringWriter(output));
_consoleOutRedirected = output != null;
}
public override void AfterTest(TestDetails testDetails)
{
// Reset Console.Out, if appropriate
if(_consoleOutRedirected)
Console.SetOut(new System.IO.StreamWriter(Console.OpenStandardOutput()) { AutoFlush = true });
}
public override ActionTargets Targets
{
// needs to apply to each test, since [TestWriter]s are applied per test
get { return ActionTargets.Test; }
}
private bool _consoleOutRedirected;
}
And your tests can just use Console.WriteLine
which will be captured per test:
[ConsoleOutToTestWriter] // redirect Console.Out into "Output" property per test
public class ClassTest
{
[Test]
[TestWriter] // adds "Output" property
public void MyTest()
{
Console.WriteLine("test 123");
Console.WriteLine("321 test");
}
[Test]
[TestWriter]
public void MyTest2()
{
// this console output will be written to this test's own "Output"
Console.WriteLine("test2 123");
Console.WriteLine("321 test2");
}
}
Which produces the following under <results>
in the NUnit XML output:
<test-case name="SO_31092459.ClassTest.MyTest" executed="True" result="Success" success="True" time="0.023" asserts="0">
<properties>
<property name="Output" value="test 123
321 test
" />
</properties>
</test-case>
<test-case name="SO_31092459.ClassTest.MyTest2" executed="True" result="Success" success="True" time="0.000" asserts="0">
<properties>
<property name="Output" value="test2 123
321 test2
" />
</properties>
</test-case>
Upvotes: 1