10 Prompts for Writing Unit and Integration Tests That Actually Work

10 Prompts for Writing Unit and Integration Tests That Actually Work

Imagine this: you've just finished refactoring a critical payment module. You run pytest — and 47 tests pass. But in production, invoices are duplicated. Why? Because your tests covered the happy path but missed the race condition in the database transaction. If that sounds familiar, you're not alone. A 2024 survey by the State of Software Quality Report found that 64% of developers admit their test suites lack adequate coverage for edge cases.

Testing is not just about writing code that passes; it's about writing tests that fail meaningfully. But crafting those tests — especially for complex integrations — takes time and mental energy. That's where AI prompts come in. In this article, I'll share 10 battle-tested prompts for generating unit and integration tests with pytest, Jest, and unittest. These aren't theoretical — I use them daily in my own workflow.

Why Prompts for Tests?

Before diving in, a quick note on why prompts matter. Large Language Models (LLMs) like GPT-4o and Claude 3.5 are excellent at pattern recognition. Testing follows patterns: arrange, act, assert. If you give the AI a clear context — function signature, expected behavior, edge cases — it can generate comprehensive tests in seconds. The key is specificity. A vague prompt like "write tests for this function" yields generic output. A structured prompt with examples yields production-ready code.

10 Prompts for Unit and Integration Tests

Below are 10 prompts organized by framework and use case. Each includes a real usage example.

1. pytest: Basic Unit Test with Fixtures

Prompt:

Write a pytest test for a function calculate_discount(price: float, user_tier: str) -> float. Use fixtures for sample user tiers ("bronze", "silver", "gold"). Include edge cases: zero price, negative price, unknown tier.

Usage example:

import pytest

@pytest.fixture
def bronze_user():
    return {"tier": "bronze"}

def test_calculate_discount():
    from app.pricing import calculate_discount
    assert calculate_discount(100.0, "gold") == 20.0
    assert calculate_discount(0.0, "bronze") == 0.0
    with pytest.raises(ValueError):
        calculate_discount(-10.0, "silver")

This prompt works because it specifies the function signature, expected behavior, and edge cases. The AI will generate a fixture-based test that's clean and reusable.

2. Jest: React Component Test

Prompt:

Write a Jest + React Testing Library test for a LoginForm component that validates email format, shows error on empty password, and calls onSubmit with correct data. Mock the API call.

Usage example:

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

jest.mock('../api/auth', () => ({
  login: jest.fn().mockResolvedValue({ token: '123' }),
}));

test('shows error for invalid email', () => {
  render(<LoginForm />);
  fireEvent.change(screen.getByLabelText(/email/i), { target: { value: 'bad' } });
  expect(screen.getByText(/valid email/i)).toBeInTheDocument();
});

This prompt is effective because it specifies the component behavior and the mocking approach. The AI will generate tests that cover both UI behavior and API interaction.

3. unittest: Mocking External API

Prompt:

Write a unittest test for a WeatherService.get_temperature(city: str) that calls an external API. Use unittest.mock.patch to mock requests.get. Include a test for network timeout.

Usage example:

import unittest
from unittest.mock import patch
from app.weather import WeatherService

class TestWeatherService(unittest.TestCase):
    @patch('app.weather.requests.get')
    def test_get_temperature_success(self, mock_get):
        mock_get.return_value.json.return_value = {'main': {'temp': 22.5}}
        service = WeatherService()
        result = service.get_temperature('London')
        self.assertEqual(result, 22.5)

    @patch('app.weather.requests.get')
    def test_timeout(self, mock_get):
        mock_get.side_effect = TimeoutError
        service = WeatherService()
        with self.assertRaises(TimeoutError):
            service.get_temperature('London')

This prompt is specific about the mocking library (unittest.mock.patch) and the error case (timeout). The AI will generate a test that actually catches real-world failures.

4. pytest: Integration Test with Database

Prompt:

Write a pytest integration test for a UserRepository that uses SQLAlchemy with a PostgreSQL test database. Use pytest-postgresql fixture. Test create, read, update, and delete operations.

Usage example:

@pytest.mark.integration
def test_user_crud(postgresql):
    from app.repositories import UserRepository
    repo = UserRepository(postgresql)
    user = repo.create(name="Alice", email="alice@example.com")
    assert user.id is not None
    fetched = repo.get_by_id(user.id)
    assert fetched.name == "Alice"
    repo.update(user.id, name="Alicia")
    assert repo.get_by_id(user.id).name == "Alicia"
    repo.delete(user.id)
    assert repo.get_by_id(user.id) is None

This prompt works because it specifies the database fixture and the CRUD operations. The AI will generate a test that runs against a real test database, not a mock.

5. Jest: Async API Integration Test

Prompt:

Write a Jest integration test for a getUserOrders(userId) function that calls a REST API. Use fetch mock. Test successful response, empty response, and HTTP 500 error.

Usage example:

global.fetch = jest.fn();

test('returns orders on success', async () => {
  fetch.mockResolvedValueOnce({ ok: true, json: async () => [{ id: 1 }] });
  const orders = await getUserOrders('123');
  expect(orders).toHaveLength(1);
});

test('throws on server error', async () => {
  fetch.mockResolvedValueOnce({ ok: false, status: 500 });
  await expect(getUserOrders('123')).rejects.toThrow('Server error');
});

