AI Test Gen

AI-Powered Test Generation for Modern Applications

Get Started See Examples

Features

AI-Powered Test Generation

Leverages OpenAI, Anthropic, or Gemini to generate comprehensive tests for your code.

Multiple Framework Support

Works with React, Next.js, Vue.js, Svelte, Express, Koa, Hapi, Fastify, Hono, NestJS, and GraphQL.

VS Code Extension

Seamlessly integrate into your development workflow with our VS Code extension.

CI Mode

Perfect for continuous integration with automated dependency installation and standardized exit codes.

Customizable Tests

Configure test style, naming conventions, and coverage strategies to match your preferences.

Free AI Option

Uses Google's Gemini by default, allowing you to generate tests without paid API keys.

Installation

CLI Tool

npm install -g auto-test

VS Code Extension

Search for "Auto-Test" in the VS Code marketplace or install directly:

code --install-extension auto-test

Usage

CLI Usage

# Generate tests for current directory
auto-test

# Generate tests for a specific file
auto-test path/to/file.js

# Generate tests with CI mode
auto-test --ci

# Use a specific AI provider
auto-test --provider openai

VS Code Extension

Right-click on a file or folder in VS Code and select "Generate Tests" from the context menu.

Or use the command palette (Ctrl+Shift+P / Cmd+Shift+P) and search for "Auto-Test: Generate Tests".

Supported Frameworks

React Component Tests

import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import { UserProfile } from './UserProfile';

describe('UserProfile', () => {
  test('displays user information correctly', () => {
    const user = { name: 'John Doe', email: 'john@example.com' };
    render(<UserProfile user={user} />);
    expect(screen.getByText('John Doe')).toBeInTheDocument();
    expect(screen.getByText('john@example.com')).toBeInTheDocument();
  });

  test('handles edit button click', () => {
    const onEditMock = jest.fn();
    render(<UserProfile user={{ name: 'John' }} onEdit={onEditMock} />);
    fireEvent.click(screen.getByRole('button', { name: /edit/i }));
    expect(onEditMock).toHaveBeenCalled();
  });
});

Express API Tests

import request from 'supertest';
import app from './app';
import { createUser, getUserById } from './userService';

jest.mock('./userService');

describe('User API', () => {
  test('GET /users/:id returns user data', async () => {
    (getUserById as jest.Mock).mockResolvedValue({
      id: '123',
      name: 'Jane Doe'
    });
    
    const response = await request(app).get('/users/123');
    
    expect(response.status).toBe(200);
    expect(response.body).toEqual({
      id: '123',
      name: 'Jane Doe'
    });
  });
});

Vue.js Component Tests

import { mount } from '@vue/test-utils';
import UserProfile from './UserProfile.vue';

describe('UserProfile', () => {
  test('displays user information correctly', () => {
    const user = { name: 'John Doe', email: 'john@example.com' };
    const wrapper = mount(UserProfile, {
      props: { user }
    });
    
    expect(wrapper.text()).toContain('John Doe');
    expect(wrapper.text()).toContain('john@example.com');
  });

  test('emits edit event when button clicked', async () => {
    const wrapper = mount(UserProfile, {
      props: { user: { name: 'John' } }
    });
    
    await wrapper.find('button').trigger('click');
    expect(wrapper.emitted()).toHaveProperty('edit');
  });
});

NestJS Tests

import { Test, TestingModule } from '@nestjs/testing';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';

describe('UsersController', () => {
  let controller: UsersController;
  let service: UsersService;

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      controllers: [UsersController],
      providers: [
        {
          provide: UsersService,
          useValue: {
            findAll: jest.fn().mockResolvedValue([
              { id: '1', name: 'John' },
              { id: '2', name: 'Jane' },
            ]),
            findOne: jest.fn().mockImplementation((id) =>
              Promise.resolve({ id, name: 'Test User' }),
            ),
          },
        },
      ],
    }).compile();

    controller = module.get(UsersController);
    service = module.get(UsersService);
  });

  it('should return all users', async () => {
    expect(await controller.findAll()).toEqual([
      { id: '1', name: 'John' },
      { id: '2', name: 'Jane' },
    ]);
    expect(service.findAll).toHaveBeenCalled();
  });
});

GraphQL Tests

import { createTestClient } from 'apollo-server-testing';
import { ApolloServer } from 'apollo-server';
import { typeDefs } from './schema';
import { resolvers } from './resolvers';
import { UserService } from './user-service';

jest.mock('./user-service');

describe('GraphQL API', () => {
  let query, mutate;
  
  beforeEach(() => {
    const server = new ApolloServer({
      typeDefs,
      resolvers,
    });
    
    const testClient = createTestClient(server);
    query = testClient.query;
    mutate = testClient.mutate;
    
    (UserService.findById as jest.Mock).mockResolvedValue({
      id: '123',
      name: 'Test User',
      email: 'test@example.com'
    });
  });
  
  test('queries a user by id', async () => {
    const USER_QUERY = `
      query GetUser($id: ID!) {
        user(id: $id) {
          id
          name
          email
        }
      }
    `;
    
    const result = await query({ 
      query: USER_QUERY, 
      variables: { id: '123' } 
    });
    
    expect(result.errors).toBeUndefined();
    expect(result.data.user).toEqual({
      id: '123',
      name: 'Test User',
      email: 'test@example.com'
    });
  });
});

Configuration

Create a .aitestrc file in your project root to customize settings:

{
  "testRunner": "jest",
  "modelProvider": "gemini",
  "model": "gemini-pro",
  "testNamingConvention": "camelCase",
  "testFileExtension": "ts",
  "testFileSuffix": ".spec",
  "generateMocks": true,
  "testDataStrategy": "comprehensive",
  "includeComments": true,
  "excludePatterns": ["**/*.d.ts", "**/node_modules/**"]
}