Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

No one's perfect, and no matter what we do, we are going to produce code that has bugs in it from time to time. What are some methods/techniques for reducing the number of bugs you produce, both when writing new software and changing/maintaining existing code?

share|improve this question

17 Answers 17

up vote 53 down vote accepted

Avoid fancy coding. The more complicated the code, the more likely there's bugs. Usually on modern systems, clearly written code will be fast and small enough.

Use available libraries. The easiest way to not have bugs writing a utility routine is to not write it.

Learn a few formal techniques for the more complicated stuff. If there's complicated conditions, nail them down with pen and paper. Ideally, know some proof techniques. If I can prove code correct, it's almost always good except for big, dumb, obvious bugs that are easy to fix. Obviously, this only goes so far, but sometimes you can formally reason about small but complicated things.

For existing code, learn how to refactor: how to make small changes in the code, often using an automated tool, that make the code more readable without changing the behavior.

Don't do anything too quickly. Taking a little time up front to do things right, to check what you've done, and to think about what you're doing can pay off big time later.

Once you've written the code, use what you've got to make it good. Unit tests are great. You can often write tests ahead of time, which can be great feedback (if done consistently, this is test-driven development). Compile with warning options, and pay attention to the warnings.

Get somebody else to look at the code. Formal code reviews are good, but they may not be at a convenient time.

share|improve this answer
1  
also most languages can be more or less picky. You want it to be as picky as possible. –  user1249 Oct 17 '10 at 9:45
1  
"Learn a few formal techniques for the more complicated stuff."... for instance? –  Yar Dec 16 '10 at 19:07

Unit Tests let you reduce the number of bugs that pop up a second time. If you find a bug in your code, writing a unit test will make sure it doesn't come back up later. (Plus, thinking of all the cases and writing thousands of unit tests up front is hard to get done sometimes)

share|improve this answer
2  
"Thinking of all the cases up front" leads to clean, fully-specified interfaces, which can only be a good thing. Unit tests are only hard to write if you're retrofitting them to code that wasn't designed with testing in mind. –  Mike Seymour Sep 28 '10 at 17:57
1  
If you can, you should. Unfortunately, most place I've been see unit tests as something that costs more than just "fixing bugs really quick". So, if you can, then you should write tests up front, but if it's not seen as "cost-effective" then writing them alongside bug fixes helps you build it up over time without putting too much of the budget toward just writing unit tests. –  Ryan Hayes Sep 28 '10 at 18:05
3  
"Testing shows the presence, not the absence of bugs." - E. Dijkstra. That being said, automated tests are definitely a very useful way to maintain and increase software quality. –  limist Sep 28 '10 at 20:02

+1 on both of the unit test comments.

Beyond that, set the highest warning level your compiler offers, and make sure warnings are treated as errors. Bugs often hide in those "erroneous" errors.

Similarly, invest in static analysis tools that run at compile time (I view these as an extra level of compiler warnings).

share|improve this answer

In addition to what's been mentioned:

  • Don't ignore error codes - e.g. don't assume that you got a valid result, that a file has been successfully created, etc... Because some day, something will happen.
  • Don't assume that your code will never enter some condition and that therefore "it's safe to ignore that condition".
  • Test your code, then have it tested by someone else. I find I'm the worst person to test my own code.
  • Take a break, then re-read your code and see if you "missed the obvious". Often happens to me.

Lots of other things I'm forgetting at the moment, but the others will surely think of them. :)

share|improve this answer
6  
And if you're so sure that condition X will never happen... use an assert to make sure that when condition X happens, you'll know about it (through an exception, or logging, or whatever). –  Frank Shearar Sep 28 '10 at 18:08

Write unit tests and integration tests.

share|improve this answer

I've developed a fairly functional style of programming, despite my primary languages being C++ and Python. I found that if I pass all of the context to a function (or method) that that function needs to do its job, and return the meaningful data that I'm looking for, that my code has become much more robust.

Implicit state is the enemy and in my experience is the #1 source of bugs. This state can be global variables or member variables, but if results are dependent on something that's not passed to the function you're asking for trouble. Clearly it is not feasible to eliminate state, but minimizing it has huge positive effects on program reliability.

I also like to tell my coworkers that every branch (if, for, while, ?:) is a likely bug. I can't say what the manifestation of the bug will be, but the less conditional behavior your code has, the more likely it is to be bug free simply due to the fact that the code coverage during execution will be more consistent.

Go figure, all of these things also have positive effects on performance too. Win!

