Skip to content

feat(junit-reporter): add jest-junit-compatible naming options#10189

Merged
sheremet-va merged 7 commits intovitest-dev:mainfrom
neumaennl:copilot/add-junit-naming-parity
Apr 29, 2026
Merged

feat(junit-reporter): add jest-junit-compatible naming options#10189
sheremet-va merged 7 commits intovitest-dev:mainfrom
neumaennl:copilot/add-junit-naming-parity

Conversation

@neumaennl
Copy link
Copy Markdown
Contributor

@neumaennl neumaennl commented Apr 24, 2026

Problem

Vitest's built-in JUnit reporter names <testsuite> elements with the relative file path and names <testcase> elements with the full test hierarchy joined by >. This differs substantially from jest-junit, which offers rich template-based naming through suiteNameTemplate, classNameTemplate, titleTemplate, and ancestorSeparator. Migrating from jest to Vitest therefore produces noticeably different CI XML output.

Solution

Four new opt-in options are added to the JUnitOptions interface. Defaults are unchanged so existing reports are not affected.

New options

Option Type Default Description
suiteNameTemplate string | function Template for <testsuite name>. Placeholders: {title}, {filename}, {filepath}, {basename}, {displayName}
titleTemplate string | function Template for <testcase name>. Same placeholders as classnameTemplate.
ancestorSeparator string " > " Separator for ancestor describe names when building {classname} and the default test title.
noStackTrace boolean false Omit stack trace text from <failure> bodies (message attribute is still written).

Extended classnameTemplate

The existing classnameTemplate option gains five new placeholders: {classname}, {title}, {suitename}, {basename}, {displayName}.

New template variable: {classname}

{classname} is the chain of ancestor describe block names joined by ancestorSeparator (e.g. "outer > inner"). Combined with {title} this reproduces jest-junit's default "{classname} {title}" style.

New template variable: {basename}

{basename} is the bare file name without any directory component (e.g. foo.test.ts). This corresponds to jest-junit's {filename}. Vitest keeps {filename} as the relative path from the project root for backward compatibility.

Example – jest-junit-compatible output

// vitest.config.ts
reporters: [['junit', {
  suiteNameTemplate: '{title}',   // name suite after first top-level describe
  classnameTemplate: '{classname}', // ancestor path only
  titleTemplate: '{title}',        // leaf test name only
  ancestorSeparator: ' > ',
}]]

Compatibility

  • All new options are undefined / false by default.
  • When none of the new options are set the output is identical to previous releases.
  • {filename} in classnameTemplate continues to resolve to the relative path (not basename), preserving backward compatibility for existing users.

Tests

11 new tests added to test/cli/test/reporters/junit.test.ts. All 24 JUnit reporter tests pass.

Please don't delete this checklist! Before submitting the PR, please make sure you do the following:

  • It's really useful if your PR references an issue where it is discussed ahead of time. If the feature is substantial or introduces breaking changes without a discussion, PR might be closed.
  • Ideally, include a test that fails without this PR but passes with it.
  • Please, don't make changes to pnpm-lock.yaml unless you introduce a new test example.
  • Please check Allow edits by maintainers to make review process faster. Note that this option is not available for repositories that are owned by Github organizations.

Tests

  • Run the tests with pnpm test:ci.

Documentation

  • If you introduce new functionality, document it. You can run documentation with pnpm run docs command.

Changesets

  • Changes in changelog are generated from PR name. Please, make sure that it explains your changes in an understandable manner. Please, prefix changeset messages with feat:, fix:, perf:, docs:, or chore:.

Fixes #10191

Copilot AI review requested due to automatic review settings April 24, 2026 21:18
@netlify
Copy link
Copy Markdown

netlify Bot commented Apr 24, 2026

Deploy Preview for vitest-dev ready!

Built without sensitive environment variables

Name Link
🔨 Latest commit eb41a34
🔍 Latest deploy log https://app.netlify.com/projects/vitest-dev/deploys/69f1aafe3543d6000817ffee
😎 Deploy Preview https://deploy-preview-10189--vitest-dev.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds opt-in, jest-junit-compatible naming controls to Vitest’s built-in JUnit reporter so users can template <testsuite> / <testcase> naming and optionally omit stack traces, while keeping defaults unchanged.

