Modern TDD with Python in 2025 — Step-by-Step, with AI at Your Side [part 4/10]
Vibe Coding with TDD — Yes, It’s Possible
Vibe Coding with TDD — Yes, It’s Possible
“Flow, but with tests.”
We need to talk about vibe coding.
You know what I mean:
- That state when you type like your fingers know what you’re doing before your brain does.
- Where time disappears.
- When you’re “just trying something real quick”, and three hours later you’ve built a local-first AI-powered multiplayer calendar in a single file.
That’s vibe coding. And it’s magical.
But there’s a myth:
“You can’t write tests while you’re in the flow.”
Let me show you why that’s false — and how TDD can support your vibe, not interrupt it.
Scene: You’re in the Zone
Let’s say you’re mid-flow. You’re adding a new --verbose flag to your calculator’s add command. You just want it to say something like:
$ python -m calculator add 2 3 --verbose
Adding 2 + 3
5
You feel it. You just want to make it happen. Now.
The trick is: don’t stop coding. But don’t stop testing either.
Here’s how you make vibe coding and TDD play nice together.
Strategy 1: Write Tests After (but Immediately)
We usually say:
Red → Green → Refactor
But during vibe coding, we may momentarily do:
Green → Refactor → THEN Red
And that’s fine — if you do it right away.
Example:
You quickly add this to main.py
:
@app.command()
def add(a: int, b: int, verbose: bool = False):
if verbose:
typer.echo(f"Adding {a} + {b}")
typer.echo(str(a + b))
Now, pause for 90 seconds and write a test:
def test_add_verbose():
result = runner.invoke(app, ["add", "2", "3", "--verbose"])
assert "Adding 2 + 3" in result.output
assert "5" in result.output
Run pytest
.
- If it passes — great.
- If not — your vibe just caught a bug before your users did.
That’s still test-driven — just not religious about order.
Prompt: TDD for Vibe Mode
Paste this into GPT:
I just added a --verbose flag to my CLI calculator's add command. It prints "Adding a + b" before the result. Can you help me write a test for this behavior using Typer's CliRunner?
Now GPT becomes your post-vibe safety check.
Strategy 2: “Describe, Don’t Assert” While Vibing
If you’re not ready to write tests yet — write comments instead.
# TODO: if verbose=True, should print "Adding a + b"
# TODO: still prints result
# TODO: should work for negative numbers too
Later, turn those into tests.
Use pytest.mark.skip(reason="writing tests after vibe")
as placeholders:
import pytest
@pytest.mark.skip(reason="writing tests after vibe")
def test_verbose_flag():
...
Now your tests are part of your flow journal.
Strategy 3: Let Zed or VSCode Keep You Flowing
Zed:
- Split screen: test on left, main on right
- Use
watchexec -e py – pytest
so tests auto-run - No distractions. Pure dopamine.
VSCode:
- Use “Run Test at Cursor” when you pause to breathe
- Copilot auto-suggests test names and input values
- Test output in the sidebar = immediate feedback
Bonus Prompt: Vibe-Driven Test Generation
Try this:
Here’s what I just wrote (paste CLI code). Can you suggest a few TDD-style tests to validate its behavior? Be concise and focus on user-visible effects.
GPT becomes your after-the-fact testing conscience.
Strategy 4: Turn Your Flow Into Fixtures
Once your feature settles, clean up the test:
import pytest
@pytest.fixture
def cli():
return CliRunner()
def test_add_verbose(cli):
result = cli.invoke(app, ["add", "1", "2", "--verbose"])
assert "Adding 1 + 2" in result.output
Now you’re combining:
- Vibe dev
- GPT-driven test prompts
- Clean, maintainable test structure
Recap: TDD and Flow Aren’t Enemies
You just learned to:
- Code first, test right after
- Use comments and skips to log test intent
- Ask GPT to help backfill coverage
- Let your editor keep tests runnable during flow
So next time someone says:
“I don’t do TDD because I code in a flow state…”
You can say:
“Cool. I vibe with tests too. Want me to show you?”
Next Up:
Part 5: GitHub Actions + pre-commit — Guardrails, Not Bureaucracy
(linke will be added here)