Stack / lifeintraffic
Workflows Guide Issued Jul 17, 2026 Sources 4

AI for Writing Tests — Complete Guide

AI writes passing tests—not good ones. Learn when to use it without getting burned.

Issued
Jul 17, 2026
Silo
Workflows
Kind
Guide
Sources
4
By
CR

Verdict

Use AI to write tests, but only with requirements and institutional context provided upfront, explicit mocking constraints, and a mandatory adversarial review pass before trusting any green suite.

AI-generated tests default to certifying whatever the code currently does rather than what it should do, producing tautological tests that can lock in bugs — a failure mode the article illustrates with a concrete real-world case where a bug was invisible because the test was written around it. The context problem, not a capability ceiling, is what limits AI across testing phases, and every documented success case in the article traces back to giving the model requirements before it writes a single assertion.

  1. 01Writing Tests with GitHub CopilotGitHub Docs (Official)
  2. 02Test with GitHub Copilot – VS Code Official GuideVisual Studio Code Docs (Microsoft Official)
  3. 03Writing Tests with AI – Vitest Official GuideVitest (Official Documentation)
  4. 04From Manual Testing to AI-Generated Automation: Our Azure DevOps MCP + Playwright Success StoryMicrosoft Azure DevOps Blog (Official)
Confidence high
Sources 4
Demonstration 1 video

AI can write a passing test suite in seconds. That’s exactly the problem.

The tests compile. They run green. Coverage jumps from 30% to 90% in a single afternoon. And then a bug ships anyway — one that lives happily inside a test that was supposed to catch it. This is the central paradox of using AI to write tests: the tool is fast, fluent, and confident, and none of those qualities correlate with catching real defects.

This guide is about closing that gap. Not “AI writes your tests for you” — that framing is where teams get burned — but a workflow where AI genuinely accelerates every phase of testing because you feed it the right context. The difference between the two is almost entirely about what you tell the model before it writes a single assertion.

The biggest mistake: writing tests without requirements

The number one workflow failure is starting the conversation at the wrong place. Developers open Copilot, highlight a function, and type “write unit tests for this.” The AI reads the code, infers what the code currently does, and writes tests asserting that behavior.

That sounds reasonable until you realize what it means: the AI is testing the implementation, not the requirement. If the function has a bug, the test now certifies the bug. If the edge case handling is wrong, the test locks in the wrong handling. You’ve produced what Hacker News threads accurately call a tautological test — a test that “simply reinforces the existing behaviour of the code.”

The fix is to give the AI context about what the code is supposed to do, not just what it does. That means requirements, acceptance criteria, and — critically — institutional knowledge. When you’re writing tests for existing code, add the insight the model can’t infer: the things that have bitten this codebase before. The race condition that took down production last quarter. The off-by-one in the pagination logic that took three engineers a day to find. The AI has no memory of your incident history. You do. That context is the single highest-leverage input you can provide.

Without it, you get tests that exercise functions without asserting anything meaningful. With it, the AI can generate genuinely defensive tests — because now it knows where the bodies are buried.

Where AI genuinely accelerates testing

Here’s a claim you’ll see contradicted in a lot of community posts: AI can accelerate every phase of testing — unit, integration, edge case generation, end-to-end — if you direct it correctly. The common wisdom that AI is “only good for boilerplate unit tests” is a symptom of under-directing the model, not a hard limit of the technology.

The reason the more complex phases appear to fall flat is information starvation. Integration and end-to-end tests require the model to understand system boundaries, real data shapes, and failure modes. When it lacks that information, it makes things up — inventing fixtures that don’t match reality or writing tests that don’t exercise anything meaningful. Give it the schema, the actual request/response payloads, and the deployment topology, and the same model produces integration tests that hold up.

Microsoft’s own team documented this pattern going from manual testing to AI-generated Playwright automation, but the enabling factor wasn’t the model — it was wiring the AI into their Azure DevOps work items via MCP so it had access to the actual acceptance criteria and test plans (Azure DevOps Blog). The context was the unlock, not the prompt.

Edge case generation is where AI shines even for skeptics. This is the phase where “brainstorm what could go wrong” turns the model into a genuine asset. It will surface null inputs, boundary values, Unicode edge cases, concurrent-access scenarios, and empty-collection paths that a tired human at 5pm forgets. You still decide which ones matter — but the enumeration is fast and thorough.

For a broader look at where AI fits across your development lifecycle, see our guide to AI tools in developer workflows.

The mocking trap

If there’s one behavior that quietly destroys the value of AI-generated tests, it’s over-mocking. The AI’s implicit success criterion is make the tests pass. Mocking is the path of least resistance to green, so the model mocks aggressively — sometimes mocking the very code it’s supposed to be testing.

Developers report this constantly: “the Agent has mocked every little thing, even the code it should test.” The result is a test that exercises your mocks and asserts your mocks behave like your mocks. It tests nothing.

