How would you feel if you took your car in for an oil change, and when you got it back, the mechanic said: “I’m done with your car. I’m pretty sure you’re good to go.”
Or what if you asked a cabinet maker to build you a custom shelf, and they showed up two weeks later at your front door with something like this.
“Gee,” you say, “it looks fabulous, but I’m not sure how well it’ll hold my set of winter tires in the garage.”
Despite their best intentions, would you think you’re dealing with professionals, and would you think twice about dealing with them again?
Now think about your own work. Do these words ever come out of your mouth?
“I think I fixed that defect.”
“I wrote the code for the feature; I’m pretty sure it works the way it’s supposed to.”
“It’s in QA; they’ll let me know if there are bugs.”
If they do, it’s time to reflect on and objectively assess how you’re going about software development, the quality of the features you’re delivering, and your work ethic as a software engineer.
Whether you’re building something brand new, or working with code that’s been around for years, the software you work with day-to-day will evolve towards chaos unless good software engineering discipline is exercised, especially when a company is undergoing rapid growth.
Why? Because complex systems are, well, complex. And so are people, and how they communicate. Without applying the right mix of innovation, knowledge, skill and discipline, it’s far too easy for complex situations to organically evolve into a big mess. And it’s far harder (though not impossible) and more costly to fix a big mess than it is to prevent it from arising in the first place.
Are you working in an environment where some of the scenarios below are beginning to surface?
If so, you may be contributing to the problem.
As a professional software engineer, it’s your job to not only build the thing right (and jointly with your team build the right thing), but also to not contribute to the mess, following the Boy Scout Rule to actively clean up around you as you go. Sometimes it means saying “no” to questions that are clearly and profoundly conflicting with what are generally recognized as being at least decent engineering practices. This is why you spent several years of your life at a good university or college, why your employer is paying you good coin, and why you’re not working at McDonalds flipping burgers.
So what steps can you take to produce high quality features or bug fixes, and increase your credibility as a competent professional software engineer? Here are a few tips:
Don’t just dive right into design & and coding without properly understanding what the feature or defect entails. Ask questions, do the necessary analysis, understand stakeholder expectations, come up with a plan of action, and consider all the angles. If necessary, do some spikes get a better perspective on potential uncertainties.
Without having a clear definition for your work’s state of completion, you’ll continue to be guessing as to whether you’re really finished with the task. A well-articulated definition of ‘done’ which includes the acceptance criteria that will need to be met and demonstrated is key to shipping the feature or bug fix with confidence that it meets the necessary business requirements.
Whether or not you are doing Test Driven Development, having a great set of automated tests is essential not only to ensure your code works as expected, but to also safeguard it against defects that could be potentially introduced at a later date. Having and maintaining a great test suite helps keep product quality high, and helps engineers deal with the code with fearless competence.
Let’s face it, as a software engineer, the quality of your code is a direct reflection of the mastery of your development skills. If your code smells, others are going to hate going near it, so please don’t subject people to that. Nobody expects you to be perfect, but you are expected to have solid software engineering fundamentals down pat, to want to improve, to learn from others (pair programming and/or code reviews are essential for this), and to avoid repeating the same mistakes.
You may think you’ve written a great set of tests but prove it to yourself by actually running a code coverage tool and reviewing its results. Make sure the coverage percentage is as high as it needs to be for you to be confident that all the viable use cases have been addressed by at least one test. Since you shouldn’t have code for non-viable use cases, this means the code coverage should be pretty close to 100%! Be careful about not succumbing to the temptation to say: “We’re at 80% — that’s good enough”. That 20% that you’re ignoring is what’s going to be keeping your team busy on evenings and weekends when your customers are down; because of that use case you hadn’t anticipated that your code isn’t equipped to handle correctly.
This should go without saying. If the tests don’t pass, no matter the reason, don’t release your code. “Some of the tests aren’t mine” or “the tests are flaky”, you say — it doesn’t matter. If the tests are intended to cover use cases that your code handles (even if in part), make sure the tests work reliably. Broken, muted, or flaky tests are a clear indication that there is still uncertainty about whether your code actually works as expected or not.
Never surprise your stakeholders, at least not in a negative way. Following the tips above will give you a very high confidence that your work will meet expectations, but it’s always best to test your assumptions, so give your stakeholders a demo of the feature you built or the defect you fixed. It doesn’t have to be a long formal meeting; in fact, it’s best when it isn’t. In addition to confirming that the work is done done, it also serves as a great opportunity to spread knowledge and receive praise/feedback that will help you and the team grow.
Learn more about how NuBinary can help your startup come to market through our Fractional CTO service, product development, and more. Visit https://nubinary.com/work-with-us.