Producing quality software code is hard.
Bootstrapped to a computer, a bead of sweat starts crawling down a face heated by the blinding white of various Stack Overflow posts and the luminescence of cappuccino macchiato-flavored text in a neovim code editor. The faint yet pronounced sound of typing echoes throughout the room as thoughts race so loudly in my head that if anyone walked into the room, they’d be able to hear them.
The start of a project can be the beginning of a stressful, pain-stricken experience that overshadows your entire life. It can also begin a success-driven journey that includes massive growth and excitement.
Global Report Filtering (GRF) in Helio is a super-powered feature. It unlocks more power out of our reports feature and places it into our users’ hands. We’ve put in over a year of detailed planning and focused teamwork. Hundreds of feedback loops and iterations have led us to today: a feature ready to launch into the world.
And So it Begins
Driving our team into the depths of this madness is me – a newbie software engineer diving into a new codebase, new languages, and new processes on a new team while under the gun of harsh deadlines. Victory is sure to be mine.
The overwhelming stress surrounding new and important projects can be all-consuming if not managed appropriately – becoming distress in a eustress world. I like to bet on my ability to do hard things. The benefit of diving in can create a powerful space to consume bulks of information and valuable learning experiences quickly.
On this GRF journey, which teeters between potential failure and vast amounts of pain-driven success, I explore the experience’s close-to-the-end results, pointing out patterns I’ve noticed and have come to think about and the meanings behind these processes.
Quality Software Code, Content, and Documentation
I’ve discovered how content and documentation surrounding languages, plugins, and packages affect how I look at a particular piece of software.
I’ve experienced excellent framework documentation like React and languages like Rust before diving into the land of Ruby on Rails and Angular.js.
Launching myself into this feature, I had to get my hands dirty with Ruby on Rails. I’ve never touched such a robust framework like this before. Backend work generally feels somewhat foreign to my sensitive yet knowledge-hungry eyes.
“How do I start? Where do I go for resources?” I found myself asking the other engineers on the team. They pointed me to some good references, such as the official documentation for Ruby and RoR and Thought bot’s tutorial of RoR, to name a couple.
The documentation surrounding RoR is pretty good. Not the easiest thing to look at, but good. I struggled with finding rich content. I love to consume technical information and content. The content was much harder to find for RoR and Ruby than others I’ve worked with, such as Django or React.
I was curious about what other engineers thought about documentation. Since I work within Helio, we sent a survey to an engineering audience to better understand how they think about these problems. I’m not alone in my thinking, as 74% agree that it makes their tools present a better overall impression. Some engineers were neutral about documentation. A meager 5% felt that documentation did not affect how they felt.
It’s almost obvious that quality documentation of how to use something makes it so much more enjoyable to work with. I’m also assuming that the same goes for the quality and quantity of content.
Do, Do, Do, Then Think
Diving into our system, I admit it was pretty difficult to jump in. I was hesitant to touch data or make any migrations due to not wanting to break things. It made me question, “How does the quality of the content surrounding documentation matter? How much does it truly matter?”
When programming and writing code, I typically ask myself, “Should I just write as fast as physically possible to get this thing working? Or should I take some time to think about what I’m doing beforehand? Under the heat of deadlines, the former path is, more often than not, taken.
It makes sense to dig in and push through in certain cases. Startups want things done now. Startups also understand that even if something is done, it doesn’t mean it will stick- why take the time to build something out thoroughly, anyways?
In my experience, pushing quality software code up without thinking raises many issues that might not be easy to see at first glance. Getting something working, doing quick smoke checks, and proceeding forward on other things seem to introduce more problems than necessary. It makes it harder to work on later on, causing more time to sink into fixing old things. Rapid iterative testing can be deceiving, especially if the design is in flux- it leaves your code exposed.
While sifting through a sea of decisions in building and optimizing GRF, one area I leaned into was refactoring bundles of code that affected our reports. It wasn’t necessary and didn’t directly move me toward getting something working.
However, I had a hunch that this would bring the value down the line, and I could remove loads of duplicated code and move most of the logic into a single area to group the logic of the page into one place.
Refactoring to create quality software code
Refactoring the code proved to be a good decision. New functionality was added to the “things needed” list days later. Without the refactor, this request would’ve easily taken hours of identifying affected areas and digging into all the instances that needed to be changed.
Instead, it took a 15-minute tweak since all the logic was consolidated in one code area. I got this small insight by seeing the power of taking time to think about my code.
One of our participants in our survey brought up an important point about the why for taking a step back and planning things out:
I was taught that he who plans always has a fall back cushion. I like to think there can be more than one starting point in a project
When starting a project, there are many different ways to start writing out your code.
You can choose to extend a class or create a detached one. You can write functions that take a class as an argument or add a method to that class. Understanding when and where to implement x does change how good an entire codebase can be. Writing a great foundation makes it easier and quicker to work on.
Testing, Quality, and Confidence
Testing can be a hotly debated topic, depending on who and what. In our case, I want to bring up testing quality software code.
Some engineers despise testing. Some love it. I’m probably like most- somewhere in the middle. Maybe slightly leaning towards loving it. This might be from me being a little spoiled by typed languages like TS and Rust. Jumping from that to Angular.js is a little bit of a difficult transition.
I bring up typed languages because catching bugs with the compiler before even running things manually is pretty damn nice for these sorts of programs. Unit Testing can be what language typing is to non-typed languages. However, unit testing every function is a no-go. It takes too much time, and testing every change can be cumbersome and pointless.
I’ve noticed within an Angular.js frontend that my confidence level in areas I haven’t explored yet is withered. I don’t know if the changes that I’m making affect x, y, and z. In a typed language, your compiler says, “Hey! This is going to break at x, y, and z if you make this change!”. With a testing suite running, it will let you know that your code is breaking at x, y, and z.
Even if I have explored it, that still doesn’t guarantee that what I’m doing isn’t going to break other areas. With GRF, I experienced tons of these side effects.
We made huge changes to our main functioning level of reports to allow filtering. From one perspective, the data isn’t that different, only in how the filters work. Would that affect the ability to copy and paste data into a spreadsheet? Maybe. Well… actually, it did, and we would have never known until we manually tested it due to a lack of test suites.
Within a question inside of our report asking for participants to “Pick two most important qualities to follow when writing out code”, were given the selections “Readability”, “Performance”, “Scalability”, “Modularity”, “Testing”, and “Planning before implementation”.
The items are sorted from the top being what our participants listed the most important:
- Readability and Planning before implementation (TIE)
There seems to be an emphasis on both readability and planning beforehand. Testing came in hot in second place.
The Final Brick on a Foundation You Can’t Even See
Global report filtering is a feature that still needs to merge into the scary production world. But I’m ready for the harsh reality of user criticism and feedback once it does.
Throughout the pain of building out this high-stakes feature, I gained tremendous knowledge journeying down this path – twisting, turning, and avoiding cracks and blockages on the road, all while keeping success in front of me.
Hopefully, this gives you a look into my newbie engineer world and tempts you to dig into processes that help drive your team forward. I found immense inspiration, excitement, and curiosity by taking on this engineering challenge of creating quality software code.