diff --git a/Frank.Testing.TestOutputExtensions/Frank.Testing.TestOutputExtensions.csproj b/Frank.Testing.TestOutputExtensions/Frank.Testing.TestOutputExtensions.csproj
index 75d72d5..8a14d3c 100644
--- a/Frank.Testing.TestOutputExtensions/Frank.Testing.TestOutputExtensions.csproj
+++ b/Frank.Testing.TestOutputExtensions/Frank.Testing.TestOutputExtensions.csproj
@@ -1,13 +1,14 @@
- Xunit
+ Xunit.Abstractions
Extends ITestOutputHelper to allow output of a generic type using a serializer.
- test, xunit, output, helper, serializer, json, console
+ test, testing, extensions, xunit, output, helper, serializer, json, xml, csharp, dump, var, dumpvar, vardump, xmlserializer, jsonserializer, testoutputhelper, testoutput, outputhelper, ITestOutputHelper, abstractions, xunit.abstractions, xunit.abstractions.extensions, xunit.extensions.ordering
+
diff --git a/Frank.Testing.TestOutputExtensions/TestOutputCSharpExtensions.cs b/Frank.Testing.TestOutputExtensions/TestOutputCSharpExtensions.cs
new file mode 100644
index 0000000..fd2449b
--- /dev/null
+++ b/Frank.Testing.TestOutputExtensions/TestOutputCSharpExtensions.cs
@@ -0,0 +1,53 @@
+using System.ComponentModel;
+
+using FluentAssertions;
+
+using VarDump;
+using VarDump.Visitor;
+
+namespace Xunit.Abstractions;
+
+public static class TestOutputCSharpExtensions
+{
+ ///
+ /// Writes the provided source object as C# code to the test output.
+ ///
+ ///
+ /// The C# code is written using the
+ ///
+ ///
+ ///
+ /// var testPerson = new Frank.Testing.Tests.TestPerson
+ /// {
+ /// Name = "John Doe",
+ /// Age = 30,
+ /// Address = new Frank.Testing.Tests.TestAddress
+ /// {
+ /// City = "Main City",
+ /// ZipCode = 18846
+ /// }
+ /// };
+ ///
+ ///
+ /// The type of the source object.
+ /// The test output helper.
+ /// The source object to be written as C# code.
+ /// The optional dump options to control the formatting of the C# code.
+ public static void WriteCSharp(this ITestOutputHelper outputHelper, T source, DumpOptions? dumpOptions = null)
+ {
+ var options = dumpOptions ?? DumpOptions;
+ var dumper = new CSharpDumper(options);
+ outputHelper.WriteLine(dumper.Dump(source));
+ }
+
+ private static DumpOptions DumpOptions => new DumpOptions()
+ {
+ IgnoreNullValues = true,
+ DateKind = DateKind.ConvertToUtc,
+ DateTimeInstantiation = DateTimeInstantiation.Parse,
+ UseTypeFullName = true,
+ GenerateVariableInitializer = true,
+ SortDirection = ListSortDirection.Ascending,
+ MaxDepth = 64,
+ };
+}
\ No newline at end of file
diff --git a/Frank.Testing.TestOutputExtensions/TestOutputExtensions.cs b/Frank.Testing.TestOutputExtensions/TestOutputJsonExtensions.cs
similarity index 95%
rename from Frank.Testing.TestOutputExtensions/TestOutputExtensions.cs
rename to Frank.Testing.TestOutputExtensions/TestOutputJsonExtensions.cs
index c845af1..0f331cc 100644
--- a/Frank.Testing.TestOutputExtensions/TestOutputExtensions.cs
+++ b/Frank.Testing.TestOutputExtensions/TestOutputJsonExtensions.cs
@@ -1,11 +1,9 @@
using System.Text.Json;
using System.Text.Json.Serialization;
-using Xunit.Abstractions;
+namespace Xunit.Abstractions;
-namespace Xunit;
-
-public static class TestOutputExtensions
+public static class TestOutputJsonExtensions
{
///
/// Writes the specified object's string representation followed by the current line terminator to the output.
diff --git a/Frank.Testing.TestOutputExtensions/TestOutputXmlExtensions.cs b/Frank.Testing.TestOutputExtensions/TestOutputXmlExtensions.cs
new file mode 100644
index 0000000..19c05b5
--- /dev/null
+++ b/Frank.Testing.TestOutputExtensions/TestOutputXmlExtensions.cs
@@ -0,0 +1,29 @@
+using System.Text;
+using System.Xml;
+using System.Xml.Serialization;
+
+namespace Xunit.Abstractions;
+
+public static class TestOutputXmlExtensions
+{
+ public static void WriteXml(this ITestOutputHelper outputHelper, T source, XmlWriterSettings? xmlWriterSettings = null)
+ {
+ var settings = xmlWriterSettings ?? XmlWriterSettings;
+
+ using var textWriter = new StringWriter();
+ using var xmlWriter = XmlWriter.Create(textWriter, settings);
+ var xmlSerializer = new XmlSerializerFactory().CreateSerializer(typeof(T));
+ xmlSerializer.Serialize(xmlWriter, source);
+ outputHelper.WriteLine(textWriter.ToString());
+ }
+
+ private static XmlWriterSettings XmlWriterSettings => new()
+ {
+ Indent = true,
+ IndentChars = new string(' ', 4),
+ NewLineChars = "\n",
+ NewLineHandling = NewLineHandling.Replace,
+ OmitXmlDeclaration = false,
+ Encoding = new UTF8Encoding(false),
+ };
+}
\ No newline at end of file
diff --git a/Frank.Testing.Tests/Frank.Testing.Tests.csproj b/Frank.Testing.Tests/Frank.Testing.Tests.csproj
index ebb790f..136322f 100644
--- a/Frank.Testing.Tests/Frank.Testing.Tests.csproj
+++ b/Frank.Testing.Tests/Frank.Testing.Tests.csproj
@@ -10,6 +10,7 @@
+
@@ -25,6 +26,7 @@
+
diff --git a/Frank.Testing.Tests/UnitTest1.cs b/Frank.Testing.Tests/TestLoggingTests.cs
similarity index 94%
rename from Frank.Testing.Tests/UnitTest1.cs
rename to Frank.Testing.Tests/TestLoggingTests.cs
index 8bd8a2e..57a0df4 100644
--- a/Frank.Testing.Tests/UnitTest1.cs
+++ b/Frank.Testing.Tests/TestLoggingTests.cs
@@ -10,11 +10,11 @@
namespace Frank.Testing.Tests;
-public class UnitTest1
+public class TestLoggingTests
{
private readonly ITestOutputHelper _outputHelper;
- public UnitTest1(ITestOutputHelper outputHelper)
+ public TestLoggingTests(ITestOutputHelper outputHelper)
{
_outputHelper = outputHelper;
}
diff --git a/Frank.Testing.Tests/TestOutputCSharpExtensionsTests.cs b/Frank.Testing.Tests/TestOutputCSharpExtensionsTests.cs
new file mode 100644
index 0000000..938dc82
--- /dev/null
+++ b/Frank.Testing.Tests/TestOutputCSharpExtensionsTests.cs
@@ -0,0 +1,17 @@
+using JetBrains.Annotations;
+
+using Xunit.Abstractions;
+
+namespace Frank.Testing.Tests;
+
+[TestSubject(typeof(TestOutputCSharpExtensions))]
+public class TestOutputCSharpExtensionsTests(ITestOutputHelper outputHelper)
+{
+ [Fact]
+ public void WriteCSharp_ShouldWriteCSharpOutput_WhenSourceIsSimpleObject()
+ {
+ var source = new TestPerson { Name = "John Doe", Age = 30 };
+
+ outputHelper.WriteCSharp(source);
+ }
+}
\ No newline at end of file
diff --git a/Frank.Testing.Tests/TestOutputExtensionsTests.cs b/Frank.Testing.Tests/TestOutputExtensionsTests.cs
index 8a2d241..a861aa8 100644
--- a/Frank.Testing.Tests/TestOutputExtensionsTests.cs
+++ b/Frank.Testing.Tests/TestOutputExtensionsTests.cs
@@ -4,7 +4,7 @@
namespace Frank.Testing.Tests;
-[TestSubject(typeof(TestOutputExtensions))]
+[TestSubject(typeof(TestOutputJsonExtensions))]
public class TestOutputExtensionsTests
{
private readonly ITestOutputHelper _outputHelper;
diff --git a/Frank.Testing.Tests/TestOutputXmlExtensionsTests.cs b/Frank.Testing.Tests/TestOutputXmlExtensionsTests.cs
new file mode 100644
index 0000000..8e3d3df
--- /dev/null
+++ b/Frank.Testing.Tests/TestOutputXmlExtensionsTests.cs
@@ -0,0 +1,40 @@
+using JetBrains.Annotations;
+
+using Xunit.Abstractions;
+
+namespace Frank.Testing.Tests;
+
+[TestSubject(typeof(TestOutputXmlExtensions))]
+public class TestOutputXmlExtensionsTests(ITestOutputHelper outputHelper)
+{
+ [Fact]
+ public void WriteXml_ShouldWriteXmlOutput_WhenSourceIsSimpleObject()
+ {
+ var source = new TestPerson { Name = "John Doe", Age = 30 };
+
+ outputHelper.WriteXml(source);
+ }
+
+ [Fact]
+ public void WriteXml_ShouldWriteXmlOutput_WhenSourceIsNestedObject()
+ {
+ var source = new TestPerson() { Name = "John Doe", Age = 30, Address = new TestAddress() { City = "Main City", ZipCode = 18846 } };
+ outputHelper.WriteXml(source);
+ }
+
+ [Fact]
+ public void WriteXml_ShouldHandleEmptyObjects()
+ {
+ var source = new TestPerson();
+
+ outputHelper.WriteXml(source);
+ }
+
+ [Fact]
+ public void WriteXml_ShouldHandleNullObjects()
+ {
+ object? source = null;
+
+ outputHelper.WriteXml(source);
+ }
+}
\ No newline at end of file
diff --git a/Frank.Testing.Tests/TestingInfrastructure/TestAddress.cs b/Frank.Testing.Tests/TestingInfrastructure/TestAddress.cs
new file mode 100644
index 0000000..3208c74
--- /dev/null
+++ b/Frank.Testing.Tests/TestingInfrastructure/TestAddress.cs
@@ -0,0 +1,8 @@
+namespace Frank.Testing.Tests;
+
+public class TestAddress
+{
+ public string City { get; set; }
+
+ public int ZipCode { get; set; }
+}
\ No newline at end of file
diff --git a/Frank.Testing.Tests/TestingInfrastructure/TestPerson.cs b/Frank.Testing.Tests/TestingInfrastructure/TestPerson.cs
new file mode 100644
index 0000000..b0ad391
--- /dev/null
+++ b/Frank.Testing.Tests/TestingInfrastructure/TestPerson.cs
@@ -0,0 +1,9 @@
+namespace Frank.Testing.Tests;
+
+public class TestPerson
+{
+ public string Name { get; set; }
+ public int Age { get; set; }
+
+ public TestAddress? Address { get; set; }
+}
\ No newline at end of file
diff --git a/README.md b/README.md
index f3f108b..d7eeef0 100644
--- a/README.md
+++ b/README.md
@@ -50,7 +50,20 @@ public class MyTestClass
[Fact]
public void MyTestMethod()
{
- _outputHelper.WriteLine(new { MyProperty = "MyValue" });
+ _outputHelper.WriteLine(new { MyProperty = "MyValue" }); // Writes to test output as JSON: {"MyProperty":"MyValue"}
+ _outputHelper.WriteJson(new { MyProperty = "MyValue" }); // Writes to test output as JSON: {"MyProperty":"MyValue"}
+ }
+
+ [Fact]
+ public void MyTestMethod2()
+ {
+ _outputHelper.WriteCSharp(new { MyProperty = "MyValue" }); // Writes to test output as C#: var anonymousType = new { MyProperty = "MyValue" };
+ }
+
+ [Fact]
+ public void MyTestMethod3()
+ {
+ _outputHelper.WriteXml(new MyClass() { Name = "MyName" }); // Writes to test output as XML: MyName
}
}
```