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()