We start a lot of new projects at Atomic, but we also spend a lot of time working with our clients to continue adding new features to software products that we built some time in the past. I recently returned to a project that I spent nearly two years building after eighteen months away from it, and I wanted to share a few things that can make jumping into a past project a joy.
1. Keep App Setup Automation/Documentation Up-to-Date
I purchased a new MacBook Pro during my time away from the project, and I’m bringing another developer in who hasn’t worked on the project before. That means the first thing we need to do is get the app (and the tests) running.
Fortunately, the documentation to get our application running was in pretty good shape. The preferred installation method for a library or two had changed, and there was one new library that wasn’t reflected on our Wiki. It was probably 95% complete, and we were able to get up and running quickly. But it would be very easy for that documentation to fall out of date.
We also use Chef on this project to automate our staging, QA, and production infrastructure setup. And we can use that same automation to spin up local development virtual machines. The Chef configuration serves as another source of information to help fill in details that may be missing from our documentation. Because it runs all our review and production environments, the automation gets exercised on a regular basis. That gives us confidence that it’s up-to-date.
Your future self and team members will thank you if you:
- Make updating documentation part of your sprint/feature rhythm.
- Have new team members exercise (and improve!) the documentation in order to get started.
- Automate infrastructure setup.
- Exercise that automation to keep environments up-to-date.
2. Plan to Update Libraries & Tools
Starting work on a project after some time away is a great opportunity to review the status of your tools and libraries. In some cases, it may actually force an upgrade. And updating libraries takes time. It can be easy to spend a few hours untangling an update to the gems included in a Rails project or evaluating the dependencies in an Ember project.
Sometimes updates are worth the time, and sometimes they’re not. Without going into details about how to discern one from the other, the thing to pay attention to is that it takes time to determine whether there are worthwhile updates to pursue. Plan for that time.
3. Plan to Refactor
No software project is perfect. We’re always making tradeoffs to meet time, budget, and functionality constraints. For my recent project, we were planning to add a significant new feature to an area of the application that we knew needed some refactoring attention. So we included time in our plans to make that refactoring happen.
We were able to improve the software so that it will be easier to extend in the future, add the new features our client needed, provide better logging and process documentation to our client, and improve the test coverage for the part of the application we refactored. Leaving code in much better shape than we found it makes for a happy team today and in the future. Having the time set aside in the plan made the investment stress-free.
4. Run the Tests
This should go without saying, but running our test suite is a huge part of any project at Atomic. It goes along with each of the previous points:
- Get your app “running,” and then run the tests.
- Update libraries and tools, and then run the tests.
- Refactor, and then run the tests.
- Make a change, and then run the tests.
It’s how we know we’re making progress.
5. Improve the Tests
A green test suite is only as valuable as the failures it can catch when it’s not green.
Picking up a project after 18 months away is likely to reveal some of the weaknesses in the test suite. Maybe something has been failing annoyingly on CI, the tests didn’t catch an error during setup, the naming of functions or tests doesn’t make the intended functionality as clear as it could, or the burden of test setup feels more painful than it did last time around. Fresh eyes and new experiences tend to bring these issues to light. Whatever it is, fix it. Make your team’s future just a little brighter.
6. Write Good Full-Stack Tests
Speaking of tests, there is a particular type of test that has provided a lot of value to us dealing with this project: full-stack tests that interact at the boundaries of our application. They’re worth their weight in gold. Here’s our approach:
- Put data in the database, retrieve data from the API, and validate the data.
- Put data in the database, update it via the API, and validate the response and resulting database state.
- Hit the API to create things, and validate the new data in the database.
- Put data in the database, run an export process, and validate the presence and contents of files.
These tests are the key that let us refactor with confidence because they’re isolated from implementation details. They also validate the behavior that matters most to our client and help us understand how the system is supposed to work.
Unit tests are valuable, too. They help enumerate a wider variety of scenarios without suffering from the multiplicative growth that full-stack integration or feature tests experience. But they’re often tied too closely to implementation details to help guide us through a significant refactoring effort or prove that we have a fully functioning system.
7. Use the Opportunity to Improve Documentation
Coming into a project with fresh eyes reveals where our current documentation needs help. It feels great to improve something that will make our lives—and our client’s work—easier in the future.
A joyful return to a project starts with what you do today. Clear documentation, useful automation and tests, and well-laid plans all contribute to being able to tackle updates and support effectively.