Skip to content

· software testing · 5 min read

Writing The Perfect Tests for your Application

Testing is hard, but knowing what and when to test is actually harder. Let me tell you about 3 types of tests that can help you secure your project.

Neciu Dan

Neciu Dan

Hi there, it's Dan, Senior Engineering Manager at Perk, host of Señors at Scale - a podcast for Senior Engineers, Organizer of ReactJS Barcelona meetup, and international speaker, I'm here to share insights on combining technology and education to solve real problems.

I write about startup challenges, tech innovations, and the Frontend Development. Subscribe to join me on this journey of transforming education through technology. Want to discuss Tech, Frontend or Startup life? Let's connect.

Share:

We, as humans, are all looking for perfection. Some are trying to capture the perfect sunset, some are trying to ride the perfect wave and Software Engineers are looking for perfection in their code.

We want to write clean, maintainable code, with as little fragility as possible, and to achieve this most of the time the correct approach is with lots and lots of tests.

I wrote about the 5 types of testing practices you need in your application, but in this article, I want to talk about the app-saving tests, that can help you save time, money, and stress.

We can categorize the perfect tests into 3 types:

  • The test that helps you build
  • The test that helps you debug
  • The test that helps you sleep well at night

The Test that helps you Build

The Test that helps you build

Photo by Randy Fath on Unsplash

The purpose of Software Testing is to make sure our code works!

And it’s important our code works in as different situations as possible. Testing just the happy path is not enough, we have to add tests for boundary situations and errors.

For example, we have an array of numbers:

const arr = [1,2,3,4,5]

And we want to write a simple function that adds +1 to every number of the array without using any array build-in functions like map or reduce

If you start with a simple for loop from 0 to 5, iterate through the array, and add 1 to each value, we can create a boundary test where instead of passing a 5-value array we will pass a 6-value array or an empty array.

Our tests would fail, and we will improve our design by changing the for loop to include the array’s length.

We are continuously iterating through our design and building better and more maintainable code.

You write your tests first, make sure they fail and write the most straightforward code that will make your test case pass.

Afterward, you look at your code and see if it can be improved in any way, if not you add another test case and continue the cycle.

This is what Test-Driven-Development (TDD) is all about.

The Test that helps you debug

 The Test that helps you debug

Photo by Mediamodifier on Unsplash

Has this ever happened to you?

You’re working on your project and you find a critical bug that is hard to reproduce but you just know it wasn’t there in the last sprint.

It was introduced recently, but you don’t know how and more importantly when.

In October 2022, Git introduced a very handy command called git bisect

git bisect is a useful tool for quickly identifying the commit that introduced a bug in your code. It can save you a lot of time compared to manually searching through the commit history.

But before you run the git bisect process, you need a test to determine if the bug is present or not.

Let’s say you have a bug in the login flow. You would write an e2e that simulates the flow for you.

Having the test ready, here’s how to use it to find the commit that introduced a bug:

  1. Start the bisect process by running git bisect start.
  2. Identify a commit that is known to be “good”, and run git bisect good <commit>.
  3. Identify a commit that is known to be “bad”, and run git bisect bad <commit>.
  4. Git will then check out a commit that is halfway between the good and bad commits.
  5. Run your test to determine whether the current commit is good or bad. If it is good, run git bisect good. If it is bad, run git bisect bad.
  6. Repeat this process until git bisect finds the commit that introduced the bug.
  7. When git bisect has found the commit, it will output the commit hash and message.
  8. Run git bisect reset to stop the bisect process and return to the HEAD commit.

Automating this process will save you hours and hours of checking commit histories, especially if the bug was introduced months ago and you have a very big codebase.

The Test that helps you Sleep well at night

The Test that helps you Sleep well at night

Photo by bruce mars on Unsplash

Engineers love complexity.

Like building software that does things, nobody or no other software has done before.

And the same is true for our automation processes. Engineers like to add automated flows for visual tests, performance tests, unit tests, and every other kind of testing flow imaginable.

I actually wrote a piece about 5 testing practices you should have in your CI/CD pipeline, but the truth of the matter is that a very simple synthetic test would give you more value than all of those combined.

Sure, testing practices in your CI/CD can prevent faults from being deployed, but bugs are tricky, they like to hide in dark places and only come out during the perfect moment (Like a long weekend, or Christmas)

Having a smoke test or a synthetic test that covers the most critical business flow in your application running on the production environment, will give everyone involved that amazing good night’s rest without worrying about the feature they deployed on Friday.

