19 / 87 · 02 AI-Augmented Test Design · Boundary-Value Analysis and Equivalence Partitioning via AI← prev⊞ allnext →☰ Read as one page
4.2Boundary-Value Analysis with AI
The Prompt Pattern
Describe the input constraints and let the LLM enumerate every boundary:
Given the following input field constraints, generate boundary value test cases:
Field: age (integer)
Valid range: 18-65 (inclusive)
Required: yes
Generate test values for:
- Just below minimum (17)
- At minimum (18)
- Just above minimum (19)
- Nominal value (40)
- Just below maximum (64)
- At maximum (65)
- Just above maximum (66)
- Zero
- Negative (-1)
- Null/undefined
- Non-numeric ("abc")
- Float (18.5)
- Very large number (999999999)
- Empty string
For each, state: input value, expected result (accept/reject), and why.
Expected Output
A well-trained LLM returns a structured table:
| Input | Expected | Rationale |
|---|---|---|
17 |
Reject | Below minimum boundary |
18 |
Accept | Minimum boundary (inclusive) |
19 |
Accept | Just above minimum |
40 |
Accept | Nominal/mid-range |
64 |
Accept | Just below maximum |
65 |
Accept | Maximum boundary (inclusive) |
66 |
Reject | Above maximum boundary |
0 |
Reject | Below minimum |
-1 |
Reject | Negative number |
null |
Reject | Required field |
"abc" |
Reject | Type mismatch |
18.5 |
Reject | Not an integer |
999999999 |
Reject | Above maximum |
"" |
Reject | Empty/required field |
Converting BVA Tables to Code
The table above translates directly to parametrized tests:
import pytest
class TestAgeValidation:
"""Boundary value tests for the age field."""
@pytest.mark.parametrize("age,should_accept", [
(17, False), # Just below minimum
(18, True), # Minimum boundary (inclusive)
(19, True), # Just above minimum
(40, True), # Nominal/mid-range
(64, True), # Just below maximum
(65, True), # Maximum boundary (inclusive)
(66, False), # Just above maximum
(0, False), # Zero
(-1, False), # Negative
])
def test_age_integer_boundaries(self, client, age, should_accept):
response = client.post("/api/users", json={"age": age, "name": "Test"})
if should_accept:
assert response.status_code == 201, f"age={age} should be accepted"
else:
assert response.status_code == 400, f"age={age} should be rejected"
@pytest.mark.parametrize("age,description", [
(None, "null value"),
("abc", "non-numeric string"),
(18.5, "float instead of integer"),
("", "empty string"),
(999999999, "extremely large number"),
])
def test_age_type_boundaries(self, client, age, description):
response = client.post("/api/users", json={"age": age, "name": "Test"})
assert response.status_code == 400, f"age={age} ({description}) should be rejected"
Multi-Field BVA
Real APIs have multiple constrained fields. Ask the AI to generate BVA for all of them at once:
Generate boundary value test cases for the following fields in the
POST /api/v2/products endpoint:
Fields:
- name: string, required, minLength=1, maxLength=200
- price: number, required, minimum=0 (exclusive: price > 0)
- quantity: integer, required, minimum=0 (inclusive), maximum=10000
- weight_kg: number, optional, minimum=0.01, maximum=500.0
For each field, test:
- At and around each boundary (min-1, min, min+1, max-1, max, max+1)
- Type mismatches
- Null/missing
- Empty string (for string fields)
- Precision limits (for number fields: 0.001, 0.009, etc.)