[READ-ONLY] Mirror of https://github.com/vitest-dev/vitest. Next generation testing framework powered by Vite. vitest.dev
test testing-tools vite
12

Configure Feed

Select the types of activity you want to include in your feed.

fix: `hideSkippedTests` should not hide `test.todo` (fix #9562) (#9781)

authored by

김성현 and committed by
GitHub
(Mar 5, 2026, 10:08 AM +0100) 8181e06e d9af8446

+42 -12
+3 -1
test/cli/fixtures/reporters/pass-and-skip-test-suites.test.ts
··· 1 - import { expect, describe, test } from 'vitest' 1 + import { describe, test } from 'vitest' 2 2 3 3 test('passing test #1', () => {}) 4 4 ··· 7 7 }) 8 8 9 9 test.skip('skipped test #1', () => {}) 10 + 11 + test.todo('todo test #1') 10 12 11 13 describe.skip("skipped suite", () => { 12 14 test('skipped test #2', () => {})
+5 -3
test/cli/test/reporters/default.test.ts
··· 164 164 }) 165 165 166 166 expect(trimReporterOutput(stdout)).toMatchInlineSnapshot(` 167 - "✓ fixtures/reporters/pass-and-skip-test-suites.test.ts (4 tests | 2 skipped) [...]ms 167 + "✓ fixtures/reporters/pass-and-skip-test-suites.test.ts (5 tests | 2 skipped | 1 todo) [...]ms 168 168 ✓ passing test #1 [...]ms 169 169 ✓ passing suite (1) 170 170 ✓ passing test #2 [...]ms 171 171 ↓ skipped test #1 172 + □ todo test #1 172 173 ↓ skipped suite (1) 173 174 ↓ skipped test #2" 174 175 `) ··· 183 184 }) 184 185 185 186 expect(trimReporterOutput(stdout)).toMatchInlineSnapshot(` 186 - "✓ fixtures/reporters/pass-and-skip-test-suites.test.ts (4 tests | 2 skipped) [...]ms 187 + "✓ fixtures/reporters/pass-and-skip-test-suites.test.ts (5 tests | 2 skipped | 1 todo) [...]ms 187 188 ✓ passing test #1 [...]ms 188 189 ✓ passing suite (1) 189 - ✓ passing test #2 [...]ms" 190 + ✓ passing test #2 [...]ms 191 + □ todo test #1" 190 192 `) 191 193 }) 192 194
+3 -1
test/cli/test/reporters/verbose.test.ts
··· 36 36 "✓ fixtures/reporters/pass-and-skip-test-suites.test.ts > passing test #1 [...]ms 37 37 ✓ fixtures/reporters/pass-and-skip-test-suites.test.ts > passing suite > passing test #2 [...]ms 38 38 ↓ fixtures/reporters/pass-and-skip-test-suites.test.ts > skipped test #1 39 + □ fixtures/reporters/pass-and-skip-test-suites.test.ts > todo test #1 39 40 ↓ fixtures/reporters/pass-and-skip-test-suites.test.ts > skipped suite > skipped test #2" 40 41 `) 41 42 }) ··· 50 51 51 52 expect(trimReporterOutput(stdout)).toMatchInlineSnapshot(` 52 53 "✓ fixtures/reporters/pass-and-skip-test-suites.test.ts > passing test #1 [...]ms 53 - ✓ fixtures/reporters/pass-and-skip-test-suites.test.ts > passing suite > passing test #2 [...]ms" 54 + ✓ fixtures/reporters/pass-and-skip-test-suites.test.ts > passing suite > passing test #2 [...]ms 55 + □ fixtures/reporters/pass-and-skip-test-suites.test.ts > todo test #1" 54 56 `) 55 57 }) 56 58
+16 -4
packages/vitest/src/node/reporters/base.ts
··· 134 134 let testsCount = 0 135 135 let failedCount = 0 136 136 let skippedCount = 0 137 + let todoCount = 0 137 138 138 139 // delaying logs to calculate the test stats first 139 140 // which minimizes the amount of for loops ··· 147 148 const suiteState = child.state() 148 149 149 150 // Skipped suites are hidden when --hideSkippedTests, print otherwise 150 - if (!this.ctx.config.hideSkippedTests || suiteState !== 'skipped') { 151 + if (!this.ctx.config.hideSkippedTests || suiteState !== 'skipped' || child.task.mode === 'todo') { 151 152 this.printTestSuite(child) 152 153 } 153 154 ··· 161 162 failedCount++ 162 163 } 163 164 else if (testResult.state === 'skipped') { 164 - skippedCount++ 165 + if (child.options.mode === 'todo') { 166 + todoCount++ 167 + } 168 + else { 169 + skippedCount++ 170 + } 165 171 } 166 172 167 - if (this.ctx.config.hideSkippedTests && suiteState === 'skipped') { 173 + if (this.ctx.config.hideSkippedTests && suiteState === 'skipped' && child.options.mode !== 'todo') { 168 174 // Skipped suites are hidden when --hideSkippedTests 169 175 continue 170 176 } ··· 185 191 tests: testsCount, 186 192 failed: failedCount, 187 193 skipped: skippedCount, 194 + todo: todoCount, 188 195 })) 189 196 logs.forEach(log => this.log(log)) 190 197 } ··· 205 212 this.log(` ${padding}${c.yellow(c.dim(F_CHECK))} ${this.getTestName(test.task, separator)} ${suffix}`) 206 213 } 207 214 208 - else if (this.ctx.config.hideSkippedTests && (testResult.state === 'skipped')) { 215 + else if (this.ctx.config.hideSkippedTests && testResult.state === 'skipped' && test.options.mode !== 'todo') { 209 216 // Skipped tests are hidden when --hideSkippedTests 210 217 } 211 218 ··· 218 225 tests: number 219 226 failed: number 220 227 skipped: number 228 + todo: number 221 229 }): string { 222 230 let state = c.dim(`${counts.tests} test${counts.tests > 1 ? 's' : ''}`) 223 231 ··· 227 235 228 236 if (counts.skipped) { 229 237 state += c.dim(' | ') + c.yellow(`${counts.skipped} skipped`) 238 + } 239 + 240 + if (counts.todo) { 241 + state += c.dim(' | ') + c.gray(`${counts.todo} todo`) 230 242 } 231 243 232 244 let suffix = c.dim('(') + state + c.dim(')') + this.getDurationPrefix(testModule.task)
+6 -1
packages/vitest/src/node/reporters/summary.ts
··· 221 221 this.tests.failed++ 222 222 } 223 223 else if (!result?.state || result?.state === 'skipped') { 224 - this.tests.skipped++ 224 + if (test.options.mode === 'todo') { 225 + this.tests.todo++ 226 + } 227 + else { 228 + this.tests.skipped++ 229 + } 225 230 } 226 231 227 232 this.renderer.schedule()
+1 -1
packages/vitest/src/node/reporters/verbose.ts
··· 18 18 19 19 const testResult = test.result() 20 20 21 - if (this.ctx.config.hideSkippedTests && testResult.state === 'skipped') { 21 + if (this.ctx.config.hideSkippedTests && testResult.state === 'skipped' && test.options.mode !== 'todo') { 22 22 return 23 23 } 24 24
+1
packages/vitest/src/node/reporters/renderers/figures.ts
··· 8 8 export const F_CROSS = '×' 9 9 export const F_LONG_DASH = '⎯' 10 10 export const F_RIGHT_TRI = '▶' 11 + export const F_TODO = '□' 11 12 export const F_TREE_NODE_MIDDLE = '├──' 12 13 export const F_TREE_NODE_END = '└──'
+7 -1
packages/vitest/src/node/reporters/renderers/utils.ts
··· 14 14 F_DOWN_RIGHT, 15 15 F_LONG_DASH, 16 16 F_POINTER, 17 + F_TODO, 17 18 } from './figures' 18 19 19 20 export const pointer: string = c.yellow(F_POINTER) 20 21 export const skipped: string = c.dim(c.gray(F_DOWN)) 22 + export const todo: string = c.dim(c.gray(F_TODO)) 21 23 export const benchmarkPass: string = c.green(F_DOT) 22 24 export const testPass: string = c.green(F_CHECK) 23 25 export const taskFail: string = c.red(F_CROSS) ··· 181 183 } 182 184 183 185 export function getStateSymbol(task: Task): string { 184 - if (task.mode === 'skip' || task.mode === 'todo') { 186 + if (task.mode === 'todo') { 187 + return todo 188 + } 189 + 190 + if (task.mode === 'skip') { 185 191 return skipped 186 192 } 187 193