This prompt is effective because it explicitly lists the response scenarios (success, empty, error). The AI will generate tests that cover the full API contract.

6. pytest: Parametrized Tests for Edge Cases

Prompt:

Write a pytest parametrized test for a function validate_password(password: str) -> bool. Test edge cases: too short, no uppercase, no digit, valid password, empty string, Unicode characters. Use @pytest.mark.parametrize.

Usage example:

import pytest
from app.validation import validate_password

@pytest.mark.parametrize("password, expected", [
    ("Ab1", False),          # too short
    ("abcdef", False),       # no uppercase, no digit
    ("ABCDEF1", False),      # no lowercase
    ("Abcdef1", True),       # valid
    ("", False),             # empty
    ("Über1Pass", True),     # Unicode
])
def test_validate_password(password, expected):
    assert validate_password(password) == expected

This prompt is powerful because it specifies the test framework feature (@pytest.mark.parametrize) and lists specific edge cases. The AI will generate a compact, readable test that covers many scenarios.

7. unittest: Testing Class Inheritance

Prompt:

Write a unittest test for a base class Animal and subclass Dog. Test that Dog.speak() returns "Woof" and that Animal.speak() raises NotImplementedError.

Usage example:

import unittest
from app.animals import Animal, Dog

class TestAnimals(unittest.TestCase):
    def test_animal_speak_raises(self):
        with self.assertRaises(NotImplementedError):
            Animal().speak()

    def test_dog_speak(self):
        self.assertEqual(Dog().speak(), "Woof")

This prompt is simple but effective. It tests both the base class contract and the subclass implementation.

8. pytest: Testing Exception Handling

Prompt:

Write a pytest test for a function parse_config(file_path: str) that raises FileNotFoundError if file missing, json.JSONDecodeError if invalid JSON, and returns a dict on success. Use tmp_path fixture.

Usage example:

import json
import pytest
from app.config import parse_config

def test_parse_config_missing_file(tmp_path):
    with pytest.raises(FileNotFoundError):
        parse_config(tmp_path / "nonexistent.json")

def test_parse_config_invalid_json(tmp_path):
    f = tmp_path / "config.json"
    f.write_text("{invalid")
    with pytest.raises(json.JSONDecodeError):
        parse_config(f)

def test_parse_config_success(tmp_path):
    f = tmp_path / "config.json"
    f.write_text('{"key": "value"}')
    result = parse_config(f)
    assert result["key"] == "value"

This prompt is great because it uses tmp_path (a built-in pytest fixture) and covers both error and success paths.

9. Jest: Testing Redux Thunks

Prompt:

Write a Jest test for a Redux thunk fetchUser(id) that dispatches fetchUser.pending, then fetchUser.fulfilled on success, or fetchUser.rejected on error. Mock axios.

Usage example:

import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import axios from 'axios';
import { fetchUser } from './userSlice';

jest.mock('axios');
const middlewares = [thunk];
const mockStore = configureMockStore(middlewares);

test('dispatches fulfilled on success', async () => {
  axios.get.mockResolvedValue({ data: { id: 1, name: 'Alice' } });
  const store = mockStore({});
  await store.dispatch(fetchUser(1));
  const actions = store.getActions();
  expect(actions[0].type).toBe('user/fetchUser/pending');
  expect(actions[1].type).toBe('user/fetchUser/fulfilled');
});

This prompt is effective because it specifies the Redux pattern (thunk with pending/fulfilled/rejected) and the mocking library (axios).

10. pytest: Testing Async Code with asyncio

Prompt:

Write a pytest test for an async function fetch_data(url: str) -> dict that uses aiohttp. Use pytest-asyncio and mock aiohttp.ClientSession.get.

Usage example:

import pytest
from unittest.mock import AsyncMock, patch
from app.fetcher import fetch_data

@pytest.mark.asyncio
async def test_fetch_data_success():
    mock_response = AsyncMock()
    mock_response.__aenter__.return_value.json = AsyncMock(return_value={"key": "value"})
    with patch('aiohttp.ClientSession.get', return_value=mock_response):
        result = await fetch_data("http://example.com")
        assert result["key"] == "value"

This prompt works because it specifies the async framework (pytest-asyncio) and the mocking approach (AsyncMock). The AI will generate a test that actually runs async code correctly.

Putting It All Together

These 10 prompts form a toolkit for generating tests across different frameworks and scenarios. The key patterns to remember:

  1. Be specific about function signatures, expected inputs, and outputs.
  2. List edge cases explicitly — empty strings, invalid data, network errors.
  3. Specify the testing framework (pytest, Jest, unittest) and fixtures.
  4. Include mocking details — which library, what to mock, and how.

Testing is a skill that improves with practice. AI prompts can accelerate that practice by generating templates you can adapt. But remember: no prompt replaces human judgment. Always review generated tests for correctness, readability, and coverage of your specific domain logic.

Conclusion

Writing tests that catch real bugs — not just pass — requires thinking about failure modes. The 10 prompts in this article give you a starting point for generating comprehensive unit and integration tests with pytest, Jest, and unittest. Use them as templates, adapt them to your codebase, and you'll spend less time writing boilerplate and more time reasoning about edge cases. In the end, that's what makes a test suite valuable: not the number of tests, but the confidence they give you.

This article was written in July 2026. All tools and frameworks mentioned are current as of this date.

← All posts

Comments