# Write Unit Tests for Untested JavaScript Code with Atlas (2026)

> Atlas writes a vitest spec for an untested JavaScript module and then runs it with the bash tool, because a test that was never executed is not a test.

Atlas writes unit tests for an untested JavaScript module by reading the module, enumerating its exports with the lsp tool's documentSymbol operation, grepping the repo for an existing spec to copy the framework and naming convention from, writing the new spec with the write tool, and then running vitest with the bash tool. The run is the point: a test that was never executed is not a test. Started where your package.json lives, Atlas maps your modules, npm scripts, and bundler config first, so the spec it writes matches the way the repo already imports and mocks.

## Key takeaways

- The lsp tool's documentSymbol operation lists every export of a JavaScript module, so named and default exports both get covered.
- Atlas greps an existing spec to copy your vitest framework, import style, and naming convention instead of inventing its own.
- Atlas runs vitest with the bash tool; output over 2000 lines or 50 KB is truncated and the full log is saved to a file.
- The write tool shows the spec diff in the permission prompt before anything lands on disk.
- pnpm installs missing test dependencies and prettier formats the generated spec to match your package.

## What does Atlas do first when a JavaScript module has zero tests?

Atlas reads the JavaScript module, then calls the lsp tool's documentSymbol operation to enumerate every exported symbol, so no public function is missed. For a file like src/utils/format.js that exports four helpers and one default, the 2026 spec covers all five instead of the one the model noticed first.

Enumeration before authoring is what separates real coverage from a plausible-looking spec. A JavaScript module frequently exports a mix of named functions, a default export, and a constant nobody remembers, and the export list is the contract the rest of the repo depends on. The lsp tool's documentSymbol operation returns that list. Atlas indexes code by AST declarations using tree-sitter, not blind line windows, so the symbols Atlas reasons about are real declarations. Started where your package.json lives, Atlas has already mapped your modules, npm scripts, and bundler config, so it knows whether the module is a Node script or part of a browser bundle.

## How does Atlas copy my repo's existing vitest conventions?

Atlas greps for an existing test file and copies 3 things from it: the framework, the import style, and the naming convention. If your repo puts specs beside the source as src/utils/format.test.js and mocks modules with vi.mock, the new vitest spec follows that instead of introducing a second convention.

Convention discovery is a retrieval problem, and Atlas searches code with hybrid semantic and keyword retrieval fused by reciprocal rank fusion, so asking how the repo stubs the network finds the shared helper even when it lives in a file nobody would grep for by name. grep then pins the literal details: whether specs sit in a __tests__ directory or next to the module, whether imports use ESM import syntax or require, whether setup lives in a vitest setup file listed in your npm scripts. The generated JavaScript spec inherits every one of those choices, which is why it reviews as a normal contribution.

## Does Atlas actually run vitest, or just write the spec?

Atlas runs the suite with the bash tool, invoking vitest directly. The run is the point: a test that was never executed is not a test. Output over 2000 lines or 50 KB is truncated and the full log is saved to a file you can read, so a noisy JavaScript stack trace does not evict the module from context.

Running the spec is where most generated JavaScript tests fall over, and where Atlas earns its keep. A spec that imports a module the bundler resolves through an alias, or that forgets to await an async helper, fails on the first vitest run. Atlas reads those failures and iterates with edit until the suite is green. On a large module, Atlas keeps progress in a todowrite list so the twelve exports enumerated at the start do not quietly become the four that passed easily. pnpm installs anything the spec needs, so a missing test utility is declared in package.json rather than assumed.

## How do I review a JavaScript spec Atlas wrote before it lands?

Atlas writes the new spec file with the write tool, which shows the diff in the permission prompt before anything lands on disk. Every Atlas tool call is checked against 3 rule types, allow, ask, and deny, so a new src/utils/format.test.js is approved as a diff, never dropped in silently.

