How to Use Qodo for Automatic Test Generation in 2026

How to Use Qodo for Automatic Test Generation in 2026

Qodo (formerly CodiumAI) generates unit tests automatically using AI. Install Qodo Gen in VS Code or JetBrains, select a function, run /test, and get a complete test file with assertions for happy paths, edge cases, and error scenarios. This guide covers setup, the test generation workflow, and what to do with the output.

Key Takeaways

Qodo Gen is the IDE extension. Install it from the VS Code marketplace or JetBrains plugin store. The test generation capability lives here.

The /test command is the core workflow. Select a function, run /test, get tests. No config required for basic use.

Qodo analyzes branches, not just signatures. Generated tests cover the logic paths inside the function — conditions, error throws, return variations — not just "call with valid args."

AI-generated tests still need review. The tests are a starting point. Verify assertions match your actual expectations and add domain-specific scenarios the AI doesn't know about.

Setup

Qodo test generation requires the Qodo Gen extension. Install it from:

  • VS Code Marketplace: Search "Qodo Gen", install the extension
  • JetBrains Plugin Store: Search "Qodo Gen" in Settings → Plugins

After installation, sign in to your Qodo account. The free tier provides 75 credits per month — enough for regular personal use. Teams use the $30/user/month Teams plan for unlimited generation.

No project-level configuration is required to start generating tests. Qodo reads your existing test files to understand patterns (naming conventions, assertion style, test framework), so having some existing tests improves the output quality.


The /test command

The primary test generation workflow:

  1. Open a source file in VS Code
  2. Select a function or class you want tests for (or place your cursor inside the function)
  3. Open the Qodo Gen chat panel (Ctrl+Shift+G or the Qodo icon in the sidebar)
  4. Type /test
  5. Qodo generates a test file

You can also right-click on selected code and choose "Generate Tests" from the context menu if you prefer not to use the chat panel.

The generated file appears in the chat panel as a code block you can copy, or as a diff you can apply directly to your project.


What Qodo analyzes

Before generating tests, Qodo analyzes:

The function signature:

  • Parameter names and types (TypeScript types are used when available)
  • Return type
  • Async vs sync
  • Exported or internal

The function body:

  • Conditional branches — each if/else and switch generates test cases
  • Error throws — each throw new Error() generates a test for that error condition
  • External dependencies — what gets called, what needs mocking
  • Return variations — different values returned in different branches

Existing test files:

  • What test framework you're using (Jest, Vitest, Mocha, pytest, JUnit, etc.)
  • Naming conventions (describe blocks, it vs test, etc.)
  • How you mock dependencies (jest.mock, vi.mock, sinon, etc.)
  • Assertion style (jest.expect, chai assert, etc.)

Using existing patterns makes the generated tests fit naturally into your codebase without style inconsistencies.


Example: TypeScript function

Given this function:

// src/services/discount.ts

export async function applyDiscount(
  orderId: string,
  couponCode: string
): Promise<number> {
  const order = await db.orders.findById(orderId);
  if (!order) {
    throw new Error(`Order ${orderId} not found`);
  }

  const coupon = await db.coupons.findByCode(couponCode);
  if (!coupon) {
    throw new Error(`Coupon ${couponCode} is invalid`);
  }

  if (coupon.expiresAt < new Date()) {
    throw new Error(`Coupon ${couponCode} has expired`);
  }

  const discountAmount = order.total * (coupon.percent / 100);
  return order.total - discountAmount;
}

Qodo generates tests covering:

// src/services/discount.test.ts

import { applyDiscount } from './discount';

jest.mock('../db');

describe('applyDiscount', () => {
  const mockOrder = { id: 'order-1', total: 100 };
  const mockCoupon = {
    code: 'SAVE20',
    percent: 20,
    expiresAt: new Date(Date.now() + 86400000), // tomorrow
  };

  beforeEach(() => {
    jest.clearAllMocks();
  });

  it('applies discount correctly when order and coupon are valid', async () => {
    db.orders.findById.mockResolvedValue(mockOrder);
    db.coupons.findByCode.mockResolvedValue(mockCoupon);

    const result = await applyDiscount('order-1', 'SAVE20');
    expect(result).toBe(80); // 100 - 20%
  });

  it('throws when order is not found', async () => {
    db.orders.findById.mockResolvedValue(null);

    await expect(applyDiscount('nonexistent', 'SAVE20'))
      .rejects.toThrow('Order nonexistent not found');
  });

  it('throws when coupon code is invalid', async () => {
    db.orders.findById.mockResolvedValue(mockOrder);
    db.coupons.findByCode.mockResolvedValue(null);

    await expect(applyDiscount('order-1', 'INVALID'))
      .rejects.toThrow('Coupon INVALID is invalid');
  });

  it('throws when coupon has expired', async () => {
    const expiredCoupon = {
      ...mockCoupon,
      expiresAt: new Date(Date.now() - 86400000), // yesterday
    };
    db.orders.findById.mockResolvedValue(mockOrder);
    db.coupons.findByCode.mockResolvedValue(expiredCoupon);

    await expect(applyDiscount('order-1', 'SAVE20'))
      .rejects.toThrow('Coupon SAVE20 has expired');
  });

  it('handles 0% discount correctly', async () => {
    const zeroCoupon = { ...mockCoupon, percent: 0 };
    db.orders.findById.mockResolvedValue(mockOrder);
    db.coupons.findByCode.mockResolvedValue(zeroCoupon);

    const result = await applyDiscount('order-1', 'FREE0');
    expect(result).toBe(100); // no discount applied
  });

  it('handles 100% discount correctly', async () => {
    const fullCoupon = { ...mockCoupon, percent: 100 };
    db.orders.findById.mockResolvedValue(mockOrder);
    db.coupons.findByCode.mockResolvedValue(fullCoupon);

    const result = await applyDiscount('order-1', 'FREE100');
    expect(result).toBe(0);
  });
});

