Skip to content

Commit 2e87c1b

Browse files
authored
Trx Parsing Improvements (#595)
1 parent bb1cc09 commit 2e87c1b

File tree

12 files changed

+120
-59
lines changed

12 files changed

+120
-59
lines changed

.idea/.idea.ModularPipelines/.idea/.name

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
- The namespace for the TrxParser has changed
2+
- The TrxParser now parses the ResultSummary tag
Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
using ModularPipelines.DotNet.Enums;
2-
using ModularPipelines.DotNet.Parsers.NUnitTrx;
1+
using ModularPipelines.DotNet.Parsers.Trx;
32

43
namespace ModularPipelines.DotNet;
54

6-
public record DotNetTestResult(IReadOnlyList<UnitTestResult> UnitTestResults)
5+
public record DotNetTestResult(IReadOnlyList<UnitTestResult> UnitTestResults, ResultSummary ResultSummary)
76
{
8-
public bool Successful => UnitTestResults.All(x => x.Outcome != TestOutcome.Failed);
7+
public bool Successful => ResultSummary.Outcome is "Passed" or "Completed";
98
}

src/ModularPipelines.DotNet/Extensions/DotNetExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
using Microsoft.Extensions.DependencyInjection;
44
using Microsoft.Extensions.DependencyInjection.Extensions;
55
using ModularPipelines.Context;
6-
using ModularPipelines.DotNet.Parsers.NUnitTrx;
6+
using ModularPipelines.DotNet.Parsers.Trx;
77
using ModularPipelines.DotNet.Services;
88
using ModularPipelines.Engine;
99

src/ModularPipelines.DotNet/Parsers/NUnitTrx/TrxParser.cs

Lines changed: 0 additions & 49 deletions
This file was deleted.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
namespace ModularPipelines.DotNet.Parsers.Trx;
2+
3+
public record Counters(
4+
int Total,
5+
int Executed,
6+
int Passed,
7+
int Failed,
8+
int Error,
9+
int Timeout,
10+
int Aborted,
11+
int Inconclusive,
12+
int PassedButRunAborted,
13+
int NotRunnable,
14+
int NotExecuted,
15+
int Disconnected,
16+
int Warning,
17+
int Completed,
18+
int InProgress,
19+
int Pending);
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
namespace ModularPipelines.DotNet.Parsers.Trx;
2+
3+
public record ResultSummary(string Outcome, Counters Counters);

src/ModularPipelines.DotNet/Parsers/NUnitTrx/TestOutput.cs renamed to src/ModularPipelines.DotNet/Parsers/Trx/TestOutput.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
using System.Diagnostics.CodeAnalysis;
22
using System.Xml.Serialization;
33

4-
namespace ModularPipelines.DotNet.Parsers.NUnitTrx;
4+
namespace ModularPipelines.DotNet.Parsers.Trx;
55

66
[XmlRoot(ElementName = "Output")]
77
[ExcludeFromCodeCoverage]
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
using System.Xml.Linq;
2+
using ModularPipelines.DotNet.Enums;
3+
4+
namespace ModularPipelines.DotNet.Parsers.Trx;
5+
6+
public class TrxParser : ITrxParser
7+
{
8+
public DotNetTestResult ParseTrxContents(string input)
9+
{
10+
var xDocument = XDocument.Load(new StringReader(input));
11+
return new DotNetTestResult(GetUnitTestResults(xDocument), GetResultSummary(xDocument));
12+
}
13+
14+
private ResultSummary GetResultSummary(XDocument document)
15+
{
16+
return ParseResultSummary(document
17+
.Descendants()
18+
.First(e => e.Name.LocalName == "ResultSummary"));
19+
}
20+
21+
private ResultSummary ParseResultSummary(XElement element)
22+
{
23+
var outcome = element.Attribute("outcome")!.Value;
24+
25+
var counters = ParseCounters(element.Descendants().First(e => e.Name.LocalName == "Counters"));
26+
27+
return new ResultSummary(outcome, counters);
28+
}
29+
30+
private Counters ParseCounters(XElement element)
31+
{
32+
return new Counters(
33+
int.Parse(element.Attribute("total")!.Value),
34+
int.Parse(element.Attribute("executed")!.Value),
35+
int.Parse(element.Attribute("passed")!.Value),
36+
int.Parse(element.Attribute("failed")!.Value),
37+
int.Parse(element.Attribute("error")!.Value),
38+
int.Parse(element.Attribute("timeout")!.Value),
39+
int.Parse(element.Attribute("aborted")!.Value),
40+
int.Parse(element.Attribute("inconclusive")!.Value),
41+
int.Parse(element.Attribute("passedButRunAborted")!.Value),
42+
int.Parse(element.Attribute("notRunnable")!.Value),
43+
int.Parse(element.Attribute("notExecuted")!.Value),
44+
int.Parse(element.Attribute("disconnected")!.Value),
45+
int.Parse(element.Attribute("warning")!.Value),
46+
int.Parse(element.Attribute("completed")!.Value),
47+
int.Parse(element.Attribute("inProgress")!.Value),
48+
int.Parse(element.Attribute("pending")!.Value)
49+
);
50+
}
51+
52+
private List<UnitTestResult> GetUnitTestResults(XDocument xDocument)
53+
{
54+
return xDocument.Descendants()
55+
.Where(d => d.Name.LocalName == "UnitTestResult")
56+
.Select(ParseUnitTestResult)
57+
.ToList();
58+
}
59+
60+
private UnitTestResult ParseUnitTestResult(XElement element)
61+
{
62+
var errorInfo = element.Descendants().FirstOrDefault(x => x.Name.LocalName == "ErrorInfo");
63+
64+
return new UnitTestResult
65+
{
66+
ExecutionId = element.Attribute("executionId")!.Value,
67+
TestId = element.Attribute("testId")!.Value,
68+
TestName = element.Attribute("testName")!.Value,
69+
ComputerName = element.Attribute("computerName")!.Value,
70+
Duration = TimeSpan.Parse(element.Attribute("duration")!.Value),
71+
StartTime = DateTimeOffset.Parse(element.Attribute("startTime")!.Value),
72+
EndTime = DateTimeOffset.Parse(element.Attribute("endTime")!.Value),
73+
TestType = element.Attribute("testType")!.Value,
74+
Outcome = Enum.Parse<TestOutcome>(element.Attribute("outcome")!.Value),
75+
TestListId = element.Attribute("testListId")!.Value,
76+
RelativeResultsDirectory = element.Attribute("relativeResultsDirectory")!.Value,
77+
Output = new TestOutput
78+
{
79+
StdOut = element.Descendants().FirstOrDefault(x => x.Name.LocalName == "StdOut")?.Value,
80+
ErrorInfo = errorInfo == null ? null : new ErrorInfo
81+
{
82+
Message = errorInfo.Descendants().FirstOrDefault(x => x.Name.LocalName == "Message")?.Value,
83+
StackTrace = errorInfo.Descendants().FirstOrDefault(x => x.Name.LocalName == "StackTrace")?.Value,
84+
},
85+
},
86+
};
87+
}
88+
}

src/ModularPipelines.DotNet/Parsers/NUnitTrx/UnitTestResult.cs renamed to src/ModularPipelines.DotNet/Parsers/Trx/UnitTestResult.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
using System.Xml.Serialization;
33
using ModularPipelines.DotNet.Enums;
44

5-
namespace ModularPipelines.DotNet.Parsers.NUnitTrx;
5+
namespace ModularPipelines.DotNet.Parsers.Trx;
66

77
[Serializable]
88
[XmlRoot(ElementName = "UnitTestResult")]

test/ModularPipelines.UnitTests/Helpers/DotNetTestResultsTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
using ModularPipelines.Context;
22
using ModularPipelines.DotNet.Extensions;
33
using ModularPipelines.DotNet.Options;
4-
using ModularPipelines.DotNet.Parsers.NUnitTrx;
4+
using ModularPipelines.DotNet.Parsers.Trx;
55
using ModularPipelines.Enums;
66
using ModularPipelines.Exceptions;
77
using ModularPipelines.Git.Extensions;

test/ModularPipelines.UnitTests/TrxParsingTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
using ModularPipelines.DotNet.Enums;
44
using ModularPipelines.DotNet.Extensions;
55
using ModularPipelines.DotNet.Options;
6-
using ModularPipelines.DotNet.Parsers.NUnitTrx;
6+
using ModularPipelines.DotNet.Parsers.Trx;
77
using ModularPipelines.Enums;
88
using ModularPipelines.Git.Extensions;
99
using ModularPipelines.Modules;

0 commit comments

Comments
 (0)