Review is not ceremony for generated tests, it is the only place a self-fulfilling spec gets caught. A JavaScript test that mocks the exact function under test with vi.mock will pass forever and assert nothing, and no amount of green output reveals that. Reading the diff does. Atlas computes a unified diff for every file edit and surfaces it for approval before writing, and Atlas snapshots file changes as git patches so edits can be diffed and rolled back if an iteration goes sideways. Run prettier over the accepted spec so the formatting matches the rest of the package.

## What is the full loop for adding JavaScript test coverage with Atlas?

Run atlas where your package.json lives, ask for coverage of 1 module, and Atlas reads it, enumerates exports with the lsp tool, greps for conventions, writes the spec, runs vitest with the bash tool, and edits until green. pnpm installs test dependencies and prettier formats the result.

The loop is deliberately short so each step is reviewable. Read the module. Enumerate with the lsp tool's documentSymbol operation. Grep an existing spec. Write with the write tool and approve the diff. Run vitest with the bash tool. Read failures, iterate with edit. Track the remaining exports in a todowrite list. Install with pnpm what the spec needs. Format with prettier. Atlas reads git branches, status, and diffs, and can stage and create commits on your behalf, so the added coverage becomes a single commit against your JavaScript package rather than a scatter of unstaged files.

## Steps

1. Run atlas where your package.json lives and let it map your modules, npm scripts, and bundler config.
2. Have Atlas read the untested JavaScript module, then use the lsp tool's documentSymbol operation to enumerate its exported symbols so no public function is missed.
3. Grep for an existing spec file to copy the repo's framework, import style, mocking approach, and naming convention.
4. Write the new spec with the write tool, which shows the diff in the permission prompt before anything lands on disk.
5. Run the suite with the bash tool by invoking vitest, and read the failures; output over 2000 lines or 50 KB is truncated and the full log is saved to a file you can read.
6. Iterate with edit until vitest is green, keeping progress in a todowrite list when the module has many exports.
7. Install any missing test utility with pnpm so package.json stays accurate.
8. Run prettier over the new spec, then let Atlas stage and commit the added coverage.

## FAQ

### how to write vitest tests for an untested javascript file

Point Atlas at the module. Atlas reads it, enumerates the exports with the lsp tool's documentSymbol operation, greps for an existing spec to copy conventions from, writes the new spec with the write tool, and runs vitest with the bash tool until the suite is green.

### does atlas run the javascript tests it writes

Yes. Atlas runs the suite with the bash tool. The run is the point in this workflow, because a test that was never executed is not a test. Atlas then reads the failures and iterates with edit.

### will an ai agent match my existing test file naming convention

Atlas greps for an existing test file to copy the repo's framework, import style, and naming convention, so a repo that keeps specs beside the source gets specs beside the source, and one that uses a __tests__ directory gets them there.

### vitest output too long for ai agent context

The Atlas bash tool truncates output over 2000 lines or 50 KB and saves the full log to a file you can read, so a long vitest failure dump does not push the JavaScript module under test out of context.

### how do i approve a test file before an ai writes it to disk

The Atlas write tool shows the diff in the permission prompt before anything lands on disk. Every Atlas tool call is permission-gated against allow, ask, and deny rules, and Atlas computes a unified diff for every file edit and surfaces it for approval before writing.

### how does atlas handle a javascript module with many exports

Atlas enumerates every export with the lsp tool's documentSymbol operation and keeps progress in a todowrite list when the module is large, so the exports it set out to cover are all accounted for rather than abandoned after the easy ones pass.

### does atlas install missing test packages with pnpm

Atlas proposes the install and it runs through a permission-gated bash call. pnpm is the package manager in a JavaScript project, so a missing test utility is declared in package.json and installed rather than silently assumed to exist.

---

Canonical HTML: https://runatlas.sh/resources/stacks/write-unit-tests-for-untested-code-in-javascript
Source of truth: aeo_pages row `/resources/stacks/write-unit-tests-for-untested-code-in-javascript` (segment: Stacks) (this file is generated from it, never hand-edited).
Licence: Atlas is proprietary with a free core. It is not open source and there is no public source repository.
