Skip to content

Commit c731eb5

Browse files
committed
Add support for NUnitV3 content inside TouchUnit result files.
* Add a new TouchUnit_NUnitV3 xml result jargon. * Refactor the TouchUnit test report generator to call into the NUnitV2 or NUnitV3 test report generators depending on the embedded content. * Simplify the NUnitV3 test report generator to just look for 'test-case' elements, not caring about any parent nodes. * Make the NUnitV3 test report print the full name of failing tests, not just the name.
1 parent f023631 commit c731eb5

File tree

8 files changed

+14364
-86
lines changed

8 files changed

+14364
-86
lines changed

src/Microsoft.DotNet.XHarness.Common/XmlResultJargon.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ namespace Microsoft.DotNet.XHarness.Common;
66
public enum XmlResultJargon
77
{
88
TouchUnit,
9+
TouchUnit_NUnitV2 = TouchUnit,
10+
TouchUnit_NUnitV3,
911
NUnitV2,
1012
NUnitV3,
1113
xUnit,

src/Microsoft.DotNet.XHarness.iOS.Shared/XmlResults/NUnitV2TestReportGenerator.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,12 @@ public class NUnitV2TestReportGenerator : TestReportGenerator
1414
{
1515
public override void GenerateTestReport(TextWriter writer, XmlReader reader)
1616
{
17-
if (!reader.ReadToFollowing("test-results"))
17+
if (reader.Name != "test-results")
1818
{
19-
return;
19+
if (!reader.ReadToFollowing("test-results"))
20+
{
21+
return;
22+
}
2023
}
2124

2225
long.TryParse(reader["errors"], out var errors);

src/Microsoft.DotNet.XHarness.iOS.Shared/XmlResults/NUnitV3TestReportGenerator.cs

Lines changed: 12 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -16,42 +16,21 @@ public class NUnitV3TestReportGenerator : TestReportGenerator
1616
public override void GenerateTestReport(TextWriter writer, XmlReader reader)
1717
{
1818
var failedTests = new List<(string name, string message)>();
19-
while (reader.Read())
19+
20+
while (reader.ReadToFollowing("test-case"))
2021
{
21-
if (reader.NodeType == XmlNodeType.Element && reader.Name == "test-run")
22+
var status = reader["result"];
23+
switch (status)
2224
{
23-
long.TryParse(reader["failed"], out var failed);
24-
if (failed == 0)
25-
{
25+
case "Error":
26+
case "Failed":
27+
string name = reader["fullname"] ?? throw new InvalidOperationException();
28+
var subtree = reader.ReadSubtree();
29+
subtree.ReadToDescendant("message");
30+
string message = subtree.ReadElementContentAsString();
31+
while (subtree.Read()) { } // read to end of subtree
32+
failedTests.Add((name, message));
2633
break;
27-
}
28-
}
29-
30-
if (reader.NodeType == XmlNodeType.Element && reader.Name == "test-suite" && (reader["type"] == "TestFixture" || reader["type"] == "ParameterizedFixture"))
31-
{
32-
reader.ReadToDescendant("test-case");
33-
do
34-
{
35-
if (reader.Name != "test-case")
36-
{
37-
break;
38-
}
39-
// read the test cases in the current node
40-
var status = reader["result"];
41-
switch (status)
42-
{
43-
case "Error":
44-
case "Failed":
45-
string name = reader["name"] ?? throw new InvalidOperationException();
46-
var subtree = reader.ReadSubtree();
47-
subtree.ReadToDescendant("message");
48-
string message = subtree.ReadElementContentAsString();
49-
while (subtree.Read()) { } // read to end of subtree
50-
failedTests.Add((name, message));
51-
break;
52-
53-
}
54-
} while (reader.ReadToNextSibling("test-case"));
5534
}
5635
}
5736

src/Microsoft.DotNet.XHarness.iOS.Shared/XmlResults/TouchUnitTestReportGenerator.cs

Lines changed: 10 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33
// See the LICENSE file in the project root for more information.
44

5+
using System;
56
using System.IO;
67
using System.Xml;
78
using Microsoft.DotNet.XHarness.iOS.Shared.Utilities;
@@ -20,57 +21,24 @@ public override void GenerateTestReport(TextWriter writer, XmlReader reader)
2021
{
2122
while (reader.Read())
2223
{
23-
24-
if (reader.NodeType != XmlNodeType.Element || reader.Name != "test-suite" || reader["type"] != "TestFixture" && reader["type"] != "TestCollection")
24+
if (reader.NodeType != XmlNodeType.Element)
2525
{
2626
continue;
2727
}
2828

29-
long.TryParse(reader["errors"], out var errors);
30-
long.TryParse(reader["failed"], out var failed);
31-
32-
// if we do not have any errors, return, nothing to be written here
33-
if (errors == 0 && failed == 0)
29+
if (reader.Name == "test-run")
3430
{
31+
var innerReader = new NUnitV3TestReportGenerator();
32+
innerReader.GenerateTestReport(writer, reader);
3533
return;
3634
}
3735

38-
writer.WriteLine("<div style='padding-left: 15px;'>");
39-
writer.WriteLine("<ul>");
40-
41-
reader.ReadToDescendant("test-case");
42-
do
36+
if (reader.Name == "test-results")
4337
{
44-
if (reader.Name != "test-case")
45-
{
46-
break;
47-
}
48-
49-
// read the test cases in the current node
50-
var status = reader["result"];
51-
switch (status)
52-
{ // only interested in errors
53-
case "Error":
54-
case "Failure":
55-
writer.WriteLine("<li>");
56-
var test_name = reader["name"];
57-
writer.Write(test_name.AsHtml());
58-
// read to the message of the error and get it
59-
reader.ReadToDescendant("message");
60-
var message = reader.ReadElementContentAsString();
61-
if (!string.IsNullOrEmpty(message))
62-
{
63-
writer.Write(": ");
64-
writer.Write(message.AsHtml());
65-
}
66-
writer.WriteLine("<br />");
67-
writer.WriteLine("</li>");
68-
break;
69-
}
70-
} while (reader.ReadToNextSibling("test-case"));
71-
72-
writer.WriteLine("</ul>");
73-
writer.WriteLine("</div>");
38+
var innerReader = new NUnitV2TestReportGenerator();
39+
innerReader.GenerateTestReport(writer, reader);
40+
return;
41+
}
7442
}
7543
}
7644
}

src/Microsoft.DotNet.XHarness.iOS.Shared/XmlResults/XmlResultParser.cs

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ public class XmlResultParser : IResultParser
2020
private static readonly IHelpers s_helpers = new Helpers();
2121
private readonly Dictionary<XmlResultJargon, (IXmlResultParser Parser, ITestReportGenerator Generator)> _xmlFormatters = new()
2222
{
23-
{ XmlResultJargon.TouchUnit, (new TouchUnitResultParser(), new TouchUnitTestReportGenerator()) },
23+
{ XmlResultJargon.TouchUnit_NUnitV2, (new TouchUnitResultParser(), new TouchUnitTestReportGenerator()) },
24+
{ XmlResultJargon.TouchUnit_NUnitV3, (new TouchUnitResultParser(), new TouchUnitTestReportGenerator()) },
2425
{ XmlResultJargon.NUnitV2, (new NUnitV2ResultParser(), new NUnitV2TestReportGenerator()) },
2526
{ XmlResultJargon.NUnitV3, (new NUnitV3ResultParser(), new NUnitV3TestReportGenerator()) },
2627
{ XmlResultJargon.Trx, (new TrxResultParser(), new TrxTestReportGenerator()) },
@@ -60,8 +61,19 @@ public bool IsValidXml(TextReader stream, out XmlResultJargon type)
6061
}
6162
if (line.Contains("TouchUnitTestRun"))
6263
{
63-
type = XmlResultJargon.TouchUnit;
64-
return true;
64+
while ((line = stream.ReadLine()) != null) {
65+
if (line.Contains("test-run"))
66+
{
67+
type = XmlResultJargon.TouchUnit_NUnitV3;
68+
return true;
69+
}
70+
if (line.Contains("test-results"))
71+
{
72+
type = XmlResultJargon.TouchUnit_NUnitV2;
73+
return true;
74+
}
75+
}
76+
return false;
6577
}
6678
if (line.Contains("test-results"))
6779
{ // first element of the NUnitV3 test collection
@@ -88,7 +100,8 @@ public string GetXmlFilePath(string path, XmlResultJargon xmlType)
88100
var fileName = Path.GetFileName(path);
89101
switch (xmlType)
90102
{
91-
case XmlResultJargon.TouchUnit:
103+
case XmlResultJargon.TouchUnit_NUnitV2:
104+
case XmlResultJargon.TouchUnit_NUnitV3:
92105
case XmlResultJargon.NUnitV2:
93106
case XmlResultJargon.NUnitV3:
94107
return path.Replace(fileName, $"nunit-{fileName}");

tests/Microsoft.DotNet.XHarness.iOS.Shared.Tests/Microsoft.DotNet.XHarness.iOS.Shared.Tests.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
<None Remove="Samples\simulators.xml" />
3030
<None Remove="Samples\TestCaseFailures.xml" />
3131
<None Remove="Samples\TouchUnitSample.xml" />
32+
<None Remove="Samples\TouchUnitSample2.xml" />
3233
<None Remove="Samples\xUnitSample.xml" />
3334
<None Remove="Samples\Issue95.xml" />
3435
</ItemGroup>
@@ -50,6 +51,7 @@
5051
<EmbeddedResource Include="Samples\simulators.xml" />
5152
<EmbeddedResource Include="Samples\TestCaseFailures.xml" />
5253
<EmbeddedResource Include="Samples\TouchUnitSample.xml" />
54+
<EmbeddedResource Include="Samples\TouchUnitSample2.xml" />
5355
<EmbeddedResource Include="Samples\xUnitSample.xml" />
5456
<EmbeddedResource Include="Samples\Issue95.xml" />
5557
</ItemGroup>

0 commit comments

Comments
 (0)