DEV Community

Cover image for Towards zero bugs

Towards zero bugs

Jonathan on March 17, 2019

I am on a personal and professional mission to write bug-free code. Software with zero bugs may seem like an ambitious goal. Over time, defects in...
Collapse
 
akatrevorjay profile image
Trevor Joynson • Edited

You made a logic error in your code:

if (hidden) { show(); } else { hide(); }.

I think you meant the opposite.

Also software that is decently complex will always have bugs. Don't get me wrong, you get better at identifying common causalities over time as you have shown here, but given sufficient complexity, you will eventually have bugs. It's just entropy at work.

Collapse
 
conw_y profile image
Jonathan • Edited

Thanks for pointing out the error! I've fixed the bug.

Collapse
 
qm3ster profile image
Mihail Malo • Edited

Hewwo, pwease change

- if (hidden) { show(); } else { hide(); }
+ if (hidden) { hide(); } else { show(); }`.

if hidden is the current state.
OR, if hidden is desired state, change

- if (!hidden) { show(); } else { hide(); }
+ if (!hidden) { hide(); } else { show(); }

You didn't flip the cases when negating the predicate.

Stylistically I would ofc prefer one of:

if (hidden) show()
else hide()

or

hidden ? show() : hide()

for a better signal/noise ratio (which makes bugs more evident)

Thread Thread
 
conw_y profile image
Jonathan

Apologies for the delay. I've fixed the logic error you rightly pointed out.

Collapse
 
nickytonline profile image
Nick Taylor

Nice post Jonathan!

Linting and static type checking definitely remove a chunk of these issues

I'm trying to remember for C#, there was a tool that would check for potential memory leaks that wasn't the memory profiler. The name is escaping me at the moment.

As well for C# async/await, setting ConfigureAwait(false). Where I used to work we create a rule using the Roslyn compiler to check for this.

Anyways, looking forward to your next post!

Collapse
 
qm3ster profile image
Mihail Malo

I have a problem with the way Subtle logic errors section is phrased.

if (hidden) { show(); } else { hide(); }

is not a clearer way to write

if (!hidden) { show(); } else { hide(); }

It's different code. Did you mean that a bug was fixed, and not a refactor occured?

Same for the next one:

for (let i = 0; i < 10; i++) { ... }

is not clearer than

for (let i = 0; i <= 10; i++) { ... }

It is different code.

for (let i = 0; i < 11; i++) { ... }

could be the clearer rewrite of the same code. (Is it though? What's 11?)

The bigger issue there is probably the magic number 10.
Better than any comment you could leave would be extracting it to a named constant. A constant semantically named for the reason it's used there.

These are both good code:

for (let i = 0; i < 10; i++) { ... } // BAD
for (let i = 0; i <= 9; i++) { ... } // BAD

const len = 10
const lastIndex = len - 1

for (let i = 0; i < len; i++) { ... } // GOOD
for (let i = 0; i <= lastIndex; i++) { ... } // GOOD
Collapse
 
bosepchuk profile image
Blaine Osepchuk • Edited

Great post, Jonathan. Zero-defect software is a worthwhile goal (one that I've been pursuing for the last couple of years).

Here's my code review checklist.

We've been using this checklist at my work for a couple of years and it really works for us. We find a only a handful of minor errors in production each year (which is a fraction of what we found before we used this checklist).

Watts Humphrey published extensively zero-defect software. I wrote a summary here.

But, even if you don't want anything to do with PSP (and most people don't), chapter 8 of PSP: A Self-Improvement Process for Software Engineers lays out the economic case for producing high quality software. Spoiler: it's almost always worth the effort for software that's going to be around for a long time.

Collapse
 
conw_y profile image
Jonathan

Thanks for sharing, Blaine! That writing by Humphrey looks very interesting. I'll certainly read up on it.

Collapse
 
adam_cyclones profile image
Adam Crockett 🌀

Imagine bug free code, how would we improve that? If I change your checklist to include screen readers in multiple languages, would I have just created more bugs? It's a moving target, great to aim for but imperfection is reality.

Collapse
 
conw_y profile image
Jonathan • Edited

Yes! Someone referred to accessibility! It is certainly critical, as you mentioned, for those who rely on screen-readers and other assistive technology to be able to access and use applications.

I have added a short section on accessibility, but as a mere paragraph wouldn't do the topic justice, I will publish a separate blog post on the topic and/or reference the best sources I can find.

Agreed that imperfection is the default state, and we often can't cover all bases. I think that as we push forward and aiming higher, for more reliable and bug-free code, we will build up tools and expertise for dealing with a large number of concerns, including accessibility, efficiently and effectively.

Update: I have added a section on 'Accessibility'. Great idea – so thumbs up to you. 👍

Collapse
 
qm3ster profile image
Mihail Malo

Some stuff I'd like to add:

  1. Write regression tests for all sorts of bugs you find. The first step if you find a bug through production use should be to write a failing test for it, even if the software isn't being developed through TTD.
  2. Write UI tests.
  3. Use fuzzers.
  4. Use mutation testing.
  5. Use TypeScript/mypy
  6. Use linters.
  7. Use formatters. Yes, formatters. Having your code consistently formatted will instantly reveal when you mistyped something parseable but different from what you meant. And it will minimize git diffs, making them easier to review.
Collapse
 
ben profile image
Ben Halpern

Wow, fabulous post.

Collapse
 
conw_y profile image
Jonathan

Thanks mate! Will try to improve it also, over the next week.

Collapse
 
aaleksu profile image
alex anisimov

Why on Earth for (let 0; i < 10; i++) {...} will iterate 9 times?

Collapse
 
conw_y profile image
Jonathan

Apologies, my bad. Thanks for identifying this. I have corrected the error.

Collapse
 
aaleksu profile image
alex anisimov

Actually, all you wrote is more or less fair, but usually you finally learn how to deal with all of them. But bugs might float up when you implement some really complicated logic - there, where behavior and result are hard to predict or manage.

Collapse
 
aaleksu profile image
alex anisimov

Good (thumb up)

Collapse
 
robdwaller profile image
Rob Waller

A good list for any new or junior developer to review.

Collapse
 
tomerbendavid profile image
Tomer Ben David

Great one I just want to emphasize that requirements are always non bug free so even if code is bug free it's non bug free by definition

Collapse
 
conw_y profile image
Jonathan

Great point. Certainly, requirements cannot be taken as gospel. Rather, they must be understood and integrated. Where there are contradictions and ambiguities, those must be questioned and either settled or the requirements changed. Thanks for your comment.

Collapse
 
miberg81_0 profile image
Michael Berger

Thanks for sharing! Will use your list next tine

Collapse
 
pavelloz profile image
Paweł Kowalski

Tldr: hire a qa, write tests and check your code.

Collapse
 
conw_y profile image
Jonathan

Thanks for identifying the error in the ‘off by one’ code. I have corrected the error.