Building Software

What I've Learned · Apr 18, 2025 · Updated Oct 25, 2026 · 4 min read

Can AI Write Unit Tests? 200 Tests, 15% Caught Real Bugs

ai-vibe-coding-django.jpg
_ □ ×
ai-vibe-coding-django.md
_ □ ×

Yes, AI can write your unit tests, as long as you run them and read them. Over a month Claude wrote about 200 Django tests for me, and roughly 15% failed on the first run because the code was wrong.

I let AI write both my code and my tests, and the results were better than I expected. Andrej Karpathy gave this style a name in February 2025, when he described vibe coding as the kind where you “fully give in to the vibes, embrace exponentials, and forget that the code even exists.” There’s a common objection to AI-generated code, and it gets louder when the code is vibe coded: “How do you know it’s correct?” The usual answer involves careful code review, which is valid but incomplete.

My approach: Let AI write the tests too.

Won’t AI just write tests that pass broken code?

I assumed that if AI writes broken code, it would just write tests that pass for that broken code. Usually it doesn’t.

Different Prompting, Different Assumptions

When you ask AI to implement a feature, it makes certain assumptions about the requirements. When you ask it to write tests for that feature, it approaches the problem fresh, often making different assumptions.

This mismatch is actually valuable. The tests often catch edge cases the implementation missed.

Example: I asked Claude to implement a function that processes user input. The implementation handled the happy path well. When I asked for comprehensive tests, it generated tests for:

  • Empty strings
  • Unicode characters
  • Extremely long inputs
  • Inputs with special characters

Several of these tests failed, revealing bugs I wouldn’t have thought to look for.

The Django Sweet Spot

This approach works especially well with Django because of its excellent test infrastructure:

class ContactAPITests(TestCase):
    def setUp(self):
        self.client = Client()
        self.user = User.objects.create_user(
            username='testuser',
            email='test@example.com',
            password='testpass123'
        )

    def test_create_contact_authenticated(self):
        self.client.login(username='testuser', password='testpass123')
        response = self.client.post('/api/contacts/', {
            'name': 'John Doe',
            'email': 'john@example.com'
        })
        self.assertEqual(response.status_code, 201)
        self.assertTrue(Contact.objects.filter(email='john@example.com').exists())

    def test_create_contact_unauthenticated(self):
        response = self.client.post('/api/contacts/', {
            'name': 'John Doe',
            'email': 'john@example.com'
        })
        self.assertEqual(response.status_code, 401)

Django’s TestCase, Client, and ORM make tests readable and fast to write. AI knows these patterns deeply, which is one reason Django is the backend I pick for AI-assisted work. The Django testing docs also explain why these tests are safe to run over and over: Django creates “separate, blank databases” for the test run, and TestCase runs each test inside a transaction to keep tests isolated from each other.

My Workflow

  1. Describe the feature to Claude (what it should do, edge cases I know about)
  2. Have Claude implement it (usually gets 80% right on first pass)
  3. Ask Claude for comprehensive tests (“Write Django tests that cover happy paths, edge cases, and error conditions”)
  4. Run the tests (python manage.py test)
  5. Fix what fails (often with Claude’s help)

The tests act as a specification. When they fail, I learn something about either the implementation or my requirements.

Real Numbers

From my last month of development on ContactAI, the startup I was building at the time:

  • ~200 AI-generated tests
  • ~15% failed on first run (revealing real bugs)
  • 3 tests had issues in the tests themselves (easily fixed)
  • Time saved: days (that’s how long these tests would have taken me to write by hand)

The Trust But Verify Model

I don’t blindly trust AI-generated tests. I review them for:

  1. Coverage. Are the important paths tested?
  2. Assertions. Are they actually checking the right things?
  3. Setup. Is the test data realistic?
  4. Independence. Do tests depend on execution order?

But this review is faster than writing tests from scratch. And it catches the obvious issues. It’s also the kind of review that still takes a developer who knows the fundamentals.

Meta runs a stricter version of this at scale. Their TestGen-LLM paper (February 2024) describes a tool that has an LLM write new tests, then throws away any test that doesn’t build, doesn’t pass reliably, or doesn’t add coverage. On Instagram’s Reels and Stories code, 75% of the generated tests built correctly, 57% passed reliably, and 25% increased coverage. Across their Instagram and Facebook test-a-thons, engineers accepted 73% of the tool’s recommendations for production. Most of what the model wrote got filtered out, and most of what survived was good enough to ship. That’s the same deal I’m making by hand: let the AI write a lot, then check it.

Meta's LLM-generated tests (Instagram Reels and Stories)Built correctly: 75%Built correctly75%Passed reliably: 57%Passed reliably57%Increased coverage: 25%Increased coverage25%
Only one in four of Meta’s generated tests made it through every filter, and engineers still reviewed the survivors before anything shipped.
Show the data
StageShare of generated tests
Built correctly75%
Passed reliably57%
Increased coverage25%

When should you write the tests yourself?

  • Complex business logic. When requirements are nuanced, you need to specify carefully.
  • Integration with external services. Mocking strategies need human judgment.
  • Performance tests. AI doesn’t know your scale requirements.
  • Security tests. Critical paths need expert review.

For these cases, I write the test specifications myself and have AI implement them.

The Productivity Multiplier

The biggest surprise: AI-generated tests make AI-generated code better.

When AI knows tests will be written, it seems to generate more defensive code. When I’m iterating with failing tests, the feedback loop is tight and productive.

In practice, AI-generated code AND tests make me faster without doubling the risk.

Try This Tomorrow

If you’re skeptical, try this experiment:

  1. Pick a small feature you need to build
  2. Have AI implement it
  3. Have AI write tests for it
  4. Run the tests
  5. Note what fails

I bet you’ll find real bugs. And you’ll have tests you can run forever.

The “vibe coding” critique assumes AI code goes untested. Once AI writes the tests too, that assumption stops holding.

Update, October 2026: green tests aren’t the whole story. In our company brain we later found 153 passing tests over a feature that was broken, because the test fixture described an API response the real API never sends. I still let AI write tests, and now I also check what they actually exercise. If you want to set up that workflow on your own codebase, I do Claude Code coaching. Build It Yourself coaching is four 90-minute sessions for $1,997.

Keep Reading