···46464747The `npx` tool will execute the specified command. By default, `npx` will first check if the command exists in the local project's binaries. If it is not found there, `npx` will look in the system's `$PATH` and execute it if found. If the command is not found in either location, `npx` will install it in a temporary location prior to execution.
48484949+Vitest and third party integrations can use `.vitest` directory to store generated artifacts. It's recommended to add this in your `.gitignore`.
5050+5151+``` sh [.gitignore]
5252+# Vitest reports and artifacts
5353+.vitest/
5454+```
5555+4956## Writing Tests
50575158As an example, we will write a simple test that verifies the output of a function that adds two numbers.
+119
docs/api/advanced/vitest.md
···687687::: warning
688688At the moment, the [browser](/guide/browser/) modules are not supported.
689689:::
690690+691691+## createReport <Version>5.0.0</Version> {#createreport}
692692+693693+```ts
694694+function createReport(scope: string): Report
695695+```
696696+697697+Creates a report that is limited to the given scope. `Report` follows Vitest's rules around [Storing artifacts on file system](/guide/advanced/reporters.html#storing-artifacts-on-file-system).
698698+699699+`Report` provides collection of utilities for writing test results, temporary files and other artifacts on the file system. It's especially intended for third party integrations like custom reporters.
700700+701701+All operations of `Report` are limited to given `scope`. A single report cannot interfere with other reports. Internally Vitest creates `.vitest` directory where each `scope` creates their own directory. This convention of `.vitest` directory reduces the amount of entries end-users need to specify in their `.gitignore`.
702702+703703+```ts
704704+import type { Report } from 'vitest/node'
705705+706706+const scope = 'example-yaml-reporter'
707707+708708+// Automatically creates `<project-root>/.vitest/example-yaml-reporter/`
709709+// directory if it does not exist already
710710+const report: Report = vitest.createReport(scope)
711711+```
712712+713713+### Report.root
714714+715715+```ts
716716+const root: string
717717+```
718718+719719+The root directory for this scope.
720720+721721+```ts
722722+const report = vitest.createReport('my-json-reporter')
723723+724724+// Is <project-root>/.vitest/my-json-reporter
725725+const root = report.root
726726+```
727727+728728+729729+### Report.clean
730730+731731+```ts
732732+function clean(): Promise<void>
733733+```
734734+735735+Clean up the report directory for this scope.
736736+737737+```ts
738738+const report = vitest.createReport('my-json-reporter')
739739+740740+// Removes everything inside <project-root>/.vitest/my-json-reporter/
741741+await report.clean()
742742+```
743743+744744+### Report.writeFile
745745+746746+```ts
747747+function writeFile(
748748+ filename: string,
749749+ content: string | Uint8Array,
750750+ encoding?: BufferEncoding
751751+): Promise<void>
752752+```
753753+754754+Write a file to the report directory for this scope. By default the file will be written with UTF-8 encoding. The filename is relative to the scope directory.
755755+756756+```ts
757757+const report = vitest.createReport('my-json-reporter')
758758+759759+// Writes file to .vitest/my-json-reporter/test-report.json
760760+await report.writeFile('test-report.json', JSON.stringify(results))
761761+```
762762+763763+### Report.readFile
764764+765765+```ts
766766+function readFile(filename: string, encoding?: BufferEncoding): Promise<string>
767767+```
768768+769769+Read a file from the report directory for this scope.
770770+771771+```ts
772772+const report = vitest.createReport('my-json-reporter')
773773+774774+// Reads file from .vitest/my-json-reporter/test-report.json
775775+const content: string = await report.readFile('test-report.json')
776776+```
777777+778778+### Report.readdir
779779+780780+```ts
781781+function readdir(): Promise<string[]>
782782+```
783783+784784+Read contents of the report directory for this scope.
785785+786786+```ts
787787+const report = vitest.createReport('my-json-reporter')
788788+789789+// Reads contents from .vitest/my-json-reporter
790790+const filenames: string[] = await report.readdir()
791791+```
792792+793793+### Report.delete
794794+795795+<!-- eslint-skip -->
796796+```ts
797797+function delete(filename: string): Promise<void>
798798+```
799799+800800+Delete a file from the report directory for this scope.
801801+802802+```ts
803803+const report = vitest.createReport('my-json-reporter')
804804+805805+// Deletes file from .vitest/my-json-reporter/test-report.json
806806+await report.delete('test-report.json')
807807+```
808808+
+27
docs/guide/advanced/reporters.md
···7272}
7373```
74747575+## Storing artifacts on file system
7676+7777+::: tip
7878+Vitest provides [`vitest.createReport`](/api/advanced/vitest.html#createreport) that exposes collection of utilities for writing artifacts on file system conveniently.
7979+:::
8080+8181+If your custom reporter needs to store any artifacts on file system it should place them inside `.vitest` directory. This directory is a convention that Vitest reporters and third party integrations can use to co-locate their results in a single directory. This way users of your custom reporter do not need to add multiple exclusion in their `.gitignore`. Only the `.vitest` is needed.
8282+8383+Reporters and other integrations should respect following rules around `.vitest` directory:
8484+8585+- `.vitest` directory is placed in [the `root` of the project](/config/root)
8686+- Reporter can create `.vitest` directory if it does not already exist
8787+- Reporter should never remove `.vitest` directory
8888+- Reporter should create their own directory inside `.vitest`, for example `.vitest/yaml-reporter/`
8989+- Reporter can remove their own specific directory inside `.vitest`, for example `.vitest/yaml-reporter/`
9090+9191+```ansi
9292+.vitest
9393+│
9494+├── yaml-reporter
9595+│ ├── results.yaml
9696+│ └── summary.yaml
9797+│
9898+└── junit-reporter
9999+ └── report.xml
100100+```
101101+75102## Exported Reporters
7610377104`vitest` comes with a few [built-in reporters](/guide/reporters) that you can use out of the box.
+9
packages/vitest/src/node/core.ts
···99import type { CliOptions } from './cli/cli-api'
1010import type { VitestFetchFunction } from './environments/fetchModule'
1111import type { ProcessPool } from './pool'
1212+import type { Report } from './reporters/report'
1213import type { TestModule } from './reporters/reported-tasks'
1314import type { TestSpecification } from './test-specification'
1415import type { ResolvedConfig, TestProjectConfiguration, UserConfig, VitestRunMode } from './types/config'
···4647import { getDefaultTestProject, resolveBrowserProjects, resolveProjects } from './projects/resolveProjects'
4748import { BlobReporter, readBlobs } from './reporters/blob'
4849import { HangingProcessReporter } from './reporters/hanging-process'
5050+import { createReport } from './reporters/report'
4951import { createBenchmarkReporters, createReporters } from './reporters/utils'
5052import { VitestResolver } from './resolver'
5153import { VitestSpecifications } from './specifications'
···16641666 const positivePattern = project.slice(1)
16651667 return wildcardPatternToRegExp(positivePattern).test(name)
16661668 })
16691669+ }
16701670+16711671+ /**
16721672+ * Create a report that's scoped to a specific reporter directory.
16731673+ */
16741674+ createReport(scope: string): Report {
16751675+ return createReport(this, scope)
16671676 }
16681677}
16691678
+1-1
packages/vitest/src/public/node.ts
···7373} from '../node/reporters'
7474export type { HTMLOptions } from '../node/reporters/html'
7575export type { JsonOptions } from '../node/reporters/json'
7676-7776export type { JUnitOptions } from '../node/reporters/junit'
78777878+export type { Report } from '../node/reporters/report'
7979export type {
8080 ModuleDiagnostic,
8181 TaskOptions,