Unit Testing is a software testing method where individual components or "units" of a software are tested independently to ensure they work as expected. The main goal is to validate that each piece of the software (usually a function or method) performs its task correctly. Unit testing helps in catching bugs early in the development cycle and ensures that the codebase remains maintainable and reliable.
Imagine a calculator application where you want to test the addition function. In unit testing, you'd isolate that function and verify whether it correctly returns the sum of two numbers.
- Manual Unit Testing: Manually executing test cases to check the functionality of a unit.
- Automated Unit Testing: Writing scripts to automatically test the functionality of a unit using frameworks (e.g., JUnit, pytest).
Unit testing can be performed using various techniques to cover different parts of the code:
These focus on testing the internal structure and control flow of a unit.
Definition: Ensures that every line of code is executed at least once.
def is_even(number):
if number % 2 == 0:
return True
else:
return False
- Test Case
1
:is_even(4)
should return True. - Test Case
2
:is_even(3)
should return False.
Definition: Tests every condition (e.g., boolean expressions) to ensure that both true and false outcomes are covered.
def check_positive_even(number):
if number > 0 and number % 2 == 0:
return True
else:
return False
- Test Case
1
:check_positive_even(4)
should return True. - Test Case
2
:check_positive_even(-4)
should return False. - Test Case
3
:check_positive_even(3)
should return False.
Definition: Tests all possible branches in conditional statements.
def calculate_grade(score):
if score >= 90:
return 'A'
elif score >= 80:
return 'B'
else:
return 'C'
- Test Case
1
:calculate_grade(92)
should return 'A'. - Test Case
2
:calculate_grade(85)
should return 'B'. - Test Case
3
:calculate_grade(75)
should return 'C'.
Definition: Tests all possible execution paths in a function.
def operation(a, b, op):
if op == "add":
return a + b
elif op == "subtract":
return a - b
else:
return None
- Test Case
1
:operation(2, 3, 'add')
should return5
. - Test Case
2
:operation(5, 2, 'subtract')
should return3
. - Test Case
3
:operation(5, 2, 'multiply')
should returnNone
.
Unit testing is conducted using different testing methods. These focus on how the internal logic is verified.
Tests internal logic, code structure, and behavior.
Example:
Testing a sorting algorithm by verifying each condition and loop.
Tests the unit based on inputs and expected outputs without knowing the code structure.
Example:
Testing an addition function by providing inputs and checking if the output is correct.
Combines aspects of both white box and black box testing.
Example:
Testing a web service by knowing partial implementation but primarily testing inputs/outputs.
Consider a banking application where you have a function that calculates the interest on a savings account:
def calculate_interest(balance, rate):
return balance * rate
- Test Case
1
: If the balance is$1000
and the rate is0.05
,calculate_interest(1000, 0.05)
should return50
. - Test Case
2
: For a balance of0
,calculate_interest(0, 0.05)
should return0
. - Test Case
3
: For a negative balance,calculate_interest(-100, 0.05)
should return-5
.
def test_calculate_interest():
assert calculate_interest(1000, 0.05) == 50
assert calculate_interest(0, 0.05) == 0
assert calculate_interest(-100, 0.05) == -5
Unit testing is a foundational practice that helps ensure individual components work properly before integrating them into larger systems. Techniques like statement, condition, branch, and path testing, along with methods such as white box and black box testing, enable developers to maintain a reliable codebase.