Third-party monitoring and observability tools like DataDog, Sentry, or Testing as Service platforms allow you to build these kinds of tests that run on your application every minute and alert you if anything goes wrong.

Building these tests in your pipeline, having canary deployments, and running them only on the affected group could save your company a lot of money and reduce the stress level of all the company’s engineers.

Conclusion

Software Testing is not only useful to verify the correctness of your software.

Taking full advantage of tests you can use them to better write your code using TDD practices like Red-Green-Refactor or Triangulation.

You can automate debugging with git bisect and a handy E2E test to quickly find when a bug was introduced in your codebase.

And having a small and simple synthetic test that runs on your production environment can make sure your dreams at night are without worry and stress.

Doesn’t that sound just perfect?

Neciu Dan

Discover more from The Neciu Dan Newsletter

A weekly column on Tech & Education, startup building and occasional hot takes.

Over 1,000 subscribers

🎙️ Latest Podcast Episodes

Dive deeper with conversations from senior engineers about scaling applications, teams, and careers.

Hypermedia at Scale with Carson Gross
Episode 53
58 minutes

Señors @ Scale host Neciu Dan sits down with Carson Gross, creator of HTMX, principal at Big Sky Software, and computer science professor at Montana State University. Carson has been programming for more than 30 years, from HyperCard on a family Mac to Excel macros for an industrial engineering firm, a JVM language called Gosu, a Rails startup, and the 2012 library Intercooler.js that he rewrote without jQuery during COVID and released as HTMX. His argument is that the web was built as a hypermedia system, that links and forms are control logic living inside the document, and that most of what we call REST today fails the one constraint Roy Fielding cared about. He also covers which apps HTMX is wrong for, what changed in HTMX 4 and why 3 was skipped, and why his students now sit pencil and paper exams. It is a conversation about using the browser as the hypermedia client it was built to be.

📖 Read Takeaways
Performance at Scale with Ryan Townsend
Episode 52
52 minutes

Señors @ Scale host Neciu Dan sits down with Ryan Townsend, Principal Product Manager for Performance at Cloudflare, where he owns real user monitoring and the wider performance measurement remit. Ryan has over 20 years in web technology and a decade as a CTO: he co-founded Shift Commerce, the first enterprise scale headless SaaS, and was CTO of Matalan Direct after the business he built came second in Shopify's Build a Business competition with only three months of trading. We cover why the 'Rails doesn't scale' story was always a myth, the resume driven development he kept finding as a fractional CTO, the personalization script that claimed zero performance impact and cost seconds at P90, and how Shift ran over 99% cache hit ratios by splitting the anonymous page from the basket.

📖 Read Takeaways
Design Systems at Scale with Szymon Chudy
Episode 51
56 minutes

Señors @ Scale host Neciu Dan sits down with Szymon Chudy, Software Engineer at Netflix on the Hawkins team, which builds the design system behind thousands of internal applications used to produce the shows you watch. Before Netflix, Szymon spent two and a half years at Lokalise, growing from senior to staff frontend engineer and leading frontend direction across teams, and before that he toured Poland as a reggae guitarist while freelancing as a web developer in the off season. From why the source of truth for a design system lives in code, to Hawkins Consumer versus Hawkins Professional, to the UI paved road that changes what freedom and responsibility mean at Netflix, to measuring the team on adoption rate and shipping codemods and agent skills for every breaking change, to what being an informed captain who farms for dissent means in practice, this is the design system conversation for anyone maintaining a platform other engineers have to choose to use.

📖 Read Takeaways
Agentic Systems at Scale with Vilva Athiban
Episode 50
52 minutes

Señors @ Scale host Neciu Dan sits down with Vilva Athiban, Lead AI Engineer at Omio, one of Europe's leading travel platforms, where he architects and ships agentic AI systems in production. Vilva designed and delivered Omio AI, along with the MCP integrations that connect AI agents to the company's systems. He never set out to switch from JavaScript to AI: in June 2024 Omio picked two people to start an AI team reporting to the CEO and CTO, and he learned on the job, from his first API call to an LLM up to a consumer-facing agent whose backend runs on nothing but MCP. From why a bigger model with medium thinking came out cheaper than the mini, to capping tool calls because LLMs are built for token maxing, to the whale hunting request that showed his team guardrails are subjective, this is a conversation about what production agentic systems look like once the tutorials run out.

📖 Read Takeaways
Back to Blog