Vitest retry feature and file‑system write operations: handling duplicate writes
0 reputation · 18 Jan 2024, 15:21 UTC
0 reputation · 18 Jan 2024, 15:21 UTC
When a Vitest test is marked with retry: n, the framework re‑executes the entire test function on each attempt, including any setup code that performs file‑system writes such as snapshot creation or log output. This behavior can produce duplicate writes if the test writes to the same path on every retry, potentially corrupting artifacts or causing noisy CI logs. The current documentation does not describe a built‑in way to isolate or reset side‑effects between retry attempts, leaving users to manage cleanup manually in hooks like beforeEach or afterEach.
31275 reputation · 18 Jan 2024, 23:40 UTC
No. As of the Vitest 1.x/2.x public API, there is no hook that runs specifically between retry attempts, no way to restrict a retry to only the assertion portion of a test, and no built-in side-effect isolation. When you set retry: n, Vitest re-executes the entire test function — including any inline setup that writes files — and it also re-runs the surrounding beforeEach/afterEach hooks on every attempt. Cleanup between attempts is your responsibility.
Confirmed behavior (stable, well-documented): the retry option re-runs the whole test closure per attempt, and beforeEach/afterEach fire per attempt. The retry mechanism has no concept of "setup vs. assertion" — it simply invokes the test function again after a failure.
Likely, but worth verifying against your exact version: hook ordering around retries and how task results are reported differed between the 1.x and 2.x lines, and there is no shipped automatic reset of file-system state, module state, or snapshot caches between attempts. Treat any claim about a future isolation feature as unverified until you check the current changelog and open GitHub discussions for your version.
Since you cannot skip setup on retries, make the writes safe to repeat:
expect.getState().currentTestName plus a timestamp.beforeEach. Because hooks run per attempt, deleting the target file or truncating a log in beforeEach gives you an effective "between attempts" cleanup point:import { beforeEach, it } from 'vitest';
import { rmSync } from 'node:fs';
beforeEach(() => {
rmSync('out/artifact.log', { force: true });
});
it('flaky writer', { retry: 2 }, () => {
// writes to out/artifact.log — safe now, each attempt starts clean
});writeFileSync) over append (appendFileSync) for anything a retry might repeat. Append-mode logs are the most common source of duplicated CI noise.beforeAll (which runs once per file, not per attempt) rather than inside the test body.A two-minute experiment settles it for your installed version: create a test with retry: 2 that appends a line to a file and fails on the first attempt, then count the lines. Also log inside beforeEach to confirm it fires per attempt. If line count equals attempt count, you have confirmed there is no isolation and the patterns above apply.
Community interest in retry isolation exists, but no automatic side-effect reset between attempts is known in core Vitest as of this writing. Check the release notes and the vitest-dev GitHub discussions for your version before designing around an assumed upcoming API.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.