Combat this explicitly in your prompt and your review:

  • Name what should be real. Tell the AI which collaborators are the system under test and must not be mocked. Only external boundaries — network, filesystem, clock, third-party APIs — should be doubled.
  • Prefer fakes and in-memory implementations over mocks where you can. An in-memory repository catches integration bugs a mock never will.
  • Read every mock in review. If a mock’s return value is doing the work the real code should do, the test is theater.

Vitest’s official AI guidance leans the same direction — steering the model toward testing behavior and observable output rather than stubbing internals (Vitest docs).

The real-world failure: a test that certified a bug

This is not hypothetical. A concrete example: a coworker had a bug in their code, and the test they wrote — or generated — tested for that buggy behavior. Everything was green. The bug was invisible because the safety net had been woven around it.

The way it got caught is worth internalizing as a workflow step. The fix wasn’t more coverage. It was a different prompt: asking Claude what could go wrong, and whether the code actually honored the original ask. That reframing — from “test this code” to “audit whether this code does what it’s supposed to, and where it might fail” — is the antidote to the tautological test.

Make it a standing part of your process. After the AI generates tests, run a second pass with a prompt like:

“Here are the requirements. Here is the implementation. Here are the tests. Where could this code produce wrong output that the current tests would not catch? Does the implementation honor the stated requirement?”

This decouples the model from its own assumptions. In the first pass it inferred behavior from code; in the second pass you force it to compare code against intent. That gap is exactly where bugs live.

TDD: the workflow that fixes this at the source

The cleanest way to avoid AI certifying bugs is to never let it read the buggy implementation first. This is where test-driven development — long dismissed as ceremony — becomes the natural partner for agentic coding.

In a TDD loop, you (or the AI, given clear requirements) write the tests before the implementation exists. The tests encode the requirement, not the code. Then you ask the AI to write code that makes the tests pass. Now the model can’t tautologically reinforce buggy behavior, because there is no behavior yet — only intent expressed as failing tests.

This is why TDD is resurging in AI circles. The Red-Green-Refactor cycle gives the model an unambiguous target: red tests derived from requirements, code written to turn them green, then refactoring under the safety of those tests. The AI is superb at the “write code to pass this test” half of the loop. Your job is to make sure the tests genuinely express the requirement — which loops right back to the context problem.

A practical workflow for writing tests with AI

Putting it together, here’s a sequence that produces tests with real coverage value:

  1. Start with requirements, not code. Paste acceptance criteria, expected behavior, and the specific failure modes this area has hit before. If you’re doing TDD, this becomes your test spec directly.
  2. Ask for scenarios before assertions. Have the AI enumerate what should be tested — happy paths, edge cases, error conditions — and review that list before any code is written. You are the SDET; the AI is the brainstorming assistant and the boilerplate typist.
  3. Constrain the mocking. Explicitly state what is the system under test and what may be doubled.
  4. Generate the tests. Let the model write the boilerplate — this is what it’s genuinely fast at. GitHub Copilot’s official test-writing guide walks through using /tests and agent mode to scaffold suites (GitHub Docs), and VS Code’s agent guide covers running and iterating on them in-editor (VS Code Docs).
  5. Run the adversarial pass. Ask the model where the code could fail that the tests wouldn’t catch, and whether the implementation honors the requirement.
  6. Review like a human reviewing a junior engineer. Read every assertion. Confirm each test would actually fail if the behavior broke — mutate the code mentally and check the test catches it.

That last check is the real definition of coverage. Not lines hit — behaviors defended.

The verdict

Use AI to write tests. It’s faster than doing it by hand across every phase of the lifecycle, and the “AI is only good for trivial unit tests” ceiling is a context problem, not a capability limit.

But treat the AI exactly as the community’s most durable heuristic suggests: a junior engineer who writes fast and needs review. It has no memory of your outages, no access to your requirements unless you provide them, and a built-in bias toward making tests pass rather than making them meaningful. The 2025 Stack Overflow survey found 84% of developers use AI tools while only 33% trust the output — and that skepticism is earned. Trust should be low by default and earned through review.

The developers who win with AI-generated tests aren’t the ones who prompt best. They’re the ones who feed the model requirements, constrain its mocking, run the adversarial pass, and never ship a green suite they haven’t read. The AI types the tests. You decide what “correct” means. Keep that division of labor and AI becomes one of the highest-leverage tools in your testing workflow. Blur it, and you’re just automating the production of false confidence.

Demonstration

I used AI to write tests for my .NET application... Here's what happened Click to load · YouTube · 11 min 17 s

New plates as they're issued.

Plates reach your inbox before they are posted, with the longer version and the systems being built behind them. One letter across all three Life in Traffic sites.

Double opt-in — you'll get a confirmation email. Unsubscribe anytime.