share|improve this answer
  • Write less code that does more.
  • Think about the low-level implications and the high-level ramifications
  • Contemplate the abstraction you are creating in your code.
  • Write only the essential complexity if possible.
share|improve this answer
1  
But be careful not to get fancy code when trying to achieve less code. –  gablin Sep 29 '10 at 20:23
1  
@gablin: fancy is in the eye of the beholder in many respects. I can write and read code today that I would have been stupefied at 4 years ago. Haskell today is fancy to me. :) –  Paul Nathan Sep 29 '10 at 21:47

A little less technical answer: don't program when you are tired (9h/day are enough), drunk or 'baked'. When I'm tired I don't have the required patience to write clean code.

share|improve this answer
2  
It usually takes most programmers several years to realize this. It's an important point. –  Jeff Davis Feb 7 '12 at 20:02

Some great answers here regarding unit testing and tools. The only thing I can add to them is this:

Involve your testers as early as you can

If you have a test team, don't fall into the trap of treating them as the gatekeepers for your code quality and catching your defects for you. Instead, work with them and involve them as early as possible (on agile projects this will be from the project's beginning, but we can always find ways to involve them earlier if we really try).

  • Find out what their test plan is. Review their test cases with them - are you covering them all with your code?
  • Ask them for their understanding of the requirements. Is it the same as yours?
  • Give them early working builds to do exploratory testing on - you'll be amazed at the improvements they will suggest.

Having a good working relationship with your testers means that you can catch poor assumptions and defects really early on, before they can do any damage. It also means that the testers feel empowered to help with the product design and catch usability issues when there is time to fix them.

share|improve this answer

Static Analysis Tools

Plugins and apps like FindBugs crawl your code and find places where there are potential bugs. Places where variables aren't initialized and used or just crazy things that 9 times out of 10, make it way easier for bugs to arise. Tools like this help me prevent my bonehead moves down the road even if it's not a bug yet.

P.S.: Remember to always research why a tool tells you something is bad. Never hurts to learn (and not everything is right in all situations).

share|improve this answer

Code inspection or other forms of peer review such as pair programming.

Structured code reviews such as Fagan inspection can be at least as effective and efficient as unit testing and has even proved to be better than unit testing in some cases. Inspections can also be used earlier in the software lifecycle and with artifacts other than code.

Peer Reviews in Software by Karl Wiegers is a great book on this subject.

share|improve this answer

In addition to all of the other suggestions here, turn on all possible warnings to the highest level of sensitivity, and treat them as errors. Also use any linting tools the language has.

You would be amazed at how many simple mistakes can be caught by warnings and how many of those simple things translate into real bugs in your code.

share|improve this answer

A lot of good answers here, but a few things I wanted to add. Make sure you actually understand the requirement. I've seen lots of bugs when the user thought the requirement meant X and the programmer thought it meant Y. Push back for clarification on poor or ambiguous requirements. I know we all like to jump in and code but the more time spent up front ensuring understanding, the less rework and bug fixing there will be.

Get to know the business you are supporting, you will often see things in requirements that are missing or need further explanation then. Know that if you do task Y as stated, it will break existing feature Z.

Understand your database structure. Many many bugs are as a result of a query that is syntactically correct, but returns the wrong results. Learn how to recognize when your results look funny. If I am writing a complex reporting query, I always get a technical specialist to review my results before I mark it as ready to go, they will inevitably see something in the data I missed. Then make notes to yourself what they caught that you didn't and remember that the next time you do something simliar.

share|improve this answer

I think the most important technique is take your time. If you feel you need two days to code a new module, but you boss force you to code only in one day... your code will be probable more buggy.

One of the books I read some time ago, said that you shouldn't live with broken windows, because people won't care if anotherone gets broken... Coding is the same, everyone will care about being the first in doing something bad but fast, but none will care about one hell code, with lots of bugs, and very poor design and style.

share|improve this answer

I follow the practice of Test-Code-Test instead of Code-test-code-test. This helps me to think of use-cases and appropriately frame the logic

share|improve this answer

Use code inspection tools like ReSharper or IDEs like IntelliJ IDEA that warn about many copy-and-paste bugs and others by e.g. pointing out variables that "are written to, but never read". Has saved me a lot of time.

share|improve this answer

Merge multiple bugs into one bug?

share|improve this answer
1  
Technically, yes, but I feel this answer completely misses the point. –  Anna Lear Sep 29 '10 at 14:12

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.