The 2 most important tools for any software engineering team in 2024
The very first line of the agile manifesto is “Individuals and interactions over processes and tools” — which is absolutely true, all the best teams I have worked in have been highly collaborative and highly social. Some people take this line to mean processes and tools don’t matter — which is not true, we just prefer collaboration over relying on processes and tools to deliver valuable software.
Tooling is still an important part of software engineering, and it’s an important one to get right. For me, after here are only two tools that offer the most value for any software engineering team: Unit test frameworks and static code analysis. These tools give you the guard rails your team needs to go fast, safely — and can be implemented by any team, at any stage.
Unit test frameworks
Even though I was somewhat late to the game, I am a proponent of Test Driven Development (TDD), and have used it for a number of years — so I have heard (and even used myself) all the excuses not to use TDD.
“It will slow us down too much”
”We are only doing web stuff, we don’t need tests”
“They don’t guarantee quality”
While the learning curve of TDD can seem like a steep one, once you’ve been at the top of that curve for a while, you wonder how you ever built good software without it.
The fact is you probably didn’t.
I’ve lost count of the number of times I’ve changed part of a system that I instinctively thought was safe, only to have a test fail. The number of bugs that I didn’t ship to production is probably somewhere in the hundreds. I used to think writing tests was going to slow us down and cost us money, but then I thought back to some teams I’ve worked with that didn’t use TDD and just wrote functional code. I thought about the large amount of bug tickets in the backlog. I thought about the time spent it takes someone to report a bug, and time spent triaging the bug. Then I thought about the time spent trying to find the source of the bug — often by a developer unfamiliar with that part of the system, or who may have joined the team recently. Then I thought about how much money that bug might’ve cost the company, either through poor user experience or through incorrect data or reporting. After a while the time and money really adds up.
In fact, the National Institute of Standards and Technology (NIST) has done research on the effort required to identify and fix defects as software progresses through five broad phases of development.
As you can see, identifying and fixing bugs after they are deployed is 1-2 orders of magnitude greater than if it’s caught during the coding phase (which is where you write your tests, you don’t write them in the testing phase).
One of the big benefits of TDD is instant feedback. This feedback is a huge time saver if you are working on a piece of logic that might be very complex or just challenging for some developers to craft.
To use an example, a function that calculates distance between 2 or more points on the planet.
How would you go about testing this without automated tests to give you instant feedback?
You know what answers the function should return for a number of scenarios, so you do manual testing incrementally. Maybe you reload a page in your browser and fill out a form. Maybe you change a bit of logic which then breaks a calculation that used to work. Maybe you think you’re done, and you pass it off to a QA for testing, only for it to come back again and again.
Now imagine you’re starting again from scratch. You already know what the answers the function should return for a number of scenarios, so you put those in some tests.
You know that the distance between Melbourne and Sydney is 713.43km. So you put that in a test, and assert that the answer should be 713.43.
You know that the distance between Melbourne and Brisbane is 1375km. So you put that in a test, and assert that the answer should be 1375.
You also know that if someone wants to find the distance between Sydney, then Melbourne, then Brisbane that the answer is 2088.43km. So you put that in a test, and assert that the answer should be 2088.43.
Now you run your tests, ensuring that they are watching the code for any changes. All your tests should fail, logically, because you haven’t written and logic yet!
Now you can write the logic to return those correct answers. Every time you save the file, the tests will give you red lights or green lights. Once you’ve got green lights, you can be reasonably confident that your function is working as it should.
Now doesn’t that seem like a much better use of time than the former?
Static code analysis
The other guard rail that helps teams move quickly and safely is static code analysis. Static code analysis helps maintain code quality by identifying poor quality code before it enters the system.
My personal preference is Sonarcloud, it’s free (for public repos) and incredibly easy to set up. It also supports a huge number of languages and frameworks.
While TDD may not be relevant for some projects (such as prototypes), Sonarcloud is valuable for any kind of project. For example, I’ve used it to run code quality checks on Wordpress plugins for MVPs. You’d be shocked at how poorly crafted some well known Wordpress plugins are!
Tools like Sonarcloud are able to do the following:
1) Identify any code smells (e.g. unused imports, bloated functions, unresolved TODOs, etc)
2) Identify potential bugs (e.g. missing null checks)
3) Identify security problems (e.g. potential data leaks or entry points for hackers)
Above all it automates all of the above so other engineers/team members can focus on the bigger picture during code reviews, saving time and energy.
It’s also a great way to get an idea of the quality of an existing project without having to delve too deep into the weeds. Simply configure Sonarcloud and let it run — within minutes you’ll have an idea of the quality of your codebase, and what (if any) areas need remediation.
Conclusion
While the number of tools available for software engineers in 2024 seems infinite — AI assistants, cloud infrastructure, containers, linters, IDEs — for mine, you just don’t get a better bang for your buck than unit tests and static code analysis. It’s impossible to deliver high quality software without them.