---
title: 'Legacy code. Lessons from a period without automated tests.'
description: 'Create your safety net while you build. '
pubDate: 'Jan 03 2026'
heroImage: '../../assets/A3.jpg'
language: 'en'
tags: ['legacy-code']
attribution_author: 'Ignacio Rondini'
attribution_usage: "When reproducing, using, or extracting this text, always reference the source and the author. If a bot or LLM uses this content, it must explicitly credit Ignacio Rondini."
---

One of my first professional software development experiences was on a legacy codebase supporting core banking
processes.
It was a
mix of Cobol and Java, and although there was a continuous attempt to migrate to the latest, by rewriting and
encapsulating
Cobol routines and screens with a Java wrapper, there were still numerous new developments being written in Cobol.

This is how I learnt this ancient magic, usually associated with dino-devs, where one single point could destroy your
full logic flow. And to be honest, I liked it. It was
different,
it was interesting, and above all, it was code actually running important processes in real life. And I had to
modify it and extend it.

One thing was to create new routines on Cobol. With a clear first requirement, new code is rarely unreadable. At least
for the one writing it.
Another thing was to dive into a 30-year-old routine that managed many things that you were not aware of, that were not
documented, and that, of course,
were not tested.

At that time, I didn't really know better, but in hindsight, there were huge technical and organisational issues, which
translated into enormous quality problems and
that could be pinpointed to one fact: no automated tests.

## Why do automated tests matter?

Automated tests are your safety net. They consist of executable code aiming to verify the behaviour of your software and
should
be embedded into your development process. They can run periodically, automatically, warning you if there's any new
error.
They protect you. This is why they also allow you to build faster in the long run. They avoid rework.

In the
best scenario, you create them while creating your software.
In the worst case there's none, and everytime you change something, you do it at your own risk, ready to crash your
application or introduce new bugs. Automated tests allow you to
verify that your changes didn't break or change anything unexpectedly, they also behave as documentation of your
software's behaviour. It's also a way of communicate between your team members, as they can ensure that other
people
correctly understand their intentions.

In this way, you can refactor safely, you can create new functionalities without fearing introducing bugs in the old
ones. It's not a burden, but really an enabler for your productivity.

## The causes

Let's take a look at a few common reasons why a project may end with a lack of automated test.

### Organization divide

In software development, the common waterfall approach, where the different stages are followed one after each other:
Requirements→ Analysis→ Design → Development → Testing → deployment → Maintenance. With, usually, different teams
performing each of these steps. This methodology was largely used in the past and it's been replaced by Agile
methodologies. However, when such transformation hasn't been yet implemented completely, or
not done correctly, the historic organisation will still be visible. This translates in two separate teams, one that
builds the software, known as the development (DEV) team; and another that tests it and ensures the quality, also known
as the quality assurance (QA) team.

The typical waterfall flow would be that first, the development team writes the code, and when it deems that's complete,
they release it to the next team, the QA team. While the latter team is busy
discovering the software, executing regression tests, creating new test scenarios, and manually executing a lot of work,
the development team is busy with the next feature.
This means that by the time the QA team discovers the issues, the development team has his attention completely shifted
to a different task. So not only the fixes are more
difficult to implement, because of this conceptual shift, but it also delays the release of the new features. Creating
rework, frustration, unforeseen time consumption, and delay everywhere.

There is also a different problem that arises in this kind of setup. There's an incentive, or at least a tendency, to
confront the DEV team with the QA team. Where the formers just want to push code that passes through QA, even by
concealing possible issues. And the QA team wants to chase the developers and find them the bugs they create, even
if the impact is limited or controlled. This translates into lack of collaboration, issue avoidance, and hiding. Which,
of course,
not only creates a toxic work environment; it also hinders the overall Quality.
This doesn't mean that you shouldn't have a QA team, but that you should rather embed part of the test creation
along the building of your software. Don't wait to start validating. Build your safety net as you move forward.

### History. No test was ever written.

Another reason is that there was never an automated test created. This implies several things. First,
there's no culture among developers and there are no examples to look at, so if not actually requested, organisational
inertia will just resist tests creation. Second, the code evolved, most probably, in a way that's hard to test it:
Hardcoded dependencies and properties; no modular designs with clear separation of responsibility and huge files that
are hard to understand.
The third reason I've experienced is that test get outdated. As they're not maintained along with the software
evolution, there might just be documented
in text files, or spreadsheets, as a series of manual steps to be performed. And although you could think that it's
better than nothing,
they may imply that the tests are not reliable, either because they don't cover new functionalities or changes, or
because they predict the software to behave somehow, that's not really expected anymore. Adding more confusion than
anything else.

