12 Prompts for Writing Unit and Integration Tests with pytest, Jest, and unittest
Are you tired of writing repetitive test code? A well-crafted prompt can turn an LLM into a junior tester that follows your exact specifications. In this article, I share 12 prompts that have worked in real projects, ranging from simple pytest functions to property-based and mutation testing.
The prompts are structured in three levels: basic, advanced, and expert. Each prompt includes a task, the exact prompt to copy, and an example output. You can adapt them to your own codebase by replacing placeholders.
Why Test Generation with Prompts Works
Unit and integration tests have a predictable structure: set up inputs, call the code, assert the outcome. LLMs are good at recognizing common patterns. According to the pytest documentation (https://docs.pytest.org), using plain asserts makes tests easier to read. By stating your framework and expected behavior, you steer the model toward idiomatic code.
A common failure is that models invent edge cases or miss them. This is why the prompts include boundary conditions, mocks, and feature-specific checks. Always run the generated tests and inspect them as you would any code review.
How to Use the Prompts
- Replace function names and signatures with your own.
- Specify the exact error type for exception tests.
- For integration tests, provide a seed database or container configuration.
- Use the output as a starting point, not a finished artifact.
Basic Prompts
1. Generate a pytest Test File from a Function
Task: Build a first suite for a simple arithmetic function.
Prompt: "You are a senior Python developer. Write a pytest test file for the function multiply(a, b) that returns the product of two numbers. Include tests for positive, negative, and zero inputs."
Example result:
import pytest
from src.math_utils import multiply
def test_multiply_positive():
assert multiply(3, 4) == 12
def test_multiply_negative():
assert multiply(-2, 5) == -10
def test_multiply_zero():
assert multiply(0, 10) == 0
2. Create Jest Tests for a Pure Function
Task: Test a JavaScript utility function with typical and edge inputs.
Prompt: "Write a Jest test suite for formatName(first, last) which returns a capitalized full name. Include a test for empty strings and unusual whitespace."
Example result:
const { formatName } = require('./formatName');
describe('formatName', () => {
test('capitalizes both names', () => {
expect(formatName('john', 'doe')).toBe('John Doe');
});
test('handles empty strings', () => {
expect(formatName('', 'Doe')).toBe('Doe');
});
test('trims extra spaces', () => {
expect(formatName(' john ', ' doe ')).toBe('John Doe');
});
});
3. Expand a unittest TestCase with Boundary Conditions
Task: Improve an existing test class by covering limit values.
Prompt: "Extend this unittest TestCase with boundary tests for a function that returns 'valid' for numbers 1 to 100. Test the values 0, 1, 100, and 101."
Example result:
import unittest
def validate(n):
return "valid" if 1 <= n <= 100 else "invalid"
class TestValidator(unittest.TestCase):
def test_boundary_low(self):
self.assertEqual(validate(1), "valid")
def test_boundary_high(self):
self.assertEqual(validate(100), "valid")
def test_outside_low(self):
self.assertEqual(validate(0), "invalid")
def test_outside_high(self):
self.assertEqual(validate(101), "invalid")
4. Generate SetUp and TearDown in unittest
Task: Test a class that requires resource cleanup.
Prompt: "Create a unittest test case for a DatabaseConnection class. Use setUp to create a connection and tearDown to close it. Include a test for successful query."
Example result:
import unittest
class TestDatabaseConnection(unittest.TestCase):
def setUp(self):
self.conn = DatabaseConnection()
def tearDown(self):
self.conn.close()
def test_query(self):
self.assertEqual(self.conn.query("SELECT 1"), 1)
Advanced Prompts
5. Mock External API Calls with pytest
Task: Unit-test a function that calls a remote API.
Prompt: "Write a pytest test using unittest.mock to mock the requests.get method. The function fetch_user(id) should return a dict from JSON. Mock a successful response and a 404 error."
Example result:
from unittest.mock import patch, Mock
def fetch_user(user_id):
import requests
response = requests.get(f"https://api.example.com/users/{user_id}")
return response.json()
def test_fetch_user_success():
mock_response = Mock()
mock_response.status_code = 200
mock_response.json.return_value = {"id": 1, "name": "Alice"}
with patch("requests.get", return_value=mock_response) as mock_get:
result = fetch_user(1)
assert result == {"id": 1, "name": "Alice"}
mock_get.assert_called_once()
def test_fetch_user_404():
mock_response = Mock()
mock_response.status_code = 404
with patch("requests.get", return_value=mock_response):
result = fetch_user(999)
assert result == {}
6. Use Jest Mocks to Isolate a Module
Task: Mock a module dependency in Jest to avoid network calls.
Prompt: "Write a Jest test that mocks axios.get for a function loadComments(postId). Check that it returns a list of comments and handles a rejection."
Example result:
const axios = require('axios');
const { loadComments } = require('./comments');
jest.mock('axios');
test('loads comments', async () => {
axios.get.mockResolvedValue({ data: { comments: ['Good', 'Bad'] } });
const result = await loadComments(1);
expect(result).toEqual(['Good', 'Bad']);
});
test('handles failure', async () => {
axios.get.mockRejectedValue(new Error('Network error'));
await expect(loadComments(1)).rejects.toThrow('Network error');
});
7. Integration Test a FastAPI Endpoint with pytest
Task: Verify the full request/response cycle of a web endpoint.
Prompt: "Create a pytest integration test for a FastAPI GET /items/{id} endpoint. Use the TestClient to send a request and assert status code and body."
Example result:
from fastapi.testclient import TestClient
from main import app
def test_get_item():
client = TestClient(app)
response = client.get("/items/1")
assert response.status_code == 200
assert response.json() == {"id": 1, "name": "Widget"}
def test_get_item_missing():
client = TestClient(app)
response = client.get("/items/999")
assert response.status_code == 404
8. Test Database Interactions with Testcontainers in unittest
Task: Set up a real database for an integration test without local installation.
Prompt: "Use testcontainers.postgres.PostgresContainer in a unittest test to test a repository method that inserts a user."
Example result:
from testcontainers.postgres import PostgresContainer
class TestUserRepository(unittest.TestCase):
def test_insert_user(self):
with PostgresContainer("postgres:16") as postgres:
db_url = postgres.get_connection_url()
repo = UserRepository(db_url)
user = repo.insert("Alice")
self.assertIsNotNone(user.id)
self.assertEqual(user.name, "Alice")
Expert Prompts
9. Property-Based Testing with Hypothesis
Task: Validate a function for many inputs, not just hand-picked examples.
Prompt: "Write a property-based test using the hypothesis library for a function parse_command(args) that returns a dict. Use strategies for lists of strings and assert that the result is never empty."
Example result:
from hypothesis import given, strategies as st
def parse_command(args):
return {arg: True for arg in args}
@given(st.lists(st.text()))
def test_parse_command_returns_dict(args):
result = parse_command(args)
assert isinstance(result, dict)
10. Mutation Testing with mutmut
Task: Find gaps in your pytest suite by introducing small changes (mutants) and checking if tests fail.
Prompt: "Explain how to run mutation testing with mutmut on a specific module, and what metrics you should look for. Provide the command and an example of a mutant that would be detected."
Example result:
pip install mutmut
mutmut run --paths-to-mutate src/math_utils.py
mutmut html
If your tests don't catch a mutated + becoming -, the mutant survives. The report shows lines that need attention.
11. Test Coverage with pytest-cov
Task: Measure code coverage and enforce a minimum threshold.
Prompt: "Generate a pytest command that calculates coverage with pytest-cov, excludes the tests directory, and fails if coverage is below 80%."
Example result:
pytest --cov=src --cov-report=term-missing --cov-fail-under=80
This command displays missing lines and fails if the total coverage drops below 80%.
12. Parallel Test Execution with pytest-xdist
Task: Speed up a large test suite by running tests on multiple CPUs.
Prompt: "Explain how to run pytest on multiple CPUs with -n auto, and how to mark tests that must run sequentially."
Example result:
pip install pytest-xdist
pytest -n auto --dist loadscope
Tests that share resources can be serialized with @pytest.mark.serial and adding --dist loadfile or --dist loadscope to prevent them from running in parallel.
Conclusion
These 12 prompts cover the most common test scenarios in pytest, Jest, and unittest. The key is to be explicit about behavior, edge cases, and mocking. Always review generated tests—models are not infallible. As the official Jest docs recommend, "make tests that are simple and have a clear intent."
Start with a simple prompt and iterate. You'll soon have a suite that catches real defects and makes refactoring safe.
References
- pytest Documentation: https://docs.pytest.org/
- Jest Documentation: https://jestjs.io/
- unittest (Python standard library): https://docs.python.org/3/library/unittest.html
- Hypothesis Documentation: https://hypothesis.readthedocs.io/
- mutmut: https://mutmut.readthedocs.io/
Comments