
How I test my Svelte projects
For years I barely wrote tests. I explain why I changed my mind and how I split the work between Vitest and Playwright.
For a good part of my career I barely wrote automated tests. Working almost always alone, on projects I could test by hand in a couple of minutes, it felt like time better spent moving features forward. I changed my mind the day a seemingly harmless change in a shared component broke a form on a completely different page, and I didn’t find out until a client told me.
Where I draw the line between Vitest and Playwright
I don’t test everything with the same tool, and I don’t try to — each one answers a different question.
With Vitest I test pure logic: date-formatting functions, money, slugs, anything that takes an input and returns an output without touching the DOM. They’re quick to write and extremely quick to run, and they’re the ones I write almost without thinking as I add a new function to utils/.
For .svelte components that do interact with the DOM, I also use Vitest, but in browser mode with vitest-browser-svelte, mounting the actual component instead of simulating it. I learned one thing the hard way there: after simulating a click or typing, you need to wait for tick() before checking the DOM — runes don’t update synchronously, and the first tests I wrote failed intermittently until I understood why.
With Playwright I test complete end-to-end flows: that a form can actually be filled in and submitted, that navigation between pages works, that a critical element hasn’t disappeared after a style change. They’re slower to run, so I reserve them for the paths I’m genuinely worried about breaking — I don’t try to cover every corner with this kind of test.
What I don’t do
I don’t chase a coverage number as a goal — one hundred percent coverage with shallow tests gives a false sense of security, and I’ve seen projects with that perfect number that still broke in production anyway. I’d rather have fewer tests, but each one covering something that has genuinely failed on me before or that I know is easy to break without noticing. The list grows over time, almost always after a bug I don’t want to see again.