Why You Need Smart Test Prompts
Writing tests is one of the most time-consuming parts of development. A typical developer spends 30–40% of their coding time on tests — and yet many skip them due to deadlines. AI can change that. With the right prompts, you can generate unit tests and integration tests in seconds, not hours.
This article collects 10 prompts I actually use daily in my own workflow. They work with pytest, unittest, and Jest. Each prompt includes a real usage example and a note on when to use it.
Prerequisite: You should be familiar with basic testing concepts (mocking, fixtures, assertions). If not, check the pytest documentation or Jest docs.
1. Generate Unit Tests for a Pure Function
Prompt:
Write unit tests for the following Python function using pytest.
Cover: normal cases, edge cases (empty input, negative values, max int), and expected exceptions.
Use parametrize for multiple inputs.
Function:
{function_code}
Example:
def calculate_discount(price: float, discount_percent: float) -> float:
if not isinstance(price, (int, float)) or not isinstance(discount_percent, (int, float)):
raise TypeError("Both arguments must be numbers")
if price < 0 or discount_percent < 0:
raise ValueError("Negative values not allowed")
return round(price * (1 - discount_percent / 100), 2)
Generated tests:
import pytest
from discount import calculate_discount
@pytest.mark.parametrize("price, discount, expected", [
(100, 10, 90.0),
(0, 50, 0.0),
(1.5, 0, 1.5),
(999999.99, 99.99, 0.01),
])
def test_calculate_discount_valid(price, discount, expected):
assert calculate_discount(price, discount) == expected
def test_negative_price():
with pytest.raises(ValueError):
calculate_discount(-10, 20)
def test_non_numeric_input():
with pytest.raises(TypeError):
calculate_discount("100", 10)
When to use: Every pure function you write. This is the most common test generation task.
2. Mock External API Calls in Integration Tests
Prompt:
Write integration tests for {function_name} using pytest and pytest-mock.
Mock the external HTTP call using requests_mock or mocker.patch.
Test: success response, 404, 500, timeout.
Example:
import requests
def get_user_data(user_id: int) -> dict:
resp = requests.get(f"https://api.example.com/users/{user_id}", timeout=5)
resp.raise_for_status()
return resp.json()
Generated tests:
import pytest
import requests_mock
from user_service import get_user_data
def test_get_user_success():
with requests_mock.Mocker() as m:
m.get("https://api.example.com/users/1", json={"id": 1, "name": "Alice"})
result = get_user_data(1)
assert result["name"] == "Alice"
def test_get_user_not_found():
with requests_mock.Mocker() as m:
m.get("https://api.example.com/users/999", status_code=404)
with pytest.raises(requests.exceptions.HTTPError):
get_user_data(999)
When to use: Any function that calls an external service (REST API, database, file system).
3. Generate Jest Tests for a React Component
Prompt:
Write Jest + React Testing Library tests for the following React component.
Test: renders correctly, handles empty props, triggers onClick, displays loading state.
Example component:
function UserCard({ user, onDelete }) {
if (!user) return <p>No user data</p>;
return (
<div>
<h2>{user.name}</h2>
<p>Email: {user.email}</p>
<button onClick={() => onDelete(user.id)}>Delete</button>
</div>
);
}
Generated tests:
import { render, screen, fireEvent } from '@testing-library/react';
import UserCard from './UserCard';
test('renders user name and email', () => {
render(<UserCard user={{ id: 1, name: 'Alice', email: 'alice@test.com' }} />);
expect(screen.getByText('Alice')).toBeInTheDocument();
expect(screen.getByText('Email: alice@test.com')).toBeInTheDocument();
});
test('shows placeholder when no user', () => {
render(<UserCard user={null} />);
expect(screen.getByText('No user data')).toBeInTheDocument();
});
test('calls onDelete when button clicked', () => {
const mockDelete = jest.fn();
render(<UserCard user={{ id: 2, name: 'Bob' }} onDelete={mockDelete} />);
fireEvent.click(screen.getByText('Delete'));
expect(mockDelete).toHaveBeenCalledWith(2);
});
When to use: Any UI component — especially if you have many similar components.
4. Generate Fixtures for Database Tests
Prompt:
Create pytest fixtures for testing database operations with SQLAlchemy.
Use an in-memory SQLite database. Provide fixtures: db_session, sample_user, sample_product.
Include teardown that drops all tables after each test.
Generated fixtures:
import pytest
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from models import Base, User, Product
@pytest.fixture
def db_session():
engine = create_engine("sqlite:///:memory:")
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()
yield session
session.close()
Base.metadata.drop_all(engine)
@pytest.fixture
def sample_user(db_session):
user = User(name="Test User", email="test@example.com")
db_session.add(user)
db_session.commit()
return user
When to use: Any project with a database — this is a reusable pattern.
5. Test Asynchronous Code with pytest-asyncio
Prompt:
Write async unit tests for the following async function using pytest and pytest-asyncio.
Test: success case, exception handling, timeout.
Example:
async def fetch_data(url: str) -> dict:
async with aiohttp.ClientSession() as session:
async with session.get(url) as resp:
if resp.status != 200:
raise Exception(f"HTTP {resp.status}")
return await resp.json()
Generated tests:
import pytest
from unittest.mock import AsyncMock, patch
from fetch import fetch_data
@pytest.mark.asyncio
async def test_fetch_data_success():
mock_response = AsyncMock()
mock_response.status = 200
mock_response.json.return_value = {"key": "value"}
with patch("aiohttp.ClientSession.get", return_value=mock_response):
result = await fetch_data("http://example.com")
assert result == {"key": "value"}
When to use: Async functions are tricky to test — let AI handle the boilerplate.
6. Generate Test Coverage Report and Improve It
Prompt:
Analyze the following test coverage report (from pytest-cov).
Identify functions/modules with low coverage (<80%).
Generate additional tests to cover the missing lines.
Example input:
Name Stmts Miss Cover
----------------------------------------------
myapp/utils.py 50 10 80%
myapp/processor.py 30 20 33%
AI output:
# Add these tests for processor.py:
# Lines 15-18 (edge case: empty list)
def test_process_empty_list():
assert process([]) == []
# Lines 22-25 (error handling)
def test_process_invalid_input():
with pytest.raises(ValueError):
process([None])
When to use: Before a release to bump coverage quickly.
7. Generate Property-Based Tests with Hypothesis
Prompt:
Write property-based tests using the Hypothesis library for the following function.
Test invariants: result is always positive, function is idempotent, etc.
Example:
def normalize_name(name: str) -> str:
return name.strip().title()
Generated tests:
from hypothesis import given, strategies as st
from normalize import normalize_name
@given(st.text())
def test_normalize_name_always_stripped(s):
result = normalize_name(s)
assert result == result.strip()
@given(st.text())
def test_normalize_name_title_case(s):
result = normalize_name(s)
if result:
assert result[0].isupper()
When to use: Functions with complex input spaces (strings, numbers in ranges).
8. Generate Flaky Test Detector
Prompt:
Review the following test file for potential flakiness.
Look for: time-dependent assertions, hardcoded IDs, reliance on global state, unordered collections.
Suggest fixes.
Example fix suggestion:
# Flaky: assert get_current_time() == "2026-07-03"
# Fix: use freezegun or mock datetime
from freezegun import freeze_time
@freeze_time("2026-07-03")
def test_time():
assert get_current_time() == "2026-07-03"
When to use: When CI tests fail intermittently.
9. Generate Tests for Legacy Code (No Mocks)
Prompt:
Write integration tests for the following legacy Python code that has no dependency injection.
Use real file I/O (temporary files) and real database (SQLite in-memory).
Do not refactor the code — only add tests.
When to use: Legacy code that you cannot change but need to cover with tests.
10. Generate Test Documentation from Code
Prompt:
Generate a human-readable test summary from the following pytest output (verbose mode).
Group by test module, mark failed tests, and add suggestions for fixing.
When to use: Before a demo or release.
Putting It All Together: A Real Workflow
Let’s say you’re adding a new payment endpoint to your Django app. Here’s how I use these prompts:
- Prompt 1 — Generate unit tests for the
process_paymentfunction. - Prompt 2 — Mock the Stripe API call in integration tests.
- Prompt 6 — Run coverage, see that error handling is uncovered, generate more tests.
- Prompt 8 — Check for flaky tests (e.g., time-based discounts).
- Prompt 10 — Generate a summary for the PR description.
ASI Biont supports connecting to Stripe via API — learn more at asibiont.com/courses.
Conclusion
AI won't write perfect tests on its own — but with the right prompts, it can handle 80% of the boilerplate. You still need to review the logic, add edge cases, and ensure the tests actually fail when they should.
Start with the prompts above. Tweak them for your stack. In a month, you'll wonder how you ever wrote tests without them.
Next step: Pick one prompt from this list and use it on your actual code today. Then run pytest --cov and see the difference.
Comments