diff --git a/docs/config/slowtestthreshold.md b/docs/config/slowtestthreshold.md index 84f9594d221d..79ba1bfd703b 100644 --- a/docs/config/slowtestthreshold.md +++ b/docs/config/slowtestthreshold.md @@ -3,7 +3,7 @@ title: slowTestThreshold | Config outline: deep --- -# slowTestThreshold +# slowTestThreshold - **Type**: `number` - **Default**: `300` diff --git a/packages/runner/src/suite.ts b/packages/runner/src/suite.ts index e5caa1e75a95..80af07f5d44e 100644 --- a/packages/runner/src/suite.ts +++ b/packages/runner/src/suite.ts @@ -384,6 +384,7 @@ function createSuiteCollector( annotations: [], artifacts: [], tags: testTags, + slowTestThreshold: options.slowTestThreshold, } const handler = options.handler if (task.mode === 'run' && !handler) { diff --git a/packages/runner/src/types/tasks.ts b/packages/runner/src/types/tasks.ts index b30e04b015b4..250cb9dbc67b 100644 --- a/packages/runner/src/types/tasks.ts +++ b/packages/runner/src/types/tasks.ts @@ -340,6 +340,11 @@ export interface Test extends TaskPopulated { */ artifacts: TestArtifact[] fullTestName: string + /** + * Threshold in milliseconds for a test to be considered slow. + * Overrides the global `slowTestThreshold` config option. + */ + slowTestThreshold?: number } export type Task = Test | Suite | File @@ -582,6 +587,11 @@ export interface TestOptions { * Custom test metadata available to reporters. */ meta?: Partial + /** + * Threshold in milliseconds for a test to be considered slow. + * Overrides the global `slowTestThreshold` config option. + */ + slowTestThreshold?: number } export interface TestTags {} diff --git a/packages/runner/tsconfig.json b/packages/runner/tsconfig.json index 1f52dab27ae6..83a275cdf5f8 100644 --- a/packages/runner/tsconfig.json +++ b/packages/runner/tsconfig.json @@ -4,6 +4,7 @@ "target": "ESNext", "module": "ESNext", "moduleResolution": "Bundler", + "types": ["node"], "isolatedDeclarations": true }, "include": ["./src/**/*.ts"], diff --git a/packages/ui/client/composables/explorer/filter.ts b/packages/ui/client/composables/explorer/filter.ts index f46715321c68..f235499f6109 100644 --- a/packages/ui/client/composables/explorer/filter.ts +++ b/packages/ui/client/composables/explorer/filter.ts @@ -222,7 +222,7 @@ function* filterParents( function matchState(task: Task, filter: Filter) { if (filter.slow) { if (task.type === 'test') { - const threshold = config.value.slowTestThreshold + const threshold = task.slowTestThreshold ?? config.value.slowTestThreshold if (typeof threshold === 'number' && typeof task.result?.duration === 'number' && task.result.duration > threshold) { return true } diff --git a/packages/ui/client/composables/explorer/utils.ts b/packages/ui/client/composables/explorer/utils.ts index 294ecb5a0026..57124772f783 100644 --- a/packages/ui/client/composables/explorer/utils.ts +++ b/packages/ui/client/composables/explorer/utils.ts @@ -43,7 +43,7 @@ export function isSlowTestTask(task: Task) { return false } - const threshold = config.value.slowTestThreshold + const threshold = task.slowTestThreshold ?? config.value.slowTestThreshold return typeof threshold === 'number' && duration > threshold } diff --git a/packages/vitest/src/node/reporters/base.ts b/packages/vitest/src/node/reporters/base.ts index edd1fd63b5e2..3ac700c9631f 100644 --- a/packages/vitest/src/node/reporters/base.ts +++ b/packages/vitest/src/node/reporters/base.ts @@ -203,7 +203,7 @@ export abstract class BaseReporter implements Reporter { protected printTestCase(moduleState: TestModuleState, test: TestCase): void { const testResult = test.result() - const { duration = 0 } = test.diagnostic() || {} + const diagnostic = test.diagnostic() const padding = this.getTestIndentation(test.task) const suffix = this.getTestCaseSuffix(test) @@ -212,7 +212,7 @@ export abstract class BaseReporter implements Reporter { } // also print slow tests - else if (duration > this.ctx.config.slowTestThreshold) { + else if (diagnostic?.slow) { this.log(` ${padding}${c.yellow(c.dim(F_CHECK))} ${this.getTestName(test.task, separator)} ${suffix}`) } @@ -372,7 +372,9 @@ export abstract class BaseReporter implements Reporter { return '' } - const color = duration > this.ctx.config.slowTestThreshold + const slowTestThreshold = ('slowTestThreshold' in task && task.slowTestThreshold) + || this.ctx.config.slowTestThreshold + const color = duration > slowTestThreshold ? c.yellow : c.green diff --git a/packages/vitest/src/node/reporters/reported-tasks.ts b/packages/vitest/src/node/reporters/reported-tasks.ts index 65b48cd3b914..9daa1697a082 100644 --- a/packages/vitest/src/node/reporters/reported-tasks.ts +++ b/packages/vitest/src/node/reporters/reported-tasks.ts @@ -216,7 +216,8 @@ export class TestCase extends ReportedTaskImplementation { return undefined } const duration = result.duration || 0 - const slow = duration > this.project.globalConfig.slowTestThreshold + const slowTestThreshold = this.task.slowTestThreshold ?? this.project.globalConfig.slowTestThreshold + const slow = duration > slowTestThreshold return { slow, heap: result.heap, @@ -576,6 +577,11 @@ export interface TaskOptions { * Only tests have a `timeout` option. */ readonly timeout: number | undefined + /** + * Threshold in milliseconds for a test to be considered slow. + * Only tests have a `slowTestThreshold` option. + */ + readonly slowTestThreshold: number | undefined readonly mode: 'run' | 'only' | 'skip' | 'todo' } @@ -591,6 +597,7 @@ function buildOptions( repeats: task.repeats, tags: task.tags, timeout: task.type === 'test' ? task.timeout : undefined, + slowTestThreshold: task.type === 'test' ? task.slowTestThreshold : undefined, // runner types are too broad, but the public API should be more strict // the queued state exists only on Files and this method is called // only for tests and suites diff --git a/packages/vitest/src/node/reporters/summary.ts b/packages/vitest/src/node/reporters/summary.ts index 26a236cd16ec..e4933d9164c5 100644 --- a/packages/vitest/src/node/reporters/summary.ts +++ b/packages/vitest/src/node/reporters/summary.ts @@ -183,9 +183,10 @@ export class SummaryReporter implements Reporter { onFinish: () => {}, } + const slowTestThreshold = test.options.slowTestThreshold ?? this.ctx.config.slowTestThreshold const timeout = setTimeout(() => { slowTest.visible = true - }, this.ctx.config.slowTestThreshold).unref() + }, slowTestThreshold).unref() slowTest.onFinish = () => { slowTest.hook?.onFinish()