Skip to content

Commit 083f6bd

Browse files
hi-ogawaclaude
andauthored
feat: expose default reporters through configDefaults.reporters (#10219)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 457db29 commit 083f6bd

6 files changed

Lines changed: 47 additions & 43 deletions

File tree

docs/config/reporters.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ interface UserConfig {
1414
type ConfigReporter = string | Reporter | [string, object?]
1515
```
1616
17-
- **Default:** [`'default'`](/guide/reporters#default-reporter) (or <code>[['default'](/guide/reporters#default-reporter), ['github-actions'](/guide/reporters#github-actions-reporter)]</code> when `process.env.GITHUB_ACTIONS === 'true'`)
17+
- **Default:** [`'default'`](/guide/reporters#default-reporter). See [Default Reporters](/guide/reporters#default-reporters) for environment-specific behavior.
1818
- **CLI:**
1919
- `--reporter=tap` for a single reporter
2020
- `--reporter=verbose --reporter=github-actions` for multiple reporters
@@ -49,14 +49,14 @@ Note that the [coverage](/guide/coverage) feature uses a different [`coverage.re
4949
5050
::: code-group
5151
```js [vitest.config.js]
52-
import { defineConfig } from 'vitest/config'
52+
import { configDefaults, defineConfig } from 'vitest/config'
5353

5454
export default defineConfig({
5555
test: {
5656
reporters: [
57-
'default',
57+
...configDefaults.reporters,
5858
// conditional reporter
59-
process.env.CI ? 'github-actions' : {},
59+
...(process.env.CI ? ['html'] : []),
6060
// custom reporter from npm package
6161
// options are passed down as a tuple
6262
[

docs/guide/reporters.md

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ outline: deep
55

66
# Reporters
77

8-
Vitest provides several built-in reporters to display test output in different formats, as well as the ability to use custom reporters. You can select different reporters either by using the `--reporter` command line option, or by including a `reporters` property in your [configuration file](/config/reporters). If no reporter is specified, Vitest will use the `default` reporter as described below.
8+
Vitest provides several built-in reporters to display test output in different formats, as well as the ability to use custom reporters. You can select different reporters either by using the `--reporter` command line option, or by including a `reporters` property in your [configuration file](/config/reporters). If no reporter is specified, Vitest [auto-selects reporters](#default-configuration) based on the environment.
99

1010
Using reporters via command line:
1111

@@ -38,6 +38,26 @@ export default defineConfig({
3838
})
3939
```
4040

41+
## Default Configuration
42+
43+
When `reporters` is not configured, Vitest uses the following reporters:
44+
45+
- [`default`](#default-reporter) in normal terminal runs
46+
- [`minimal`](#minimal-reporter) when Vitest detects an AI coding agent
47+
- [`github-actions`](#github-actions-reporter) is added when `process.env.GITHUB_ACTIONS === 'true'`
48+
49+
If you configure your own reporters, the configured list replaces the default list. To add a reporter while keeping Vitest's defaults, extend `configDefaults.reporters`:
50+
51+
```ts
52+
import { configDefaults, defineConfig } from 'vitest/config'
53+
54+
export default defineConfig({
55+
test: {
56+
reporters: ['json', ...configDefaults.reporters],
57+
},
58+
})
59+
```
60+
4161
## Reporter Output
4262

4363
By default, Vitest's reporters will print their output to the terminal. When using the `json`, `html` or `junit` reporters, you can instead write your tests' output to a file by including an `outputFile` [configuration option](/config/outputfile) either in your Vite configuration file or via CLI.
@@ -66,9 +86,11 @@ npx vitest --reporter=json --reporter=default
6686
```
6787

6888
```ts
89+
import { configDefaults, defineConfig } from 'vitest/config'
90+
6991
export default defineConfig({
7092
test: {
71-
reporters: ['json', 'default'],
93+
reporters: ['json', ...configDefaults.reporters],
7294
outputFile: './test-output.json'
7395
},
7496
})
@@ -96,11 +118,7 @@ This example will write separate JSON and XML reports as well as printing a verb
96118

97119
### Default Reporter
98120

99-
By default (i.e. if no reporter is specified), Vitest will display summary of running tests and their status at the bottom. Once a suite passes, its status will be reported on top of the summary.
100-
101-
::: tip
102-
When Vitest detects it is running inside an AI coding agent, the [`minimal`](#minimal-reporter) reporter is used instead to reduce output and minimize token usage. You can override this by explicitly configuring the [`reporters`](/config/reporters) option.
103-
:::
121+
The `default` reporter displays summary of running tests and their status at the bottom. Once a suite passes, its status will be reported on top of the summary.
104122

105123
You can disable the summary by configuring the reporter:
106124

@@ -550,21 +568,11 @@ export default defineConfig({
550568
### GitHub Actions Reporter {#github-actions-reporter}
551569

552570
Output [workflow commands](https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-error-message)
553-
to provide annotations for test failures. This reporter is automatically enabled when the `reporters` option is not configured and `process.env.GITHUB_ACTIONS === 'true'` (on GitHub Actions environment).
571+
to provide annotations for test failures. This reporter is [enabled automatically](#default-configuration) when `process.env.GITHUB_ACTIONS === 'true'` (on GitHub Actions environment).
554572

555573
<img alt="GitHub Actions" img-dark src="https://github.com/vitest-dev/vitest/assets/4232207/336cddc2-df6b-4b8a-8e72-4d00010e37f5">
556574
<img alt="GitHub Actions" img-light src="https://github.com/vitest-dev/vitest/assets/4232207/ce8447c1-0eab-4fe1-abef-d0d322290dca">
557575

558-
If you configure reporters, you need to explicitly add `github-actions`.
559-
560-
```ts
561-
export default defineConfig({
562-
test: {
563-
reporters: process.env.GITHUB_ACTIONS === 'true' ? ['dot', 'github-actions'] : ['dot'],
564-
},
565-
})
566-
```
567-
568576
You can customize the file paths that are printed in [GitHub's annotation command format](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions) by using the `onWritePath` option. This is useful when running Vitest in a containerized environment, such as Docker, where the file paths may not match the paths in the GitHub Actions environment.
569577

570578
```ts
@@ -662,7 +670,7 @@ export default defineConfig({
662670
Outputs a minimal report containing only failed tests and their error messages. Console logs from passing tests and the summary section are also suppressed.
663671

664672
::: tip Agent Reporter
665-
This reporter is well optimized for AI coding assistants and LLM-based workflows to reduce token usage. It is automatically enabled when no `reporters` option is configured and Vitest detects it is running inside an AI coding agent. If you configure custom reporters, you can explicitly add `minimal` or `agent`:
673+
This reporter is well optimized for AI coding assistants and LLM-based workflows to reduce token usage. It is [enabled automatically](#default-configuration) when Vitest detects it is running inside an AI coding agent.
666674

667675
:::code-group
668676
```bash [CLI]

docs/guide/ui.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ export default defineConfig({
4040
You can check your coverage report in Vitest UI: see [Vitest UI Coverage](/guide/coverage#vitest-ui) for more details.
4141

4242
::: warning
43-
If you still want to see how your tests are running in real time in the terminal, don't forget to add `default` reporter to `reporters` option: `['default', 'html']`.
43+
If you still want to see how your tests are running in real time in the terminal, add `configDefaults.reporters` to the `reporters` option: `['html', ...configDefaults.reporters]`.
4444
:::
4545

4646
::: tip

packages/vitest/src/defaults.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ export const configDefaults: Readonly<{
7777
teardownTimeout: number
7878
forceRerunTriggers: string[]
7979
update: boolean
80-
reporters: never[]
80+
reporters: string[]
8181
silent: boolean
8282
hideSkippedTests: boolean
8383
api: boolean
@@ -116,7 +116,10 @@ export const configDefaults: Readonly<{
116116
teardownTimeout: 10000,
117117
forceRerunTriggers: ['**/package.json/**', '**/{vitest,vite}.config.*/**'],
118118
update: false,
119-
reporters: [],
119+
reporters: [
120+
isAgent ? 'minimal' : 'default',
121+
...(process.env.GITHUB_ACTIONS === 'true' ? ['github-actions'] : []),
122+
],
120123
silent: false,
121124
hideSkippedTests: false,
122125
api: false,

packages/vitest/src/node/config/resolveConfig.ts

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -692,22 +692,23 @@ export function resolveConfig(
692692
* { reporter: [[ 'json' ], 'html'] }
693693
* { reporter: [[ 'json', { outputFile: 'test.json' } ], 'html'] }
694694
*/
695-
if (options.reporters) {
696-
if (!Array.isArray(options.reporters)) {
695+
if (resolved.reporters) {
696+
if (!Array.isArray(resolved.reporters)) {
697697
// Reporter name, e.g. { reporters: 'json' }
698-
if (typeof options.reporters === 'string') {
699-
resolved.reporters = [[options.reporters, {}]]
698+
if (typeof resolved.reporters === 'string') {
699+
resolved.reporters = [[resolved.reporters, {}]]
700700
}
701701
// Inline reporter e.g. { reporters: { onFinish() { method() } } }
702702
else {
703-
resolved.reporters = [options.reporters]
703+
resolved.reporters = [resolved.reporters]
704704
}
705705
}
706706
// It's an array of reporters
707707
else {
708+
const reporters = resolved.reporters
708709
resolved.reporters = []
709710

710-
for (const reporter of options.reporters) {
711+
for (const reporter of reporters) {
711712
if (Array.isArray(reporter)) {
712713
// Reporter with options, e.g. { reporters: [ [ 'json', { outputFile: 'test.json' } ] ] }
713714
resolved.reporters.push([reporter[0], reporter[1] as Record<string, unknown> || {}])
@@ -759,15 +760,6 @@ export function resolveConfig(
759760
}
760761
}
761762

762-
if (!resolved.reporters.length) {
763-
resolved.reporters.push([isAgent ? 'agent' : 'default', {}])
764-
765-
// also enable github-actions reporter as a default
766-
if (process.env.GITHUB_ACTIONS === 'true') {
767-
resolved.reporters.push(['github-actions', {}])
768-
}
769-
}
770-
771763
if (resolved.changed) {
772764
resolved.passWithNoTests ??= true
773765
}

test/config/test/public.test.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { CoverageOptions } from 'vitest/node'
22
import { resolve } from 'pathe'
33
import { expect, test } from 'vitest'
4+
import { configDefaults } from 'vitest/config'
45
import { resolveConfig } from 'vitest/node'
56

67
test('resolves the test config', async () => {
@@ -30,7 +31,7 @@ test('respects root', async () => {
3031
})
3132
expect(viteConfig.configFile).toBe(resolve(configRoot, 'vitest.config.ts'))
3233
expect(vitestConfig.name).toBe('root config')
33-
expect(vitestConfig.reporters).toEqual([['default', {}]])
34+
expect(vitestConfig.reporters).toEqual(configDefaults.reporters.map(v => [v, {}]))
3435
})
3536

3637
test('respects custom config', async () => {
@@ -41,7 +42,7 @@ test('respects custom config', async () => {
4142
})
4243
expect(viteConfig.configFile).toBe(config)
4344
expect(vitestConfig.name).toBe('custom config')
44-
expect(vitestConfig.reporters).toEqual([['default', {}]])
45+
expect(vitestConfig.reporters).toEqual(configDefaults.reporters.map(v => [v, {}]))
4546
})
4647

4748
test('default value changes of coverage.exclude do not reflect to test.exclude', async () => {

0 commit comments

Comments
 (0)