---
title: "Generate Unit Tests for Existing Code"
source: https://docs.autohand.ai/tutorials/generate-unit-tests
---

# Generate Unit Tests for Existing Code

Add comprehensive unit tests to untested code with proper assertions, edge cases, and mocking. No more writing boilerplate by hand.

Beginner 10 min

autohand "Write unit tests for src/utils/validation.js. Cover all exported functions with happy path, edge cases, and error scenarios. Use Jest."

## What you'll learn

-   How to find which files need tests most
-   How to write prompts that produce useful test coverage
-   How to review and run generated tests
-   How to iterate toward higher coverage

## Before you start

Make sure your project has the following in place.

### Requirements

-   **Autohand Code installed.** Run `autohand --version` to verify. See [Your First Autohand Session](/docs/tutorials/your-first-session.html) if you need to set up.
-   **A testing framework installed.** This tutorial uses Jest, but Autohand works with Vitest, Mocha, and others. Run `npm install --save-dev jest` if you do not have it yet.
-   **The source file you want tested.** The agent reads the file directly, so it needs to exist in your project.

### Project setup

Add a test script to your package.json if you do not have one yet.

**Tip:** If your project uses ES modules, add `"transform": {}` and set `"type": "module"` in package.json, or configure Babel. The agent can help you set this up if you ask.

## Step 1: Identify untested code

Before writing tests, it helps to know where your gaps are. Ask Autohand to check your coverage first.

The agent runs `jest --coverage`, reads the output, and returns a summary. You might see something like this.

Files at 0% are the best starting point. You get the most impact per prompt because you are going from nothing to covered rather than patching small gaps.

## Step 2: Write the test prompt

A good test prompt names the file, names the framework, and tells the agent what kinds of cases to cover. Here is the pattern that works well.

The agent reads `validation.js`, identifies every exported function, and writes a test file. For a module that looks like this:

The agent produces a test file covering each function with multiple cases per function.

## Step 3: Review the generated tests

The agent writes the file to `src/utils/validation.test.js` and shows you the content. A well-generated test file looks like this.

Look for a few things before accepting the output. Each `describe` block should map to one function. Test names should read like plain English sentences. Every assertion should test exactly one thing.

**Tip:** If a generated test description is vague ("works correctly", "handles input"), ask the agent to rewrite it: "Rename the test descriptions to be specific about the input and expected output."

## Step 4: Run the test suite

Run the tests right away to confirm they all pass against your current implementation.

If a test fails, it usually means one of two things. Either the generated test has the wrong expected value, or the source function has a bug that the test just uncovered. Both are useful outcomes.

Hand the failure output back to the agent.

The agent reads the regex in your source file, identifies that the pattern does not match the test input, and corrects whichever side is wrong. It shows you the diff before writing.

## Step 5: Improve coverage

Once the initial tests pass, you can ask for additional edge cases to push coverage higher. This is useful when you want to hit a specific coverage target before merging.

You can also ask for specific scenarios you have thought of yourself.

Check coverage after each round.

**Tip:** 100% coverage is not always the goal. Aim for the coverage that matches the risk profile of the code. Critical path validation logic deserves near-complete coverage. Internal utility functions used only by other tested code need less.

## Step 6: Best practices

These habits make the generated output more useful and easier to maintain.

-   **Name the file explicitly.** "Write tests for validation.js" is better than "write tests for the validation utilities". The agent needs the path to read the source.
-   **Name the framework.** "Use Jest" or "use Vitest" removes any guessing. Different frameworks have different assertion APIs and the agent will match accordingly.
-   **Ask for the case types you want.** "Happy path, edge cases, and error scenarios" produces three times the coverage compared to a plain request. Be explicit.
-   **Keep test files next to source files.** `validation.test.js` beside `validation.js` is easier to find than a separate `__tests__` directory. Tell the agent where you want the file placed if your convention differs.
-   **Review mocks carefully.** When the agent generates mocks for dependencies like database clients or HTTP calls, check that the mock behavior matches how the real dependency actually works. A mock that is wrong in the wrong direction makes a bad test pass.

## What you learned

-   Used coverage reports to find the most impactful files to test
-   Wrote specific prompts that produce thorough test cases
-   Reviewed generated tests for correctness and clarity
-   Iterated with follow-up prompts to increase coverage

### Try next

autohand "Write tests for every file in src/services/ that has less than 50% coverage. Use Jest and cover error scenarios."

### Related tutorials

[

#### Add Integration Tests to an API

Write integration tests that verify your API endpoints work correctly with real database interactions.

](/docs/tutorials/add-integration-tests.html)[

#### Fix Failing Tests with Debugging Agent

Use Autohand's debugging workflow to diagnose and fix failing tests systematically.

](/docs/tutorials/fix-failing-tests-debugging.html)