Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: introduce global configuration for retry setting (fix #3598) #3603

Merged
merged 13 commits into from Jun 27, 2023
Merged
9 changes: 9 additions & 0 deletions docs/config/index.md
Expand Up @@ -1452,3 +1452,12 @@ This config option affects truncating values in `test.each` titles and inside th
Stop test execution when given number of tests have failed.

By default Vitest will run all of your test cases even if some of them fail. This may not be desired for CI builds where you are only interested in 100% successful builds and would like to stop test execution as early as possible when test failures occur. The `bail` option can be used to speed up CI runs by preventing it from running more tests when failures have occured.

### retry

- **Type:** `number`
- **Default:** `0`
- **CLI:** `--retry=<value>`
- **Version:** Since Vitest 0.32.3

Retry the test specific number of times if it fails.
1 change: 1 addition & 0 deletions docs/guide/cli.md
Expand Up @@ -93,6 +93,7 @@ Run only [benchmark](https://vitest.dev/guide/features.html#benchmarking-experim
| `--inspect` | Enables Node.js inspector |
| `--inspect-brk` | Enables Node.js inspector with break |
| `--bail <number>` | Stop test execution when given number of tests have failed |
| `--retry <times>` | Retry the test specific number of times if it fails |
| `-h, --help` | Display available CLI options |

::: tip
Expand Down
2 changes: 1 addition & 1 deletion packages/runner/src/suite.ts
Expand Up @@ -78,7 +78,7 @@ function createSuiteCollector(name: string, factory: SuiteFactory = () => { }, m
mode,
suite: undefined!,
fails: this.fails,
retry: options?.retry,
retry: options?.retry ?? runner.config.retry,
sheremet-va marked this conversation as resolved.
Show resolved Hide resolved
repeats: options?.repeats,
meta: Object.create(null),
} as Omit<Test, 'context'> as Test
Expand Down
1 change: 1 addition & 0 deletions packages/runner/src/types/runner.ts
Expand Up @@ -20,6 +20,7 @@ export interface VitestRunnerConfig {
maxConcurrency: number
testTimeout: number
hookTimeout: number
retry: number
}

export type VitestRunnerImportSource = 'collect' | 'setup'
Expand Down
1 change: 1 addition & 0 deletions packages/vitest/src/node/cli.ts
Expand Up @@ -48,6 +48,7 @@ cli
.option('--inspect-brk', 'Enable Node.js inspector with break')
.option('--test-timeout <time>', 'Default timeout of a test in milliseconds (default: 5000)')
.option('--bail <number>', 'Stop test execution when given number of tests have failed', { default: 0 })
.option('--retry <times>', 'Retry the test specific number of times if it fails', { default: 0 })
.help()

cli
Expand Down
7 changes: 7 additions & 0 deletions packages/vitest/src/types/config.ts
Expand Up @@ -597,6 +597,13 @@ export interface InlineConfig {
* Stop test execution when given number of tests have failed.
*/
bail?: number

/**
* Retry the test specific number of times if it fails.
*
* @default 0
*/
retry?: number
}

export interface TypecheckConfig {
Expand Down
10 changes: 10 additions & 0 deletions test/config/fixtures/retry/retry.test.ts
@@ -0,0 +1,10 @@
import { expect, test } from 'vitest'

let number = 0
test('should passed', () => {
expect(number++).toBe(3)
})

test('retry but still failed', () => {
expect(number++).toBe(4)
})
8 changes: 8 additions & 0 deletions test/config/fixtures/retry/vitest.config.ts
@@ -0,0 +1,8 @@
import { defineConfig } from 'vitest/config'

export default defineConfig({
test: {
include: ['*.test.ts'],
retry: 3,
},
})
26 changes: 26 additions & 0 deletions test/config/test/retry.test.ts
@@ -0,0 +1,26 @@
import path from 'node:path'
import { describe, expect, test } from 'vitest'
import { runVitest } from '../../test-utils'

const root = path.resolve('./fixtures/retry')
function run(testNamePattern?: string) {
return runVitest({
root,
testNamePattern,
})
}

describe('retry', () => {
test('should passed', async () => {
const { stdout } = await run('should passed')
expect(stdout).toContain('1 passed')
})

test('retry but still failed', async () => {
const { stdout } = await run('retry but still failed')
expect(stdout).toContain('expected 1 to be 4')
expect(stdout).toContain('expected 2 to be 4')
expect(stdout).toContain('expected 3 to be 4')
expect(stdout).toContain('1 failed')
})
})