Seven test cases generated from one function — covering all three error paths, the success path, and two edge cases (0% and 100% discounts).

The mocking setup matches Jest's jest.mock pattern and uses mockResolvedValue for async db calls. If your project uses Vitest, Qodo uses vi.mock and vi.fn().mockResolvedValue instead.


PR-integrated test suggestions

Beyond the IDE command, Qodo's PR agent flags test gaps on every PR. When you open a PR that adds or modifies functions without corresponding test changes, Qodo comments:

### Test Coverage

2 new functions added without tests:
- `applyDiscount()` in src/services/discount.ts
- `validateCoupon()` in src/utils/coupon.ts

Click "Generate Tests" to create tests for these functions.

The "Generate Tests" link in the PR comment triggers Qodo to generate test suggestions in-thread. You can copy the generated tests, apply them locally, and push a follow-up commit.

This workflow catches test gaps at review time rather than at post-merge discovery — when the function is fresh and the context is clear.


Reviewing the generated output

AI-generated tests are a starting point, not the final answer. Before committing:

Verify assertions are meaningful. Check that each expect() asserts actual behavior, not just that the function was called. A test that only verifies applyDiscount was called is not a useful test.

Add domain knowledge the AI doesn't have. Qodo doesn't know that in your system, discounts can never bring the total below a $1 minimum, or that expired coupons should log an audit event. Add tests for business rules that aren't visible in the function signature.

Check mock accuracy. Qodo infers how to mock dependencies, but the inference can be wrong for complex setups. Verify that mocked return values match the real shape of your data.

Remove redundant tests. Qodo sometimes generates multiple tests that verify the same behavior slightly differently. Trim these down to keep the test suite focused.

Add tests for scenarios Qodo missed. Common gaps: tests for the interaction between two conditions being true simultaneously, tests for large inputs, tests for concurrent access if relevant.


Supported languages and frameworks

Qodo Gen test generation works with:

Languages: TypeScript, JavaScript, Python, Java, Go, C#, Ruby, PHP, Kotlin, Scala

Test frameworks (by language):

  • TypeScript/JavaScript: Jest, Vitest, Mocha, Jasmine
  • Python: pytest, unittest
  • Java: JUnit, TestNG
  • Go: testing package
  • C#: NUnit, xUnit, MSTest

Test generation quality varies by language. TypeScript and Python have the strongest support — Qodo's understanding of type information and common patterns is most accurate there. Java and Go are solid. Less common languages may produce tests that require more editing.


When test generation works best

Well-structured, single-purpose functions. Functions that do one thing with clear input/output relationships generate excellent tests. Functions with many side effects, global state mutations, or complex dependency trees require more manual editing.

TypeScript with strict types. Type information helps Qodo understand exactly what inputs are valid and what the function promises to return. Untyped JavaScript produces less precise tests.

Codebases with existing tests. Qodo learns from your existing test patterns. Projects with zero tests produce valid but generic tests; projects with consistent test conventions produce tests that match your style.

Business logic functions. Calculation, validation, transformation, and rule-evaluation functions — pure or near-pure logic — generate the most valuable tests. These are also the hardest to manually keep comprehensive.


What test generation doesn't replace

Qodo generates unit tests. Unit tests verify that functions produce correct output for given inputs. They don't verify:

  • That the function is called correctly by its callers — integration test territory
  • That the database queries return expected results — integration or E2E test territory
  • That the UI shows users the right information — E2E test territory
  • That the deployed application works end-to-end — E2E test territory

AI-generated unit tests are one layer of a complete testing strategy. They don't replace browser-based E2E tests that validate actual user flows in a deployed environment.

A function that passes all unit tests can still cause a broken user experience if the surrounding system isn't tested — wrong API endpoint, missing feature flag, deployment configuration error. Unit tests are necessary, not sufficient.


Getting started

  1. Install Qodo Gen from VS Code Marketplace or JetBrains Plugin Store
  2. Sign in (free tier: 75 credits/month)
  3. Open a source file with functions you want to test
  4. Select a function, open the Qodo Gen panel, type /test
  5. Review the generated tests, edit as needed, add to your test suite

For teams: the $30/user/month Teams plan removes credit limits and adds the PR integration that flags test gaps on every pull request.


Qodo covers unit test generation. For browser-based E2E tests that validate deployed user flows — login, checkout, form submissions, navigation — HelpMeTest provides AI-generated browser tests, self-healing selectors, and 24/7 monitoring. Free tier includes 10 tests and unlimited health checks.

Read more