Software bugs are errors in the instructions written by programmers for computers. Rather than errors in syntax, which are usually weeded out before instructions are executed, bugs tend to be logic errors that cannot be discovered by a computer.
Take for example these instructions in English:
- Turn hob on.
- Prepare mug with teabag.
- Pour 1 pint of water into the kettle.
- Put kettle on hob.
- When kettle boils, pour water into mug.
When tested, these instructions may be seen to work, but when carried out 'in the field', it may be seen that the hob is still on at the end of the process, and if left, may cause a fire.
Bugs can occur in any kind of software, including markup and stylesheets, object-oriented programming languages, and higher-level tools like flowchart-driven programming - and the only way to ensure that programs are 100% bug-free is to test every part of the software for all cases.
So for example a program which simply multiplies numbers by 2 is not fully testable - because there are an infinite number of numbers. But more complex programs are infinitely more untestable as there are a bigger range of 'input variables'.
So how do you make sure programs are bug-free enough to be put to safe use?
One way is to test 'edge cases' - for example if your program which multiplies numbers only has to deal with integers, and the integers need to be between 1 and 100, then it makes sense to test 1, 1000, and a few numbers in between to make sure.
It also helps to use automated testing - using tools like selenium for firefox, which allows you to browse a web application recording your process, and to play that process back any time you want.
Another tool is 'test driven development', where you write the tests first, and then the software to make the program work. So at first your tests will fail, which is expected, and then as you write more code, new tests begin to pass - but if you introduce any rogure code which affects other parts of the system, you can re-run the tests and see that others begin to fail - which helps you to indentify the problem.
"Dry-running" and stepping through programs is also a very useful way to pre-empt bugs. Dry running is where a human being reads the program code and tries to work out how the computer would execute it; stepping through means running the program at a speed controlled by you - so that you can see variable values and the path of the execution as it happens.