I got one big page with multiple flows and forms to add new features and probably tweak a little what’s already there.
Of course, there were no tests. And then I opened the code and couldn’t make sense of it.
Seems familiar?
First step: Adding tests
Because of time constraints, I’ve decided to focus primarily on the happy paths and not on getting as close to 100% coverage.
I also knew that this would mean integration over unit tests.
Enter Testing Library
Testing Library and Cypress are truly amazing tools.
In the words of the Testing Library team:
The more your tests resemble the way your software is used, the more confidence they can give you.
Last time I showed you this:
https://github.com/Noriller/refreshing-way-test/blob/master/src/app.spec.jsx
Here’s an excerpt:
describe('when you submit a form', () => {
const titleValue = 'my title';
const bodyValue = 'my body';
describe('inputting both values', () => {
beforeEach(async () => {
await userEvent.type(getTitle(), titleValue);
await userEvent.type(getBody(), bodyValue);
});
it('the title input has the input value', () => {
expect(getTitle()).toHaveValue(titleValue);
});
it('the body input has the input value', () => {
expect(getBody()).toHaveValue(bodyValue);
});
Does it matter which framework was this written in? Or the implementation details?
As long as you know enough of the testing library API or can at least guess, you know exactly what’s going on.
Testing blindly
What I did was literally open the page I would be working on and go, step by step, testing for what I was seeing, checking what I had to click or type, and then checking what kind of connections were coming and going and mocking then by literally copying the returns (if something like Mirage.js or MSW were already in use I would be even able to skip that part, but that’s something for later).
The only problem I had was with the AntD version which has testability problems with the dropdown and date picker, coupled with one tricky error message that was actually a copy and pasted error from an earlier step… so… always test if an input/select actually got the value you gave them.
The happy path alone, even skipping some optional forms… took me all the way to 80% of the whole feature!
Time invested? One day (plus some more hours because of AntD that, with the lesson learned will make testing easier for future endeavors.)
And now I had an overview of what it was supposed to do. Step by step.
Second step: Refactoring
If at first, I haven't touched the code (except for that one error message, because well, anger…). In this step, I didn’t touch the test code at all.
Having tests I knew I wouldn’t be breaking anything (at least in the happy path) and I could refactor, move files, split components, files and functions to my heart's content.
Time invested? One day.
I also was able to see the implementation details and noted places I could possibly abstract to account for the new feature, I got familiar with the current code, things I could use and others I could improve.
Next step: New features and new tests
When was the last time you got to work with dozens of files with thousands of lines of code and dreaded it?
It certainly wasn’t my first time, but it was the first one I put my foot down to, before anything else, doing tests, then refactoring, and only then actually doing “something productive”.
A few days of investment to have a clear picture of what’s going on and how the code works is a bargain!
I would take twice as much just complaining about “how awful the code is” and that everything I do breaks something and I would still not know as much about the current code as I do now.
As Uncle Bob says:
The only way to go fast is to go well.
Now it’s a matter of adding more code and tests to a familiar codebase with the confidence that the tests will tell me when I break something.
TLDR
Got to work in a legacy or unfamiliar feature? Or maybe just some untested mess that you made long ago and don’t even know how it works?
- Add tests. (the amount of the code you need to check is minimal in this step)
- Refactor. (if you can’t really see places to improve, then you wouldn’t be in this pickle right?)
- You’re free to work in a more familiar codebase. And if you break something, the tests will tell you.
Cover Photo by Mateusz Butkiewicz on Unsplash
Top comments (0)