Skip to content

Commit 6adecb9

Browse files
feat(vitest): allow conditional context.skip(boolean) (#7659)
Co-authored-by: Ari Perkkiö <[email protected]>
1 parent ea3d67b commit 6adecb9

File tree

8 files changed

+61
-9
lines changed

8 files changed

+61
-9
lines changed

Diff for: docs/api/index.md

+12
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,18 @@ test('skipped test', (context) => {
129129
})
130130
```
131131

132+
Since Vitest 3.1, if the condition is unknonwn, you can provide it to the `skip` method as the first arguments:
133+
134+
```ts
135+
import { assert, test } from 'vitest'
136+
137+
test('skipped test', (context) => {
138+
context.skip(Math.random() < 0.5, 'optional message')
139+
// Test skipped, no error
140+
assert.equal(Math.sqrt(4), 3)
141+
})
142+
```
143+
132144
### test.skipIf
133145

134146
- **Alias:** `it.skipIf`

Diff for: packages/runner/src/context.ts

+10-2
Original file line numberDiff line numberDiff line change
@@ -104,10 +104,18 @@ export function createTestContext(
104104

105105
context.task = test
106106

107-
context.skip = (note?: string) => {
107+
context.skip = (condition?: boolean | string, note?: string): never => {
108+
if (condition === false) {
109+
// do nothing
110+
return undefined as never
111+
}
108112
test.result ??= { state: 'skip' }
109113
test.result.pending = true
110-
throw new PendingError('test is skipped; abort execution', test, note)
114+
throw new PendingError(
115+
'test is skipped; abort execution',
116+
test,
117+
typeof condition === 'string' ? condition : note,
118+
)
111119
}
112120

113121
context.onTestFailed = (handler, timeout) => {

Diff for: packages/runner/src/types/tasks.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -658,7 +658,10 @@ export interface TestContext {
658658
* Mark tests as skipped. All execution after this call will be skipped.
659659
* This function throws an error, so make sure you are not catching it accidentally.
660660
*/
661-
skip: (note?: string) => never
661+
skip: {
662+
(note?: string): never
663+
(condition: boolean, note?: string): void
664+
}
662665
}
663666

664667
/**

Diff for: test/cli/fixtures/fails/skip-conditional.test.ts

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { expect, it } from 'vitest';
2+
3+
it('skips correctly', (t) => {
4+
t.skip(true)
5+
expect.unreachable()
6+
})
7+
8+
it('doesnt skip correctly', (t) => {
9+
t.skip(false)
10+
throw new Error('doesnt skip')
11+
})

Diff for: test/cli/test/__snapshots__/fails.test.ts.snap

+2
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ Error: expect.poll(assertion).toBe() was not awaited. This assertion is asynchro
7474
7575
exports[`should fail primitive-error.test.ts 1`] = `"Unknown Error: 42"`;
7676
77+
exports[`should fail skip-conditional.test.ts 1`] = `"Error: doesnt skip"`;
78+
7779
exports[`should fail snapshot-with-not.test.ts 1`] = `
7880
"Error: toThrowErrorMatchingInlineSnapshot cannot be used with "not"
7981
Error: toThrowErrorMatchingSnapshot cannot be used with "not"

Diff for: test/reporters/fixtures/default/a.test.ts

+14
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,17 @@ describe('a failed', () => {
2424
})
2525
})
2626
})
27+
28+
describe('a skipped', () => {
29+
test('skipped with note', (t) => {
30+
t.skip('reason')
31+
})
32+
33+
test('condition', (t) => {
34+
t.skip(true)
35+
})
36+
37+
test('condition with note', (t) => {
38+
t.skip(true, 'note')
39+
})
40+
})

Diff for: test/reporters/tests/default.test.ts

+6-4
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,12 @@ describe('default reporter', async () => {
6363
reporters: 'none',
6464
})
6565

66-
expect(stdout).contain('✓ a passed > a1 test')
67-
expect(stdout).contain('✓ a passed > nested a > nested a3 test')
68-
expect(stdout).contain('× a failed > a failed test')
69-
expect(stdout).contain('nested a failed 1 test')
66+
expect(stdout).toContain('✓ a passed > a1 test')
67+
expect(stdout).toContain('✓ a passed > nested a > nested a3 test')
68+
expect(stdout).toContain('× a failed > a failed test')
69+
expect(stdout).toContain('nested a failed 1 test')
70+
expect(stdout).toContain('[note]')
71+
expect(stdout).toContain('[reason]')
7072
})
7173

7274
test('rerun should undo', async () => {

Diff for: test/reporters/tests/junit.test.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,8 @@ test('options.classname changes classname property', async () => {
120120

121121
// All classname attributes should have the custom value
122122
expect(xml.match(/<testcase classname="a\.test\.ts"/g)).toBeNull()
123-
expect(xml.match(/<testcase classname="/g)).toHaveLength(13)
124-
expect(xml.match(/<testcase classname="some-custom-classname"/g)).toHaveLength(13)
123+
expect(xml.match(/<testcase classname="/g)).toHaveLength(16)
124+
expect(xml.match(/<testcase classname="some-custom-classname"/g)).toHaveLength(16)
125125
})
126126

127127
test('options.suiteName changes name property', async () => {

0 commit comments

Comments
 (0)