I’m maintaining and enhancing a medium-sized Rails monolith web app that’s well-crafted, well-documented, and works well in production. But it has no automated tests.
If you found yourself in this situation, which tests would you write first: UI, mid-level (controllers), or low-level (models, modules, etc.)?
Start with automating the manual tests — there must be some way the developers verified things were working while they were building; especially if the build was done collaboratively. Then I’d test the UI; cos that’s what I can see. This would allow me drill down to other parts of the code which needs testing.
That said, the above approve is too time-consuming and — in my experience — doesn’t get much buy-in from management. What has worked for me in practice is not to write tests as a project, but wait until something breaks. Then I write a test case to reproduce the bug, and fix it.
I’ve been in a similar place before with a poorly documented monolith.
My approach was to list all models and then rank them based on their importance to the application’s core logic.
From there, write unit tests for the most crucial models first whilst mocking your data (be it with fixtures or factories). Personally, I’ve enjoyed using FactoryBot.
I found this was the best approach since it helped set up/mock test data that you would need for testing models, controllers, and services later on.
I also enjoyed having the model tests up since it gives some confidence of the integrity of your persistence layer.
I would second focusing on the models. End-to-end tests are work to get right and reliable which may cause them to abandon testing before they adopt the practice. Models by their nature are fairly isolated units and tend to be more reliable.
I am in the same boat of inheriting an app that has no tests. I’m improving it little by little. If I add functionality it gets tested. If I modify existing functionality it not only tests the new behavior but also all the other related behavior.
I found that improved automated testing led to identifying code that needs refactoring/restructuring. Best to keep this separate from testing as it can be a rabbit hole…but a worthwhile rabbit hole.
I like Risk-based testing (RBT) as it focusses the mind on what must/should not go wrong rather than what could go wrong (with anything).
Finally, you might go back to the original purpose. Ask not whether the app is functioning, but whether it does what people need it to. If there a User Experience (UX) role in your organisation then get them involved, if not then make it you. Introduce A-B testing. Get change requests lined to hypotheses and experiments.