Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
4d0a78f
feat: AOT compliance with multi-targeting (netstandard2.1 + net8.0 + …
BenjaminMichaelis May 17, 2026
5a86342
Bump actions/upload-artifact from 6 to 7 (#27)
dependabot[bot] May 17, 2026
0419ec4
fix: Workflow does not contain permissions (#44)
BenjaminMichaelis May 17, 2026
4a602bc
Add failing regression tests for bugs A, C, D
BenjaminMichaelis May 17, 2026
4fe94d7
Fix bugs A, C, D in TrxParser
BenjaminMichaelis May 17, 2026
87590e9
Clean up regression test comments
BenjaminMichaelis May 17, 2026
db5dcb9
Make publish-layout test OS-agnostic
BenjaminMichaelis May 17, 2026
aca78cf
Merge origin/main into branch
BenjaminMichaelis May 17, 2026
7669530
Address PR review feedback
BenjaminMichaelis May 17, 2026
31756cd
Merge origin/main into branch
BenjaminMichaelis May 17, 2026
d92c641
Restore main-branch outcome mapping rationale comment
BenjaminMichaelis May 17, 2026
28fd82b
Align TrxParser style with main patterns
BenjaminMichaelis May 17, 2026
c06a5bb
Replace synthetic aborted fixture with real TRX capture
BenjaminMichaelis May 17, 2026
182452e
Add repository instructions for real TRX fixtures
BenjaminMichaelis May 17, 2026
ff90059
convert TRX fixture policy from instruction file to skill file
Copilot May 17, 2026
04500cf
Rename skill to 'writing-test' and update description
BenjaminMichaelis May 17, 2026
4d6446e
Rename skill from 'writing-test' to 'test-writing'
BenjaminMichaelis May 17, 2026
08f81ba
Replace synthetic no-namespace.trx with real capture; remove publishe…
BenjaminMichaelis May 17, 2026
eb82c3e
Merge remote-tracking branch 'origin/benjaminmichaelis/trex-trxlib-bu…
BenjaminMichaelis May 17, 2026
f491c0e
Remove unproven publish-path fallback from FindProjectDirectory
BenjaminMichaelis May 17, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .github/skills/test-writing/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
name: test-writing
description: Use this skill when writing tests.
---

# TRX fixture policy for tests

When adding or updating sample `.trx` files in this repository, use **real captured TRX output**, not synthetic hand-written fixtures.

Required workflow:

1. Create temporary tests that trigger the condition you need in the TRX.
2. Run `dotnet test` with TRX output enabled to generate a real file.
3. Copy that generated TRX file into `TrxLib.Tests/SampleTrxFiles/` (renaming is fine).
4. Remove high-level personal/environment PII from the file (for example: username, machine name, local workspace paths), while preserving the TRX structure and semantics needed by tests.

Do not fabricate TRX XML by hand when a real capture is possible.
55 changes: 55 additions & 0 deletions TrxLib.Tests/SampleTrxFiles/aborted-outcome.trx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="utf-8"?>
<TestRun id="6ee07f75-fb7c-472a-826e-76d151e1c033" name="sample@MACHINE 2026-05-17 00:09:42" runUser="MACHINE\sample" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
<Times creation="2026-05-17T00:09:42.6672639-07:00" queuing="2026-05-17T00:09:42.6672644-07:00" start="2026-05-17T00:09:40.1879713-07:00" finish="2026-05-17T00:09:48.5593250-07:00" />
<TestSettings name="default" id="d5a33f7a-7488-410e-8195-3807f855af12">
<Deployment runDeploymentRoot="sample_MACHINE_2026-05-17_00_09_42" />
</TestSettings>
<Results>
<UnitTestResult executionId="2c44a0e5-0c78-4d78-9665-aa45a6d98f3f" testId="8a01445b-23e6-f125-1b18-0fa67670c70d" testName="TrxAbortGen.UnitTest1.FastTest" computerName="MACHINE" duration="00:00:00.0054353" startTime="2026-05-17T00:09:41.3979349-07:00" endTime="2026-05-17T00:09:41.3999615-07:00" testType="13cdc9d9-ddb5-4fa4-a97d-d965ccfc6d4b" outcome="Passed" testListId="8c84fa94-04c1-424b-9868-57a2d4851a1d" relativeResultsDirectory="2c44a0e5-0c78-4d78-9665-aa45a6d98f3f" />
</Results>
<TestDefinitions>
<UnitTest name="TrxAbortGen.UnitTest1.FastTest" storage="d:\sample\trxabortgen\bin\debug\net10.0\trxabortgen.dll" id="8a01445b-23e6-f125-1b18-0fa67670c70d">
<Execution id="2c44a0e5-0c78-4d78-9665-aa45a6d98f3f" />
<TestMethod codeBase="D:\sample\TrxAbortGen\bin\Debug\net10.0\TrxAbortGen.dll" adapterTypeName="executor://xunit/VsTestRunner3/netcore/" className="TrxAbortGen.UnitTest1" name="FastTest" />
</UnitTest>
</TestDefinitions>
<TestEntries>
<TestEntry testId="8a01445b-23e6-f125-1b18-0fa67670c70d" executionId="2c44a0e5-0c78-4d78-9665-aa45a6d98f3f" testListId="8c84fa94-04c1-424b-9868-57a2d4851a1d" />
</TestEntries>
<TestLists>
<TestList name="Results Not in a List" id="8c84fa94-04c1-424b-9868-57a2d4851a1d" />
<TestList name="All Loaded Results" id="19431567-8539-422a-85d7-44ee4e166bda" />
</TestLists>
<ResultSummary outcome="Failed">
<Counters total="1" executed="1" passed="1" failed="0" error="0" timeout="0" aborted="0" inconclusive="0" passedButRunAborted="0" notRunnable="0" notExecuted="0" disconnected="0" warning="0" completed="0" inProgress="0" pending="0" />
<Output>
<StdOut>[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v3.1.5+1b188a7b0a (64-bit .NET 10.0.8)&#xD;
[xUnit.net 00:00:00.08] Discovering: TrxAbortGen&#xD;
[xUnit.net 00:00:00.12] Discovered: TrxAbortGen&#xD;
[xUnit.net 00:00:00.14] Starting: TrxAbortGen&#xD;
[createdump] Writing full dump for process 120264 to file C:\Temp\sample\testhost_120264_20260517T000946_hangdump.dmp&#xD;
[createdump] Dump successfully written in 1772ms&#xD;
</StdOut>
</Output>
<RunInfos>
<RunInfo computerName="MACHINE" outcome="Error" timestamp="2026-05-17T00:09:48.4883900-07:00">
<Text>The active test run was aborted. Reason: Test host process crashed</Text>
</RunInfo>
<RunInfo computerName="MACHINE" outcome="Warning" timestamp="2026-05-17T00:09:48.5003562-07:00">
<Text>Data collector 'Blame' message: The specified inactivity time of 5 seconds has elapsed. Collecting hang dumps from testhost and its child processes.</Text>
</RunInfo>
</RunInfos>
<CollectorDataEntries>
<Collector agentName="MACHINE" uri="datacollector://microsoft/TestPlatform/Extensions/Blame/v1" collectorDisplayName="Blame">
<UriAttachments>
<UriAttachment>
<A href="MACHINE\testhost_120264_20260517T000946_hangdump.dmp"></A>
</UriAttachment>
<UriAttachment>
<A href="MACHINE\Sequence_e25cc2d916314e8d81015e2757d19f02.xml"></A>
</UriAttachment>
</UriAttachments>
</Collector>
</CollectorDataEntries>
</ResultSummary>
</TestRun>
69 changes: 69 additions & 0 deletions TrxLib.Tests/SampleTrxFiles/no-namespace.trx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?xml version="1.0" encoding="utf-8"?>
<TestRun id="b3f18c99-bcc6-465c-ba06-89825f441354" name="Utilizador@DESKTOP-PD528C3 2023-02-16 00:10:37" runUser="DESKTOP-PD528C3\Utilizador">
<Times creation="2023-02-16T00:10:37.0214256+00:00" queuing="2023-02-16T00:10:37.0214261+00:00" start="2023-02-16T00:10:36.0671216+00:00" finish="2023-02-16T00:10:37.0314500+00:00" />
<TestSettings name="default" id="202caf66-acc1-4c86-87c9-1e31b7b3ab0d">
<Deployment runDeploymentRoot="Utilizador_DESKTOP-PD528C3_2023-02-16_00_10_37" />
</TestSettings>
<Results>
<UnitTestResult executionId="55a45cd9-9f9a-4ee9-8df6-1135a7d047c0" testId="9e25854f-e30c-f2db-49d5-285adb0e9913" testName="SimpleNumberCompare(3,3)" computerName="DESKTOP-PD528C3" duration="00:00:00.0000100" startTime="2023-02-16T00:10:36.8483455+00:00" endTime="2023-02-16T00:10:36.8483552+00:00" testType="13cdc9d9-ddb5-4fa4-a97d-d965ccfc6d4b" outcome="Passed" testListId="8c84fa94-04c1-424b-9868-57a2d4851a1d" relativeResultsDirectory="55a45cd9-9f9a-4ee9-8df6-1135a7d047c0" />
<UnitTestResult executionId="1236f351-4887-4017-807c-1175b5cd36be" testId="f2de63e1-a2e1-134a-f0aa-aa4933f801df" testName="SimpleNumberCompare(2,2)" computerName="DESKTOP-PD528C3" duration="00:00:00.0001200" startTime="2023-02-16T00:10:36.8482138+00:00" endTime="2023-02-16T00:10:36.8483346+00:00" testType="13cdc9d9-ddb5-4fa4-a97d-d965ccfc6d4b" outcome="Passed" testListId="8c84fa94-04c1-424b-9868-57a2d4851a1d" relativeResultsDirectory="1236f351-4887-4017-807c-1175b5cd36be" />
<UnitTestResult executionId="73df5f45-aa3f-4cb4-8c4c-c8e702b53eb3" testId="bf3170b6-b1fd-cc8b-daa7-315dac1f80cc" testName="SimpleNumberCompare(4,4)" computerName="DESKTOP-PD528C3" duration="00:00:00.0000120" startTime="2023-02-16T00:10:36.8483593+00:00" endTime="2023-02-16T00:10:36.8483708+00:00" testType="13cdc9d9-ddb5-4fa4-a97d-d965ccfc6d4b" outcome="Passed" testListId="8c84fa94-04c1-424b-9868-57a2d4851a1d" relativeResultsDirectory="73df5f45-aa3f-4cb4-8c4c-c8e702b53eb3" />
<UnitTestResult executionId="6da6ef04-c861-456a-9228-67a8eaeb0dd6" testId="3ade358c-328b-c90b-7c97-c25ae8a92095" testName="SimpleStringCompare()" computerName="DESKTOP-PD528C3" duration="00:00:00.0362270" startTime="2023-02-16T00:10:36.8495258+00:00" endTime="2023-02-16T00:10:36.8857526+00:00" testType="13cdc9d9-ddb5-4fa4-a97d-d965ccfc6d4b" outcome="Failed" testListId="8c84fa94-04c1-424b-9868-57a2d4851a1d" relativeResultsDirectory="6da6ef04-c861-456a-9228-67a8eaeb0dd6">
<Output>
<ErrorInfo>
<Message> Expected string length 5 but was 7. Strings differ at index 5.
Expected: "value"
But was: "value 2"
----------------^
</Message>
<StackTrace> at NUnitTestExample.Tests.SimpleStringCompare() in C:\Users\Utilizador\RiderProjects\TestSolution\NUnitTestExample\SimpleTest.cs:line 17
</StackTrace>
</ErrorInfo>
</Output>
</UnitTestResult>
<UnitTestResult executionId="1926a0d8-a10a-49cb-9cc7-bc10b37e6125" testId="0a135621-0e2f-1240-b876-fb3dd56eadae" testName="SimpleNumberCompare(1,1)" computerName="DESKTOP-PD528C3" duration="00:00:00.0095590" startTime="2023-02-16T00:10:36.8360578+00:00" endTime="2023-02-16T00:10:36.8455393+00:00" testType="13cdc9d9-ddb5-4fa4-a97d-d965ccfc6d4b" outcome="Passed" testListId="8c84fa94-04c1-424b-9868-57a2d4851a1d" relativeResultsDirectory="1926a0d8-a10a-49cb-9cc7-bc10b37e6125" />
</Results>
<TestDefinitions>
<UnitTest name="SimpleNumberCompare(4,4)" storage="c:\users\utilizador\riderprojects\testsolution\nunittestexample\bin\debug\net6.0\nunittestexample.dll" id="bf3170b6-b1fd-cc8b-daa7-315dac1f80cc">
<Execution id="73df5f45-aa3f-4cb4-8c4c-c8e702b53eb3" />
<TestMethod codeBase="C:\Users\Utilizador\RiderProjects\TestSolution\NUnitTestExample\bin\Debug\net6.0\NUnitTestExample.dll" adapterTypeName="executor://nunit3testexecutor/" className="NUnitTestExample.Tests" name="SimpleNumberCompare(4,4)" />
</UnitTest>
<UnitTest name="SimpleNumberCompare(3,3)" storage="c:\users\utilizador\riderprojects\testsolution\nunittestexample\bin\debug\net6.0\nunittestexample.dll" id="9e25854f-e30c-f2db-49d5-285adb0e9913">
<Execution id="55a45cd9-9f9a-4ee9-8df6-1135a7d047c0" />
<TestMethod codeBase="C:\Users\Utilizador\RiderProjects\TestSolution\NUnitTestExample\bin\Debug\net6.0\NUnitTestExample.dll" adapterTypeName="executor://nunit3testexecutor/" className="NUnitTestExample.Tests" name="SimpleNumberCompare(3,3)" />
</UnitTest>
<UnitTest name="SimpleNumberCompare(2,2)" storage="c:\users\utilizador\riderprojects\testsolution\nunittestexample\bin\debug\net6.0\nunittestexample.dll" id="f2de63e1-a2e1-134a-f0aa-aa4933f801df">
<Execution id="1236f351-4887-4017-807c-1175b5cd36be" />
<TestMethod codeBase="C:\Users\Utilizador\RiderProjects\TestSolution\NUnitTestExample\bin\Debug\net6.0\NUnitTestExample.dll" adapterTypeName="executor://nunit3testexecutor/" className="NUnitTestExample.Tests" name="SimpleNumberCompare(2,2)" />
</UnitTest>
<UnitTest name="SimpleNumberCompare(1,1)" storage="c:\users\utilizador\riderprojects\testsolution\nunittestexample\bin\debug\net6.0\nunittestexample.dll" id="0a135621-0e2f-1240-b876-fb3dd56eadae">
<Execution id="1926a0d8-a10a-49cb-9cc7-bc10b37e6125" />
<TestMethod codeBase="C:\Users\Utilizador\RiderProjects\TestSolution\NUnitTestExample\bin\Debug\net6.0\NUnitTestExample.dll" adapterTypeName="executor://nunit3testexecutor/" className="NUnitTestExample.Tests" name="SimpleNumberCompare(1,1)" />
</UnitTest>
<UnitTest name="SimpleStringCompare()" storage="c:\users\utilizador\riderprojects\testsolution\nunittestexample\bin\debug\net6.0\nunittestexample.dll" id="3ade358c-328b-c90b-7c97-c25ae8a92095">
<Execution id="6da6ef04-c861-456a-9228-67a8eaeb0dd6" />
<TestMethod codeBase="C:\Users\Utilizador\RiderProjects\TestSolution\NUnitTestExample\bin\Debug\net6.0\NUnitTestExample.dll" adapterTypeName="executor://nunit3testexecutor/" className="NUnitTestExample.Tests" name="SimpleStringCompare()" />
</UnitTest>
</TestDefinitions>
<TestEntries>
<TestEntry testId="9e25854f-e30c-f2db-49d5-285adb0e9913" executionId="55a45cd9-9f9a-4ee9-8df6-1135a7d047c0" testListId="8c84fa94-04c1-424b-9868-57a2d4851a1d" />
<TestEntry testId="f2de63e1-a2e1-134a-f0aa-aa4933f801df" executionId="1236f351-4887-4017-807c-1175b5cd36be" testListId="8c84fa94-04c1-424b-9868-57a2d4851a1d" />
<TestEntry testId="bf3170b6-b1fd-cc8b-daa7-315dac1f80cc" executionId="73df5f45-aa3f-4cb4-8c4c-c8e702b53eb3" testListId="8c84fa94-04c1-424b-9868-57a2d4851a1d" />
<TestEntry testId="3ade358c-328b-c90b-7c97-c25ae8a92095" executionId="6da6ef04-c861-456a-9228-67a8eaeb0dd6" testListId="8c84fa94-04c1-424b-9868-57a2d4851a1d" />
<TestEntry testId="0a135621-0e2f-1240-b876-fb3dd56eadae" executionId="1926a0d8-a10a-49cb-9cc7-bc10b37e6125" testListId="8c84fa94-04c1-424b-9868-57a2d4851a1d" />
</TestEntries>
<TestLists>
<TestList name="Results Not in a List" id="8c84fa94-04c1-424b-9868-57a2d4851a1d" />
<TestList name="All Loaded Results" id="19431567-8539-422a-85d7-44ee4e166bda" />
</TestLists>
<ResultSummary outcome="Failed">
<Counters total="5" executed="5" passed="4" failed="1" error="0" timeout="0" aborted="0" inconclusive="0" passedButRunAborted="0" notRunnable="0" notExecuted="0" disconnected="0" warning="0" completed="0" inProgress="0" pending="0" />
<Output>
<StdOut>NUnit Adapter 4.2.0.0: Test execution started
Running all tests in C:\Users\Utilizador\RiderProjects\TestSolution\NUnitTestExample\bin\Debug\net6.0\NUnitTestExample.dll
NUnit3TestExecutor discovered 5 of 5 NUnit test cases using Current Discovery mode, Non-Explicit run
NUnit Adapter 4.2.0.0: Test execution complete
</StdOut>
</Output>
</ResultSummary>
</TestRun>
21 changes: 21 additions & 0 deletions TrxLib.Tests/TrxParserTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,27 @@ public void Parse_Example2WindowsTrx_TestsDoNotAppearWithMoreThanOneOutcome()
results.Count.Should().Be(recombinedCount);
}

// ── Regression tests ─────────────────────────────────────────────────────────

[Fact]
public void Parse_AbortedRunTrx_ParsesRealAbortedRunFixture()
{
var results = TrxParser.Parse(new FileInfo(GetSampleFilePath("aborted-outcome.trx")));
results.Should().HaveCount(1);
results.Single().Outcome.Should().Be(TestOutcome.Passed);
results.OriginalTestRun?.ResultSummary?.Outcome.Should().Be("Failed");
}

// Real NUnit TRX captured without xmlns on the root element, sourced from:
// https://github.com/joaoopereira/dotnet-test-rerun/blob/main/test/dotnet-test-rerun.UnitTests/Fixtures/RerunCommand/NUnitTrxFileWithOneFailedTest.trx
[Fact]
public void Parse_NoNamespaceTrx_ParsesResultsWithoutNamespace()
{
var results = TrxParser.Parse(new FileInfo(GetSampleFilePath("no-namespace.trx")));
results.Should().HaveCount(5,
"the parser must fall back to namespace-agnostic element matching when xmlns is absent");
}

[Fact]
public void Parse_ComplexTrx_ParsesTestRunNameCorrectly()
{
Expand Down
Loading
Loading