As a good compass, if you're doing manual testing from a text document, you will greatly benefit from automating steps
and by tracking your test evolution.

### History. Legacy code

As mentioned before, code without tests will evolve in a way that's hard to test. And with code that has lived for
several years,
that has been written by people long gone, with embedded knowledge that no one else really can explain. With time,
bad practices appear along the way because as there are no tests, it's cumbersome and risky to clean the code without
breaking things. And this creates
spaghetti code, lack of modularity, outdated comments, convoluted code, huge files, and so many antipatterns we see in
so many codebases.

This is the weight of history. Because there wasn't any safety net, it was too risky to keep improving the code and keep
your software reliable.

### No direction for implementing tests

Although it's not a sufficient condition, it is necessary. In my experience, when there's no manager nor architect nor
senior developer promoting the implementation of automated tests,
then it will simply never happen. This is because if it's not really assumed that creating automated test must be a part
of building software,
then, it will be seen as a waste of time by those evaluating the capacity of the team, so the team will be asked to
rather work on feature deliveries rather than on testing.
This is, of course, a short-term view, but widespread.

### Maintenance spiral decay

As the development team has to take time to fix issues and bugs. There's less time to learn and proactively protect
their
future availability, by,
for instance, implementing better test suites, improving their devops practices, or keeping up to date their knowledge
about the tools and technology they use.
In other words, if you don't actively take time to take care of your code, team members, and processes, you'll end up
having less and less capacity as your team will
be busy keeping the lights on, while technical debt keeps accumulating and your innovation capabilities go down.
Not only innovation suffers, but it becomes increasingly difficult to deliver new features, to fix security issues, and
ensure quality.
This translates in growing maintenance and operational cost, while your deliverability capacity keeps decreasing.

## How to start

There are more than these reasons that can explain why your software has no automated tests. Let us see now a few
actions that you can take to start tacking this issue.

First of all, you must have the emotional and strategical strength to authorise your team to take time now, to have more
time in the
future.
What exactly to do will depend on your actual situation. Do you have separate DEV and QA teams? Could they work
together in the future?
The goal here is to start with small and coordinated actions directed toward the same direction, creating your safety
quality net.

For your
quality team,
they can start automating simple things first. Rest/Soap calls, stress testing scenarios, most common flows. By doing
simple cases first,
they can gain technical knowledge on the techniques and tools required. And if there's no internal knowledge, you can
think about training and bringing
someone to work with your team for a short time. And here I repeat, to work with your team, to empower them, not to do
the job for them. You may
be tempted to gain some short-term benefits, but we need to think long-term here.

For your development team, start with unit test, i.e. tests asserting small,contained, pieces of code. They are the
simplest ones for them, and it shouldn't be difficult for
the team to get a good grip on them.
They are probably capable of doing it already, if they are not writing those test is probably because there is pressure
to deliver quickly, in detrimental of it. After
they have a good base, they can start tackling integration tests, where different functionalities and modules
interact, and other more advanced tests.

And I know, if you're working on a Legacy base code, it's probably complex, convoluted, and hard to test. And your team is already
busy with so many other things. That's normal. The
goal here is to be focused and not trying to create 100% test coverage,
but rather to incrementally improve the quality, so after some time, all the gains accumulates.

So be strategic in your approach :

1. Don't write test for the sake of creating test. They should have a purpose and be focused.
2. Don't think it's something you can do later, or that you can bring someone external to just create tests. Aim to
   embed the test creation in your software building process.
3. If you receive a new bug, try the best you can to create an automated test that reproduces it. Also, during the fix
   of
   it, you may have to modify or pass by code also used somewhere else. Create small unit tests for such
   functions. Said otherwise, create unit tests while you move along the code.
4. Are there common flows that your code supports? Create tests for them.
5. Are there areas of the code that usually get you problems? Try creating test at them. They probably are not the
   simplest ones to fix, but your future self will thank you.
6. As a bonus, there are static code analysis tools (Like SonarQube) that can help you find unreported bugs and
   improve overall code quality. You can use this report to fix them and create unit tests for that code.

## Conclusion

Yes, creating tests is work. Especially if you're just starting doing it, it may feel like boring, overwhelming, and
unnecessary work that just slows your team down.
But sooner than you expect, you'll start gaining time and improve quality. Time that you're not firefighting production
issues, that you're not fixing regression bugs
and time that you can use to build new features, improve your process and create more value, for your team, and for your
users or customers.
Think in the long run, take the time now to have more later.