Why We Finally Started Writing Unit Tests (and Why You Should Too)

Maiko CasperMaiko Casper
8 min read

"Isn't testing just extra work?"
That was the thought echoing through our dev chats every time someone brought up unit testing. Like many small teams building fast (maybe too fast), we focused on pushing features, fixing bugs, and moving to the next task. But as our system grew more logic, more users, more moving parts we hit a tipping point.

Recently, our team made a conscious decision to start writing unit tests both on the frontend (React/Next.js) and backend (Node.js). We’re using Jest and Vitest, and while we’re still early in the process, we’ve already learned a lot about the real value of testing, the misconceptions that held us back, and how to fit testing into a fast-paced workflow.

Unit Test Images – Browse 24,389 Stock Photos, Vectors, and Video | Adobe  Stock

What Is Unit Testing (Really)?

Unit testing is about checking individual pieces of your code, usually functions or components to make sure they do what they're supposed to. Sounds simple, right? And it is. But it's also powerful. Writing a test that says, "If I give this function X, I should get Y" forces you to understand and isolate what each part of your code is responsible for.


What Tools We're Using

  • Frontend:

    • React + Next.js - Our app runs on the modern stack.

    • Vitest - It’s fast, integrates beautifully with Vite, and feels lightweight.

    • React Testing Library - Helps us test components the way users interact with them.

  • Backend:

    • Node.js

    • Jest - Still a solid go-to for backend logic, middleware, and utilities.


The QA Moment: "Can We Use Jest Too?"

Interestingly, when we started rolling out tests, our QA team was immediately curious, and a bit skeptical.

"What’s Jest? What’s Vitest? Are those for us too?"

They asked all the right questions. The reality? Jest and Vitest are developer-focused tools. They're made for unit tests, code-level tests, not full-blown UI walkthroughs or behavior simulations. We clarified that these tools were meant to support QA, not replace it. By catching low-level bugs early, unit tests help reduce the noisy back-and-forth and give QA cleaner, more stable builds to work with.


We’re Beginners, Not Experts - And That’s Fine

Our engineering team is just getting started with writing tests. We don’t pretend to be testing experts or TDD purists. Far from it.

We aimed to start simple: set a goal to reach 80% coverage for any new feature or updated module. This baseline gave us something to work with, not perfection, but a foundation.

We knew we couldn’t write tests for everything overnight, especially not legacy code. But by writing tests around new features, and slowly backfilling critical parts of the codebase, we started making progress. The idea was that in the future, if someone touched a module or refactored code, we’d already have tests in place to either catch regressions or confirm that things still work.

That’s the kind of workflow we were building toward. And yes, we were figuring it out as we went. Some days that meant asking questions, debugging broken mocks, or even turning to ChatGPT or Stack Overflow. That’s part of learning.


When an Intern Thought He Had All the Answers

In the middle of our unit testing rollout, an intern joined the team - eager, smart, and vocal. While we appreciated his enthusiasm, it soon became clear there was a disconnect between theory and reality.

The Intern was hilarious(ly bad) : r/moviecritic

He submitted a formal proposal arguing against our 80% code coverage baseline. He was championing black-box testing and warning about the risks of "over-testing implementation details." The document was polished and referenced all the right concepts, but it carried an assumption that we hadn’t considered these things ourselves. Worse, it missed the context of where we actually were as a team.

We were working on a fairly new system, built in 2023–2024, but much of its early codebase came from developers who had already resigned. We were still learning how different parts were wired up, figuring things out piece by piece. Adding unit tests wasn’t about chasing arbitrary coverage numbers, it was about building confidence as we touched unknown code. It was about future-proofing.

The intern, however, seemed to think he had discovered something we hadn’t. He asked things like:

“Did you just Google that?”
“Is that AI-generated?”

7+ Hundred Conflict Intern Royalty-Free Images, Stock Photos & Pictures |  Shutterstock

And to be honest, it wasn’t what he asked, it was how he asked it. The tone suggested we didn’t know what we were doing, when in fact we were just starting from the ground up, making real progress together.

I even stepped away from the online meeting for five minutes to use the bathroom, came back, and thought:

“What the f**k is going on?”

2+ Thousand Angry Intern Royalty-Free Images, Stock Photos & Pictures |  Shutterstock

The conversation had completely shifted. Instead of discussing how to gradually introduce unit tests and improve our testing workflow, we were now knee-deep in a theory-heavy, one-sided monologue about black-box testing as if it were some silver bullet.

Even our Head of Engineering, who had generously joined the call to support the discussion, eventually had to call it. Before exiting the meeting, he simply said:

“This is not a productive conversation anymore.”

And just like that, he left - because it wasn’t about ideas anymore. It had become an unproductive debate driven more by ego than understanding.