Changes:

  • Added suiteNameTemplate, titleTemplate, ancestorSeparator, and noStackTrace options to the JUnit reporter.
  • Extended classnameTemplate to support additional placeholders (e.g. {classname}, {title}, {suitename}, {basename}, {displayName}).
  • Added new fixtures + tests and updated docs to cover the new templating behavior.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
test/cli/test/reporters/junit.test.ts Adds coverage for suite/testcase templating, separator behavior, basename handling, and stack-trace omission.
test/cli/fixtures/reporters/junit-options/sample.test.ts New fixture to exercise top-level vs nested describe naming behavior.
packages/vitest/src/node/reporters/junit.ts Implements new templating options, placeholder variables, and noStackTrace behavior.
docs/guide/reporters.md Documents new JUnit reporter options and available placeholders with examples.

Comment thread packages/vitest/src/node/reporters/junit.ts
Comment thread docs/guide/reporters.md Outdated
@neumaennl
Copy link
Copy Markdown
Contributor Author

According to copilot, none of the failing changes are caused by my changes: https://github.com/copilot/share/4a06511c-41a4-8cf0-a953-a64a2457605e

@neumaennl neumaennl force-pushed the copilot/add-junit-naming-parity branch 2 times, most recently from 1ad53a6 to ff150ed Compare April 25, 2026 08:44
sheremet-va
sheremet-va previously approved these changes Apr 27, 2026
@@ -0,0 +1,19 @@
import { describe, expect, it } from 'vitest'
Copy link
Copy Markdown
Member

@sheremet-va sheremet-va Apr 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this file is supposed to be in this directory. cli was renamed to e2e

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fixing it right now.

@neumaennl neumaennl force-pushed the copilot/add-junit-naming-parity branch from 9863d1c to 570727c Compare April 28, 2026 07:08
@neumaennl neumaennl requested a review from sheremet-va April 28, 2026 08:25
sheremet-va
sheremet-va previously approved these changes Apr 28, 2026
AriPerkkio
AriPerkkio previously approved these changes Apr 28, 2026
Comment on lines +120 to +124
/**
* Omit stack traces from test failure reports.
* @default false
*/
noStackTrace?: boolean
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would actually prefer naming this without negation:

Suggested change
/**
* Omit stack traces from test failure reports.
* @default false
*/
noStackTrace?: boolean
/**
* Include stack traces from test failure reports.
* @default true
*/
stackTrace?: boolean

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I can do that tomorrow.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@neumaennl neumaennl dismissed stale reviews from AriPerkkio and sheremet-va via 39ad3de April 29, 2026 06:41
AriPerkkio
AriPerkkio previously approved these changes Apr 29, 2026
@neumaennl neumaennl force-pushed the copilot/add-junit-naming-parity branch from 39ad3de to eb41a34 Compare April 29, 2026 06:53
sheremet-va
sheremet-va previously approved these changes Apr 29, 2026
@sheremet-va
Copy link
Copy Markdown
Member

Oh, seems like tests are failing

…verted the default so the behavior stays the same

Co-authored-by: Copilot <copilot@github.com>
@neumaennl neumaennl dismissed stale reviews from sheremet-va and AriPerkkio via 582f2d8 April 29, 2026 07:19
@neumaennl neumaennl force-pushed the copilot/add-junit-naming-parity branch from eb41a34 to 582f2d8 Compare April 29, 2026 07:19
@sheremet-va sheremet-va merged commit 2739334 into vitest-dev:main Apr 29, 2026
15 of 16 checks passed
@neumaennl
Copy link
Copy Markdown
Contributor Author

Oh, seems like tests are failing

I wasn't ready. Now it should be fine. The one failing check is a flaky playwright test running into a timeout that shouldn't be caused by my changes.

@neumaennl neumaennl deleted the copilot/add-junit-naming-parity branch April 29, 2026 08:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add jest-junit-compatible naming options to junit-reporter

6 participants