AI is fast at writing tests, and that is exactly the problem. Left alone, it writes tests that confirm what the code already does, bugs included. The test-writing prompts in our code collection use a different order: edge cases first, then tests.
Below is the pattern, with a small PHP example where the edge-case step found a real bug before any test was written. If you haven’t set up a context brief yet, do that first. Tests need to match your framework and conventions.
The pattern
You are writing PHPUnit tests for the function below.
Step 1: List the edge cases this function should handle, including
inputs the author may not have considered. Do not write tests yet.
Step 2: For each edge case, state the expected result and whether
the current code produces it.
Step 3: Write tests for every case. Mark tests you expect to fail
with a comment explaining why.
Function:
{{code}}
The function under test
function slugify( string $title ): string {
$slug = strtolower( trim( $title ) );
$slug = preg_replace( '/[^a-z0-9]+/', '-', $slug );
return trim( $slug, '-' );
}
It looks fine. Step 1 of the prompt returned a list that included one case we hadn’t thought about: non-ASCII characters. strtolower() doesn’t transliterate, so “Café Menu” becomes caf-menu. The accented letter is silently dropped.
The tests
use PHPUnit\Framework\TestCase;
final class SlugifyTest extends TestCase {
public function test_converts_spaces_and_punctuation(): void {
$this->assertSame( 'hello-world', slugify( 'Hello, World!' ) );
}
public function test_trims_leading_and_trailing_separators(): void {
$this->assertSame( 'ai-prompts', slugify( ' --AI Prompts-- ' ) );
}
public function test_returns_empty_string_for_symbols_only(): void {
$this->assertSame( '', slugify( '!!!' ) );
}
// Expected to fail: accented characters are dropped, not transliterated.
public function test_keeps_accented_letters_readable(): void {
$this->assertSame( 'cafe-menu', slugify( 'Café Menu' ) );
}
}
Why the order matters
- Asking for edge cases first makes the model reason about intended behaviour, not current behaviour.
- Step 2 separates “what should happen” from “what happens”, which is where bugs show up.
- Marked failing tests are a to-do list, not noise.
A test suite that passes on the first run should make you suspicious, not happy.
QA lead
Keep a human in the loop
Always run the generated tests and read the assertions. A test that asserts the wrong value is worse than no test at all. It gives you confidence you haven’t earned.

