Skip to content

Add an option to include exception messages in Microsoft.Testing.Extensions.JUnitReport failure bodies for GitLab compatibility. #10269

Description

@picolino

Summary

Add an option to Microsoft.Testing.Extensions.JUnitReport that includes the exception or assertion message in the text content of the JUnit <failure> or <error> element, rather than storing it only in the message attribute.

This is needed for proper failure diagnostics in GitLab test reports.

Background and Motivation

I am using Microsoft Testing Platform together with Microsoft.Testing.Extensions.JUnitReport to publish .NET test results to GitLab CI.

When a test fails, the generated JUnit report contains the exception or assertion message in the message attribute of the <failure> element, while the element body contains only the stack trace.

For example:

<failure
    message="Expected the operation not to throw, but it threw System.InvalidOperationException: The expected condition was not met."
    type="Xunit.Sdk.XunitException">
  at FluentAssertions.Execution.LateBoundTestFramework.Throw(String message)
  at FluentAssertions.Execution.TestFrameworkProvider.Throw(String message)
  at FluentAssertions.Execution.DefaultAssertionStrategy.HandleFailure(String message)
  ...
</failure>

GitLab displays the text content of <failure> as the test's System output, but it does not display the message attribute in the test summary UI.

As a result, the GitLab test report shows only the stack trace:

at FluentAssertions.Execution.LateBoundTestFramework.Throw(String message)
at FluentAssertions.Execution.TestFrameworkProvider.Throw(String message)
at FluentAssertions.Execution.DefaultAssertionStrategy.HandleFailure(String message)
...

The most important diagnostic information - the actual exception or assertion message - is missing.

This is especially problematic for assertion libraries such as FluentAssertions, where the stack trace is often generic and the assertion message contains the actual reason for the failure.

Other JUnit reporters address this compatibility issue by supporting a verbose failure-body mode that writes both the message and the stack trace into the <failure> element body, like such: https://github.com/spekt/testlogger/blob/master/src/JUnit.Xml.Package/README.md#failurebodyformat

Proposed Feature

Add a configuration option to Microsoft.Testing.Extensions.JUnitReport that controls the content written into the body of <failure> and <error> elements.

For example:

--report-junit-failure-body-format

Possible values could be:

  • StackTrace — current behavior;
  • Message;
  • MessageAndStackTrace.

Alternatively, the option could be named similarly to existing JUnit reporters:

--report-junit-failure-body-format verbose

With the proposed verbose behavior, the generated XML would look like this:

<failure
    message="Expected the operation not to throw, but it threw System.InvalidOperationException: The expected condition was not met."
    type="Xunit.Sdk.XunitException">
Expected the operation not to throw, but it threw System.InvalidOperationException: The expected condition was not met.

at FluentAssertions.Execution.LateBoundTestFramework.Throw(String message)
at FluentAssertions.Execution.TestFrameworkProvider.Throw(String message)
at FluentAssertions.Execution.DefaultAssertionStrategy.HandleFailure(String message)
...
</failure>

The message attribute should remain for compatibility with JUnit consumers that read it directly.

The same value should also be included in the element body so that systems such as GitLab can display meaningful failure details.

Alternative Designs

Always include the message in the element body

Instead of introducing a new option, the reporter could always write both the exception message and the stack trace into the <failure> or <error> body.

This would provide the best compatibility with GitLab and similar JUnit consumers, but it would change the current output and could duplicate the message in tools that already display the message attribute.

GitLab-specific post-processing

A CI pipeline can modify the generated XML before publishing it and prepend the message attribute to the <failure> body.

For example:

<failure message="Assertion message">
Assertion message

Stack trace...
</failure>

This works as a workaround, but every project using Microsoft Testing Platform with GitLab must maintain its own XML transformation script.

It also makes the pipeline more complex and introduces an additional processing step that should ideally be handled by the report generator.

Generate TRX and convert it to JUnit

Another option is to generate a TRX report and convert it to a GitLab-compatible JUnit report using a separate tool.

This adds another dependency and report conversion stage, and it defeats the purpose of using the official JUnit report extension directly.

Rely on GitLab to display the message attribute

GitLab could potentially change its JUnit parser or test report UI to display the message attribute.

However, including the message in the failure body is already a commonly supported compatibility approach and would improve interoperability with other JUnit consumers as well, not only GitLab.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/mtp-extensionsMTP extensions (TrxReport, Retry, HtmlReport, ...).

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions