Friday, March 23, 2012

Why developers create bugs?


Why developers create bugs? I think this is an interesting question to ask to ourselves (testers). Of course software bugs are coming from everywhere and it is impossible to list all the cause of software bugs. However, if we can identify root-causes of majority of important bugs, we can proactively conduct our testing from beginning to end of SDLC. And our testing will be much more efficient and effective.

The common answer I get is like “Developers are humans. And humans make mistakes.” I agree that there are bugs created by developers’ coding mistakes. “Oh. I put that if-statement outside of for-loop. It should have been inside of the for-loop”, “Oh my conditionals should have been ‘greater’ not ‘greater than or equals’ and etc.” However, I don’t think this kind of coding mistake are majority of the bugs that we’re seeing in a project. I don’t have some accurate statistics about percentage of coding mistake bugs, but from my experience it’s about 10%. (I guess the number 10% by itself does not mean much; my point is that coding mistake bugs take very small percentage of the entire number of bugs)

Before we discuss about 90% of bugs, I like to mention why only 10% of bugs are coding mistake bugs. This percentage would have been higher if we’re talking about the software bugs 20 (or 30) years ago. If we talk about the time when we used low level programming languages like C or COBOL to develop applications. The time when less lines of code for the same logic was preferred because of the high memory cost. The time unit testing was not possible to do or  very hard to do. Now, it’s a different story. High level languages are commonly used in most of companies. And memory is dirt cheap. When was your last time to file a bug on memory leak or deadlock? Highly developed and sophisticated IDEs help developers reduce coding errors. And many software companies recommend or force developers to write unit tests.

Now, Let’s talk about majority of the bugs. In my opinion, 90% (majority) of bugs are coming from the nature of software development process. What do I mean by the nature of software development process? If we abstract or simplify the concept of the software development process, we’ll get something like this; software development process is human activities of transitioning some ideas into a software product or a feature. This transition is quite complicated and multidimensional process if you consider the complexity and scale of current software products and their business values. This transition is not simply getting the ideas to work in code. This transition includes making the code good enough to deliver to the customers. Let’s see what makes developers to create bug.

1. Assumption
In my opinion, this is one of the biggest reason why developers are creating bugs. And it is very hard one to catch because humans always think and speak with some assumptions. The calculator testing question is a good example. (You’re carrying a calculator. You dropped it. I might be damaged. What might do you do to test it?). Many people (even testers) answers with assumption that the calculator is a regular calculator (in their mind) and it fell off from hand or pocket on some hard surface. (I did not mention any of this in my calculator question) This kinds of assumptions are made when business people talk about software, project manager writing spec and developers writing code or speak about technical details. And some of assumptions that we make are dangerous assumptions.If we do not realize the dangerous assumption we make, it will bite entire project team badly later.

2. Implicit requirement
Implicit requirements are requirements that are not shown in requirement documents or spec but it is important requirements. Here is an example requirement: this medical device should operate properly between 100 and 150 AV. And let’s say developers make it work in that range. Good. Are we done? I would say no. There are some Implicit requirements we need to check. What happens if voltage going out of normal range? Going to 99, 98,97 AV from 100 or going to 151,152, 153 AV from 150? Will this medical device fail in a way to harm the patients or it fails gracefully? Or do we need alarm when device receives voltage near 105 or 145 AV? Implicit requirements are not outside of requirements. Lacking in business perspective and merely focusing on technical details often cause developers to be blind about implicit requirements.

3. Poor design
What I mean by poor design is not about high level architectural design. Generally speaking software architects put a lot of effort to come up with good design and normally architectural design is pretty sound (reliability, modularity, extensibility and etc.) What I’m talking about here is the design that individual developers come up with for his/her own feature. Normally, this poor design causes existing feature very fragile as they add more code. Good way to figure out poor design is to ask devs to explain how each class or component interact each other to complete a workflow using diagrams. You can easily catch their design flaws (if there is) and it is a good way to do white box testing without looking at the code.

4. Working on someone else’s code
This one has to do with some emotion. Adding new feature or fixing bugs on existing code that was written by someone else is not very fun business. Different coding style, different thought process, not enough comments, different class/method naming and long debugging time make the dev to feel the existing code is crappy. If it is an old legacy code, it gets even worse. When this negative emotion overwhelms the dev, mistake happens.  It’s good information for testers to know if the dev is working on his/her own code or someone else’s.

There are some more but I will stop here. The point I’m trying to make here is that software testing should be proactive not submissive. Verification of use cases are not majority of testing activity (shooting for 10% of  bugs) and verification only happens after dev hand over code to test team. Let’s understand how much software development process has evolved. Let’s understand what kind of software testing problem we’re dealing with NOW. Let’s not be stuck with old testing mind. Testing should evolve as development process evolves.