Testing and debugging are essential phases in the software development lifecycle. Testing verifies that a program produces correct results, while debugging is the process of finding and fixing errors (bugs) once they are detected.
Debugging is the systematic process of locating, analyzing, and correcting errors (bugs) in a program so that it functions as intended. Bugs can be:
Dry running involves manually tracing the execution of a program using sample data on paper, without using a computer. The programmer follows the logic step by step to detect logical errors before running the code.
Example: Tracing a loop iteration by iteration, writing down variable values at each step.
Desk checking is a broader, informal review of the source code, typically done by the programmer or a colleague. It checks for:
Key Difference: Dry running traces execution with data; desk checking is a general code review.
In Black Box Testing, the tester has no knowledge of the internal code structure. Tests are designed based solely on:
This technique verifies that the software meets its functional specifications.
White Box Testing (also called structural testing or glass box testing) requires the tester to have full knowledge of the source code. It tests:
A breakpoint is an intentional stopping point set in the code (using an IDE like PyCharm or VS Code, or Python's built-in pdb module). When execution reaches a breakpoint, the program pauses, allowing the developer to:
# Using Python's built-in debugger
import pdb
def calculate(a, b):
pdb.set_trace() # Breakpoint set here
result = a / b
return result
calculate(10, 0)
A Watch (or Watch Window) is a debugger feature that lets a developer monitor the value of a specific variable or expression continuously as the program runs. Unlike a breakpoint that pauses execution, a watch tracks how a variable's value changes over time.
A unit test is an automated test that verifies a single, isolated function or method produces the correct output for given inputs. Python provides the built-in unittest module for this purpose.
Why use unit tests?
Example using unittest:
import unittest
def add(a, b):
return a + b
class TestAddFunction(unittest.TestCase):
def test_positive_numbers(self):
self.assertEqual(add(3, 4), 7)
def test_negative_numbers(self):
self.assertEqual(add(-1, -1), -2)
if __name__ == '__main__':
unittest.main()
In this example:
TestAddFunction is a test case class inheriting from unittest.TestCasetest_ is an individual testassertEqual checks that the function returns the expected value| Technique | Type | Requires Code Knowledge? | Uses Computer? |
|---|---|---|---|
| Dry Running | Manual | Yes | No |
| Desk Checking | Manual | Yes | No |
| Black Box Testing | Testing | No | Yes |
| White Box Testing | Testing | Yes | Yes |
| Breakpoints | Debugging Tool | Yes | Yes |
| Watch Window | Debugging Tool | Yes | Yes |
| Unit Tests | Automated Testing | Yes | Yes |