Use cases
Use cases

Automate Test Writing with AI — Codowave

Codowave writes tests for your untested code automatically. Connect your GitHub repo, label the issues, and get test PRs without assigning a developer.

6 min read

Automate Test Writing with AI

Test coverage gaps are one of the most common items on a technical debt backlog — and one of the hardest to clear. Writing tests for existing code is unglamorous, time-consuming, and rarely urgent enough to win sprint allocation against new features. So it doesn't get done.

Codowave has a dedicated Tester agent that writes tests as part of every issue run. You can also use Codowave explicitly for test-writing issues — labeling whole batches of "add tests to X" issues and letting Codowave process them systematically.

Start your 5-day trial

Why Test Writing Stays in the Backlog

The math is straightforward: writing good tests for a 200-line service with 4 dependencies takes 2-4 hours of careful work. The benefit — catching regressions earlier — accrues over months. In a sprint planning meeting, that trade loses to "add the new billing feature," every time.

Multiply that by 20 under-tested modules and you have a coverage gap that accumulates for years. When you eventually need to refactor, you don't have the safety net. The technical debt compounds.

The answer isn't "prioritize test coverage more aggressively in sprint planning." The answer is removing the human bottleneck from test writing for existing, stable code.


How Codowave Handles Test Writing

The Tester Agent

Every Codowave issue run ends with a Tester agent step. After the Coder writes the implementation and the Reviewer scores it, the Tester:

  1. Runs your existing test suite to establish a baseline
  2. Identifies functions and branches not covered by current tests
  3. Writes new tests targeting the coverage gaps
  4. Runs the full suite again to confirm everything passes
  5. Includes the new tests in the PR

For test-specific issues ("add unit tests for AuthService"), the Tester is the primary agent. The Planner identifies which methods need coverage, the Coder scaffolds the test structure, the Reviewer checks for completeness and edge cases, and the Tester runs and verifies.

Creating Test Issues in Bulk

The fastest way to run a test coverage push is to create GitHub issues in bulk for the modules you want covered:

Title: Add unit tests for UserService
Label: test-coverage, good-first-issue
Body: The UserService class (/src/services/user.service.ts) has no unit tests. 
      Add coverage for: createUser, updateUser, deleteUser, getUserById, 
      listUsers. Include edge cases for invalid inputs and not-found conditions.

Create one issue per module or service, label them consistently (test-coverage), and configure Codowave to pick up issues with that label. It processes them in parallel (Team plan) or sequentially (Pro plan) and opens one PR per issue.

What Good Test Output Looks Like

Codowave's test output matches your existing test patterns (learned via pattern memory). If you use Jest with describe/it blocks and factory functions for fixtures, the written tests will follow that structure. If you use pytest with fixtures and parametrize decorators, same story.

Example output (Node.js/Jest):

describe('UserService', () => {
  describe('createUser', () => {
    it('creates a user with valid input', async () => {
      const input = createUserInput({ email: 'test@example.com' });
      const result = await userService.createUser(input);
      expect(result.id).toBeDefined();
      expect(result.email).toBe('test@example.com');
    });

    it('throws ValidationError when email is missing', async () => {
      const input = createUserInput({ email: undefined });
      await expect(userService.createUser(input)).rejects.toThrow(ValidationError);
    });

    it('throws ConflictError when email already exists', async () => {
      await createUserInDb({ email: 'existing@example.com' });
      const input = createUserInput({ email: 'existing@example.com' });
      await expect(userService.createUser(input)).rejects.toThrow(ConflictError);
    });
  });
});

The Reviewer agent checks that:

  • Edge cases are covered (null inputs, boundary conditions, error paths)
  • Tests are independent (no shared mutable state between tests)
  • Mocks are appropriate and not over-mocked
  • Test descriptions are readable

Test Coverage Push: A Practical Workflow

Here's a repeatable workflow for a serious coverage push:

Week 1: Audit and Issue Creation

  1. Run your coverage tool (jest --coverage, pytest --cov, go test -cover) and export a report
  2. Identify the 20-30 modules with lowest coverage
  3. Create GitHub issues for each, labeling them test-coverage
  4. Install Codowave if you haven't already (free plan covers the first 3)

Week 2-3: Codowave Processes the Issues

Configure Codowave to pick up test-coverage issues. It processes them systematically:

  • Each issue run takes 20-45 minutes
  • Output: one PR per module with tests added
  • CI runs against the new tests
  • You review the PRs (or enable auto-merge for test-only PRs once you trust the output)

Week 4: Review and Merge

Your developers review the test PRs — faster than writing them from scratch, since you're reviewing rather than authoring. The coverage report after merging shows the improvement.

Ongoing: Add test-coverage to new modules as you build them. Codowave processes them when they appear.


Languages and Frameworks Supported

Codowave's Tester agent adapts to your stack. It reads your existing tests to understand patterns before writing new ones. Supported stacks include:

  • JavaScript/TypeScript — Jest, Mocha, Vitest, Testing Library
  • Python — pytest, unittest
  • Go — standard testing package, testify
  • Ruby — RSpec, Minitest
  • Java/Kotlin — JUnit, TestNG
  • Rust — standard test module
  • PHP — PHPUnit

If your test framework isn't listed, contact us — we add new frameworks regularly.


Test Writing vs. Full Issue Runs

Two distinct use cases:

Use CaseHow to Set It Up
Test coverage push (standalone)Create issues labeled test-coverage, configure Codowave to pick that label, run in parallel
Tests as part of every PRCodowave's Tester agent writes tests as part of every issue run by default — no separate setup

The second is automatic. If you add an endpoint, Codowave's Tester writes tests for it. If you fix a bug, it writes a regression test. You don't configure this separately.


What the Numbers Look Like

A team with 30 under-tested modules and the Team plan running over 3 weeks:

  • Issues created: 30 (one per module)
  • Issues processed by Codowave: 28 (2 were too ambiguous and got flagged for clarification)
  • PRs opened: 28
  • PRs merged (CI passed, human approved): 24
  • Lines of test code added: ~1,800
  • Coverage increase: 34% → 71% on those modules
  • Developer hours spent: ~8 hours reviewing PRs (vs. ~90 hours to write all tests manually)

These are illustrative estimates, not a guarantee — actual results depend on codebase complexity and issue quality.