The intern didn’t seem to realize that we were already making trade-offs between ideal and practical. We weren’t aiming for perfection - we were aiming for momentum. An 80% coverage goal gave us something to work toward, especially on a shared codebase built by developers who were no longer with the company.

Still, we didn’t hold it against him. We never pretended to be experts. We were all beginners, figuring it out together-intentionally, transparently, and with long-term maintainability in mind.

The intern eventually completed his internship. We said our goodbyes respectfully and treated him like a younger brother. He left without any issues with the dev team. Whether things felt different with the higher-ups, we’re not sure - but from where we stood, there were no hard feelings.


Why We Started Testing (For Real This Time)

  1. Confidence: Before tests, every update felt like defusing a bomb. Now, tests act like guardrails.

  2. Debug Faster: A failed test shows exactly where things broke.

  3. Team Scalability: New devs don’t need to second-guess what code is supposed to do. Tests document intent.

  4. Regression Safety: You fix one thing, accidentally break another. With tests? You’ll know instantly.

  5. Fewer Bugs in Prod: Seriously - this one speaks for itself.


Misconceptions We Had (And Maybe You Do Too)

❌ “Unit testing is for big teams.”

Even small teams benefit - maybe more, because bugs hit harder when you don’t have a QA army.

❌ “It slows you down.”

Fixing a bug in production at 2 AM is the real time-waster.

❌ “You need 100% test coverage.”

Nope. We aimed for 80% as a realistic starting point - enough to catch issues without burning out.

❌ “Testing components is hard.”

Not with the right tools and mindset. Think like the user, not like a robot.


What We Actually Test

  • Frontend:

    • Pure functions

    • Component rendering

    • UI logic

    • Forms

  • Backend:

    • Business logic

    • Helpers/middleware

    • API input/output

    • Edge cases

We avoid unnecessary snapshot tests or low-impact coverage padding. We test what matters most to stability and user experience.


Learning By Doing: Writing Tests That Weren’t Even Mine

On my end, I took a slightly different route.

We were instructed to write unit tests for the files we made changes to - which makes sense. It ensures that the features or bug fixes we touch are backed by tests, and helps avoid breaking things in future updates.

But at some point, I went off-script a bit.

Instead of just sticking to the file I edited, I started writing tests for other parts of the codebase, even ones unrelated to my specific task. Why? Mostly out of curiosity, and partly because I was still trying to get a feel for how unit testing worked in the context of our system.

In hindsight, it was a helpful detour - but also a reminder that unit testing isn’t just about coverage numbers or satisfying a checklist. It’s about writing the right tests, at the right time, for code you understand and take responsibility for.

That said, I still do it to this day.

Even if a file isn’t assigned to me or directly tied to my task, I sometimes write or update tests for it - especially if I notice it doesn’t have any yet. Why? Because it helps the team. It makes onboarding smoother for others, reduces regressions, and gives us better coverage where it matters.

And honestly? It makes me more productive in the long run. When the tests are already there and reliable, I can move faster and with more confidence.

Unit testing, I’ve learned, isn’t just a box to check. It’s a way of leaving the codebase better than you found it - for yourself and for everyone else who comes after.

The Learning Curve Is Real

We didn’t start by covering everything. We just started. That’s the key. By committing to write tests around new features, fixing broken tests as we go, and slowly backfilling critical logic, we’re creating a habit - and a safety net.


Final Thoughts: Progress Over Perfection

Unit testing is a journey. You don’t need to master every concept on day one. You just need to start.

We’re not experts. We’re not perfect. We’re just a team that decided we cared about quality enough to do something about it. Whether you use Jest, Vitest, or something else entirely - what matters is committing to learn and supporting each other along the way.


TL;DR

  • Unit tests don’t make you slow. They make you smarter.

  • Tools like Jest and Vitest are easy to adopt if you start small.

  • 80% coverage is a solid goal - not for the number, but for the habit.

  • Be honest about what you don’t know. Humility wins.

  • Enthusiasm is great, but it should come with context and respect.

  • Say your goodbyes professionally - even if things don’t align.


0
Subscribe to my newsletter

Read articles from Maiko Casper directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Maiko Casper
Maiko Casper

Hey there! I'm Maiko Robles (you can call me Maiko — it's a nickname I use for security and peace of mind 😌). I'm a frontend developer with over 3 years of experience, passionate about building fast, user-friendly websites using Next.js, React.js, TypeScript, and Node.js. I hold a Bachelor's degree in Information Technology, majoring in Web Development, which means this isn't just a job for me — it's my responsibility to continuously learn and adapt. I'm not bound to just React or Next.js — I embrace new frameworks, languages, and tools as the field evolves. Web development is always changing, and I'm here for the ride. Let's build something awesome together!