Enterprise software architecture and testing: I wasn’t given the whole story
I have been an avid hobbyist programmer for my whole teenage and adult life. Hindsight shows that for most of this time, while I was able to “get things done”, maintainability was poor, collaboration was uninviting, and scaling was a case of rewriting. As could be expected, prior to being a professional, improvement in these skills was a non-priority and therefore glacial.
During my first job — a paid year-long internship — there was initial frustration in having to learn the basic object-oriented software patterns. To date, I’m still in the sizeable camp of those disillusioned by OOP and its religiosity. FizzBuzz Enterprise Edition is something, after enough years in industry, nearly all back-end engineers can relate to. Eventually, the sensible suggestions soaked in, noticeably avoiding problems and pitfalls. It was primarily the doctrine of separation of concerns, SOLID, DRY, and so forth; also technology-specific patterns such as WinForms MVP (I do miss those days). Their benefits were obvious, long-lasting, and without regret or indecision.
My second job was a different story. I was kindly taken aboard as a full-stack developer without prior knowledge of ASP.NET MVC, WebApi, Blazor, etc. In fact, my first few weeks were solely migrating to Webpack, as a person who had only ever used hand-written Java<script>! For learning MVC, I do recall a major hindrance was even though it sounds like a pattern, and Microsoft even advertises it as the “ASP.NET MVC Pattern”, it is in fact a beast disguised as a product disguised as a pattern. This always left me quite jaded, looking for the logic in something which was a mishmash of arbitrary or disconnected reasoning. And yet, there was a more sinister plague during my time in their team.
Like the role before it, there was 0% unit test coverage. Integration tests made sense, black-box testing made sense, and a dedicated QA member to our development team was a blessing. But why would I write code to test… other code? It took an embarrassingly long time for me to realise (and only through demonstration!) that unit testing is to guard against regressions you otherwise would have to spot manually. It is for you, or a team member, returns to the code in ten minutes to ten years, and tries to make a “quick fix”, or feels they’re doing good “tightening up” some logic. To me the most appreciable form of testing is visual regression testing, such as with Chromatic, though writing unit tests certainly helps one reason about what their code is meant to be doing.
I learned this during my third role, which had a fairly shallow learning curve — I had already worked with ASP.NET, CQRS, dependency injection, and all manner of abstractions and layers I had until then considered pointless, a time-waste, buzzwords come to life. But there was a difference: 80% mandatory test coverage, making use of Moq and AutoFixture. It was then I realised I hadn’t heard the full story about these industry practices and seemingly endless layers of abstraction — it’s for testability. In a universe where unit testing was just an alien toolset tacked onto IDEs, I had no hope of realising this. What’s worse, due to tests not being present and making violations more obvious, going off-piste from these best practices made them even more daunting and less appreciable.
The moral of the story? Watch how other businesses and professionals are using the technology you’re using, and don’t ignore unit testing if you’re adopting these particular industry practices. Even 10% test coverage is better than 0% for mitigating regressions, and making sense of what Microsoft is whispering into your manager’s ear.