Why you shouldn’t care about quality
Ok, this is a clickbaity title and of course you should care about quality. In this post I want to highlight how one of my projects failed (specifically failed in terms of I failed to write tests) miserably, how things are different now, and what I ultimately learned from the experience.
The Promising Start
Some time ago, I was in charge of writing a software application that:
reads some data from an external source
apply business logic to transform the data
write the transformed data into a data warehouse
Sounds like a pretty standard ETL job. But there was one twist: the application also had to read deltas (user inputs) from the data warehouse and re-apply the business logic and output it again in near real-time.
This core feature necessitated some kind of streaming application, so I decided to use the relatively new (at the time) Kafka stack of Kafka / Kafka Connect / Kafka Streams, now more commonly known as the Confluent Platform. Coincidentally, the platform team supporting the application developers decided to onboard to a Kubernetes stack called Openshift. It felt like some exciting times were ahead, so many cool new technology to work with, so much value to deliver to the stakeholders.
Since everybody was onboarding a new platform, there was a lot of head first learning involved. I wrote multiple posts to the Kafka Google group, had to pull frequent all-nighters, worked weekends, and did some other really unhealthy things I will never consider doing again. But it was definitely worth it, because I more or less finished the application in a fairly ridiculous amount of time.
Until everything fell apart.
Things Fall Apart
Turns out, business requirements change. After I finished my first implementation, I was trying to improve its quality by post-writing tests and refactoring it because it was so hastily written. Then came the news: I needed to make calculation changes. No big deal I thought, I just need to change the component that deals with the calculation. The change caused unexpected errors in downstream calculations, and as you can probably imagine I started panicking because I couldn't untangle the mess that this project had become. In my head, there was the initial implementation, the half-refactored version, and the calculation fix all munged together and I couldn't think straight. Productivity went down, and I started becoming visibly unhealthy. After I finally made all the pieces work together again, there was another required change that came out of nowhere. And another followed. And another followed. I never found the time to write tests for the entire project.
Hasty development on a tight deadline was not the sole contributor to not writing tests.
Our Openshift stack did not work well with Kafka Streams applications especially when they were stateful.
Our jenkins environment was never fully supported by anyone because of the lack of time and resources.
At one point I had to fork off to a custom version of Kafka because there was a bug on the Kafka side.
Of course the largest blame for not writing tests is on the engineer, but I believe the engineer being okay with not writing tests in the first place is largely a cultural problem.
How Things Improved
I eventually rotated out of the team because I could not take the stress anymore. The project eventually got rewritten multiple times depending on who was working on the project. Even though I was working on different projects, the engineering environment did not really change for a while. Then came in a few waves of great positive influence.
Cycling of personnel: A lot of oldies who had a lot of tribal knowledge had moved onto different companies or teams, which was great in forcing the tribal knowledge to become documented. Then, some great people came in to backfill those positions and this was a very important part of reinvigorating a stale culture.
Standardizing on development methodology: For a very long while our team members were arguing against each other with the topic of monorepo vs. polyrepo. We eventually decided to go full polyrepo fashion (in compliance with the 12 factor app) as much as other monorepo people wanted to continue using the monorepo. Having this lengthy argument conclude was a great relief to everyone, as topics like these become a massive time sink when left unattended.
Relying on hosted tools: We decided to use Gitlab to host our code and to run our CI pipelines, and converged onto a hosted instance of Kubernetes. We started using Databricks as our compute environment and scheduled everything with Airflow. Having standard tools for everyone meant that developers had confidence that they will get the required troubleshooting, and their problems will be solved.
This set of improvements had one effect that surfaced itself after a while: everybody had more time. When engineers have more time, they care about the code they write and they review the code that others write. This leads to a culture in which people care about quality in general. I believe this is the ideal way for an engineer to learn about quality and apply it to their daily work. As I stated in my previous post, if you want to go above and beyond a glorified Googler, you have to slow your work down and actively try to learn new things. And the ideal way to achieve this is with the help of your engineering organization's culture.
I really like this tweet as it perfectly sums up the lesson I learned from my failed project. Yeah, the project failed. But that's okay, that failure doesn't define who I am as a software engineer. I continue to work as hard as I can to foster an engineering culture that helps me, and everyone around me succeed.
















