Logo

dev-resources.site

for different kinds of informations.

Is the Test Pyramid Still Relevant?

Published at
1/8/2025
Categories
technology
coding
programming
softwareengineering
Author
Benjamin Cane
Is the Test Pyramid Still Relevant?

A friendly kitty-cone
Image Generated with AI

The other day, I saw a comment about how someone felt that testing in today’s world is different and that the coveted test pyramid doesn’t make sense anymore.

I don’t entirely agree, but I understand the sentiment.

Breaking down the argument:

The crux of this person’s argument was the following:

1: It’s not as costly or inefficient to perform functional tests as it used to be:

I agree with this argument, but I will add the caveat of “when done right.”

Background:

Functional testing used to take a long time and be expensive because it was always performed in a shared environment.

Before containerization became part of everyday development, running services locally was complex, mainly because it required localized dependencies like databases, caches, etc.

But in today’s world, the standard isn’t to perform functional tests exclusively in a shared environment but rather to be able to run everything locally and within the CI environment.

If Done Right:

The ability to run everything locally in isolated environments makes functional testing easier and faster.

But that very much depends on having a setup that allows for it.

That means running functional tests in parallel, not relying on shared services and having a good test data setup.

These are all achievable, but they require investment in testing and improvement in the time it takes to execute tests.

2: The Internals of applications change so frequently that it makes more sense to focus on functional tests:

I struggle with this argument. While I agree that internals change frequently, I’d argue that unit testing is crucial for large code bases.

Challenges for Large Code Bases:

In a large code base (and small ones), a package or certain functionality might be used across multiple areas within the application. Tracking down all of the areas of usage can be difficult at times.

Unit tests help by acting as an insurance policy, ensuring that breaking changes are identified before changes are merged. When these breaking changes are identified, it forces the conversation around whether that breaking change is needed.

When I encounter these scenarios, I try to avoid the breaking change, but when that change is valuable, I go the extra mile to find where that functionality is used. My updates, of course, rely heavily on existing unit tests.

Functional Testing Isn’t Deep Enough:

Another challenge with relying purely on functional testing is that not all things are externally observable.

If my application is supposed to fetch a record from a database and then update its internal memory cache with the result for subsequent requests, you can’t quickly test that with functional testing.

It’s far easier to test internal behavior with unit tests.

Truth is Both are Important:

If you’ve worked with me in the past, you’ll know I’m not a huge fan of BDD frameworks and most functional testing tools. These feel clunky and unwieldy to me.

I’m a fan of writing functional tests with unit testing frameworks. For example, I like using the standard library “testing” package for my Go applications.

But you’ll always find both functional and unit tests in my applications. I believe both are important to building reliable software.

You need to test the internals and externals equally.

What is your opinion? Do you think the test pyramid and focus on unit testing is still correct?

Featured ones: