Using TDD + Cypress + Cursor to Ship Features Quickly

Brian Kotos

November 19, 2025

A quick example from my workflow (video included)

I've been using a workflow that mixes TDD, Cypress, and Cursor, and it's been working extremely well for me. Instead of describing it in theory, I recorded a short video showing the exact flow I used while adding a real feature:

This is the same process I use during normal day-to-day development.

The small feature I was adding

In the video, the feature was simple: when you open the "Completed" list, completed items should show a little checkmark. Small, focused feature-- perfect for a quick TDD cycle.

Here's the loop I follow:

  1. Describe the behavior in plain English

  2. Cursor generates a failing Cypress test

  3. Run it and confirm it fails

  4. Ask Cursor to make the smallest change that makes the test pass

  5. Clean things up if needed

It's a tight loop, and I've been using it for the entire app. Lots of small steps, each one fully validated before moving on.

Why Cypress fits this so well

One reason I prefer Cypress over other tools is that it behaves like a real user. It literally launches a browser and interacts with my app the same way someone sitting in front of a laptop would-- clicking, typing, navigating around. Nothing mocked, nothing simulated. When a Cypress test passes, it means the behavior is actually correct from the user's point of view.

And interestingly, I've been able to use Cypress to drive backend changes too-- even though the backend is written in Go. Because the tests go through the UI, I end up caring much more about the outcome than the process. The backend just needs to behave correctly; how it gets there is an implementation detail I can change freely.

This has had a really nice side effect: I'm not tightly coupled to my own abstractions anymore.

I can rename things, reshape handlers, reorganize files, switch approaches entirely-- and as long as the behavior stays the same, Cypress doesn't care. That freedom makes it much easier to improve the internals over time without fear of breaking things.

Cursor helps automate the repetitive parts of this loop, but the tests keep the direction grounded.

Where this approach really shines

This workflow doesn't just help with small feature work-- it gives me something much bigger: a frontend and backend that are both completely disposable.

Because Cypress tests describe behavior, not implementation details, the entire system-- React components, Go handlers, whatever abstractions I think up today-- all become replaceable. I've actually deleted whole frontends before and regenerated them with a different framework, driven purely by the test suite. Same behavior, totally new implementation.

The same idea extends to backend code as well. The tests don't know anything about how my Go code is structured; they only know what the system should do. That's the kind of decoupling I've always wanted in real projects but rarely see in practice.

This video is just a small example of that workflow in action.