You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: content/python/concepts/unittest-module/unittest-module.md
+148-24
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,6 @@
1
1
---
2
2
Title: 'Unittest Module'
3
-
Description: 'The unittest module provides features for unit testing Python code.'
3
+
Description: 'Python’s unittest module is a built-in testing framework that helps developers create, organize, and run unit tests.'
4
4
Subjects:
5
5
- 'Computer Science'
6
6
- 'Data Science'
@@ -17,13 +17,41 @@ CatalogContent:
17
17
- 'paths/computer-science'
18
18
---
19
19
20
-
The **`unittest`**[module](https://www.codecademy.com/resources/docs/python/modules) provides features for [unit testing](https://www.codecademy.com/resources/docs/general/unit-testing) Python code. Similar to unit testing frameworks in other languages ,`unittest` allows for the following features:
21
-
22
-
- Automation of unit tests.
23
-
- Sharing of setup and tear-down code for tests.
24
-
- Aggregation of tests into collections.
25
-
26
-
## Example
20
+
Python **`unittest`**[module](https://www.codecademy.com/resources/docs/python/modules) is a built-in testing [framework](https://www.codecademy.com/resources/docs/general/framework) that provides a set of tools for testing code's functionality in a more systematic and automated way. It supports creating and running [unit tests](https://www.codecademy.com/resources/docs/general/unit-testing), helping developers catch bugs early and ensure code reliability. Similar to unit testing frameworks in other languages, `unittest` allows for the following features:
21
+
22
+
- Automation of test execution
23
+
- Setup and teardown functionality for preparing and cleaning up before/after tests
24
+
- Grouping of tests into test suites
25
+
26
+
## Commonly Used `unittest` Methods
27
+
28
+
This table lists the most frequently used methods in Python’s `unittest` module. These include assertion methods that check specific conditions in tests, as well as setup and teardown methods that manage test environments:
|`assertNotEqual(a, b)`| Test passes if `a != b`. |
34
+
|`assertTrue(x)`| Test passes if `bool(x) is True`. |
35
+
|`assertFalse(x)`| Test passes if `bool(x) is False`. |
36
+
|`assertIs(a, b)`| Test passes if `a is b` (same object). |
37
+
|`assertIsNot(a, b)`| Test passes if `a is not b`. |
38
+
|`assertIsNone(x)`| Test passes if `x is None`. |
39
+
|`assertIsNotNone(x)`| Test passes if `x is not None`. |
40
+
|`assertIn(a, b)`| Test passes if `a in b`. |
41
+
|`assertNotIn(a, b)`| Test passes if `a not in b`. |
42
+
|`assertIsInstance(a, b)`| Test passes if `a` is an instance of `b`. |
43
+
|`assertNotIsInstance(a, b)`| Test passes if `a` is _not_ an instance of `b`. |
44
+
|`assertGreater(a, b)`| Test passes if `a > b`. |
45
+
|`assertGreaterEqual(a, b)`| Test passes if `a >= b`. |
46
+
|`assertLess(a, b)`| Test passes if `a < b`. |
47
+
|`assertLessEqual(a, b)`| Test passes if `a <= b`. |
48
+
|`assertAlmostEqual(a, b)`| Test passes if `a ≈ b` (to 7 decimal places by default). |
49
+
|`assertNotAlmostEqual(a, b)`| Test passes if `a ≠ b` within tolerance. |
50
+
|`assertRaises(Exception)`| Checks if the specified exception is raised. |
51
+
|`setUp()`| Prepares test environment; runs before each test method. |
52
+
|`tearDown()`| Cleans up after each test method is executed. |
53
+
54
+
## Example 1: Testing a `Rectangle` Class
27
55
28
56
The following example begins with code for a `Rectangle`[class](https://www.codecademy.com/resources/docs/python/classes) that needs to be tested:
29
57
@@ -54,6 +82,8 @@ import unittest
54
82
import rectangle as rect
55
83
56
84
classRectangleTestCase(unittest.TestCase):
85
+
defsetUp(self):
86
+
self.rectangle = rect.Rectangle(5, 10)
57
87
58
88
deftest_area(self):
59
89
self.assertEqual(self.rectangle.area(), 50)
@@ -71,25 +101,24 @@ class RectangleTestCase(unittest.TestCase):
71
101
withself.assertRaises(TypeError):
72
102
a =self.rectangle.perimeter()
73
103
74
-
defsetUp(self):
75
-
self.rectangle = rect.Rectangle(5 ,10)
76
-
77
104
if__name__=='__main__':
78
105
unittest.main()
79
106
```
80
107
81
-
First the `unittest.TestCase` class is subclassed for our test case object. Then tests are defined as methods with names starting with `test`. This naming convention is mandatory as it allows the test runner to find the methods that represent tests.
82
-
83
-
Tests consist of methods containing calls to one or more `assert` methods of the test case object:
108
+
To run the tests, include:
84
109
85
-
-`.assertEqual()`: Test passes when both arguments are equal.
86
-
-`.assertTrue()` : Test passes when argument is `True`.
87
-
-`.assertFalse()` : Test passes when argument is `False`.
88
-
-`.assertRaises()` : Test passes when the passed exception is raised.
110
+
```py
111
+
if__name__=='__main__':
112
+
unittest.main()
113
+
```
89
114
90
-
The test case can have `.setUp()` and `.tearDown()` methods defined. The `.setUp()` method is for any initialization needed for the test, and will run before each `test`method is carried out. The `.tearDown()` method is run after each `test` method to do any needed cleanup after each test.
115
+
The `unittest.TestCase` class is subclassed to define a test case object. Each test method must start with the word `test`so the test runner can detect and execute it. A breakdown of all the tests will be as follows:
91
116
92
-
The call to `unittest.main()` runs the tests and provides the test script with a command-line interface.
117
+
-`setup()`: Initializes a `Rectangle` object before each test method runs.
118
+
-`test_area()`: Verifies that the area calculation is correct (`5 * 10 = 50`).
-`test_isSquare()`: Asserts that a rectangle with unequal sides is not a square, and that changing width to equal height makes it a square.
121
+
-`test_error()`: Ensures a `TypeError` is raised when width is set to a non-numeric value.
93
122
94
123
Running the above produces the following:
95
124
@@ -100,7 +129,7 @@ $ python test.py
100
129
Ran 4 tests in 0.001s
101
130
```
102
131
103
-
The output shows a dot printed for each successful test.
132
+
Each dot (`.`) represents a passing test.
104
133
105
134
Using the `-v` option on the command line will produce a more verbose test:
106
135
@@ -117,6 +146,101 @@ Ran 4 tests in 0.001s
117
146
118
147
The output shows the following:
119
148
120
-
- The method name for each test.
121
-
- The test case class the method belongs to.
122
-
- A message telling whether or the test was passed.
149
+
- Each test method's name
150
+
- Its test case class
151
+
- A result message indicating whether it passed
152
+
153
+
## Example 2: Testing a `BankAccount` Class
154
+
155
+
This example demonstrates how to write unit tests for a basic bank account class, covering deposit, withdrawal, and balance operations.
156
+
157
+
```py
158
+
# bank_account.py
159
+
160
+
classBankAccount:
161
+
def__init__(self, owner, balance=0):
162
+
self.owner = owner
163
+
self.balance = balance
164
+
165
+
defdeposit(self, amount):
166
+
if amount <0:
167
+
raiseValueError("Deposit amount must be positive.")
168
+
self.balance += amount
169
+
returnself.balance
170
+
171
+
defwithdraw(self, amount):
172
+
if amount >self.balance:
173
+
raiseValueError("Insufficient funds.")
174
+
self.balance -= amount
175
+
returnself.balance
176
+
177
+
defget_balance(self):
178
+
returnself.balance
179
+
```
180
+
181
+
Writing the unit tests for this:
182
+
183
+
```py
184
+
# test_bank_account.py
185
+
186
+
import unittest
187
+
from bank_account import BankAccount
188
+
189
+
classBankAccountTestCase(unittest.TestCase):
190
+
191
+
defsetUp(self):
192
+
self.account = BankAccount("Alice", 100)
193
+
194
+
deftest_deposit(self):
195
+
self.assertEqual(self.account.deposit(50), 150)
196
+
197
+
deftest_withdraw(self):
198
+
self.assertEqual(self.account.withdraw(30), 70)
199
+
200
+
deftest_withdraw_insufficient_funds(self):
201
+
withself.assertRaises(ValueError):
202
+
self.account.withdraw(200)
203
+
204
+
deftest_deposit_negative_amount(self):
205
+
withself.assertRaises(ValueError):
206
+
self.account.deposit(-20)
207
+
208
+
deftest_get_balance(self):
209
+
self.assertEqual(self.account.get_balance(), 100)
210
+
211
+
if__name__=='__main__':
212
+
unittest.main()
213
+
```
214
+
215
+
In the test cases:
216
+
217
+
-`setUp()`: Creates an account with `owner='Alice'` and initial balance of `100`.
218
+
-`test_deposit()`: Tests depositing a valid amount (`50`) updates the balance to `150`.
219
+
-`test_withdraw()`: Tests withdrawing `30` correctly reduces the balance to `70`.
220
+
-`test_withdraw_insufficient_funds()`: Ensures withdrawing more than available (`200`) raises a `ValueError`.
221
+
-`test_deposit_negative_amount()`: Ensures depositing a negative amount raises a `ValueError`.
222
+
-`test_get_balance()`: Verifies the balance remains unchanged initially (`100`).
223
+
224
+
## Best Practices for Using `unittest` Module
225
+
226
+
- Use `setUp()` for repeated setup code instead of duplicating it in each test.
227
+
- Name test methods clearly to describe what’s being tested.
228
+
- Keep tests isolated—each test should not depend on another.
229
+
- Avoid testing multiple concerns in one test method.
230
+
- Run tests frequently during development, not just before deployment.
231
+
- Use descriptive assertion messages (e.g., `self.assertEqual(a, b, "Area calculation failed")`) for easier debugging.
232
+
233
+
## Frequently Asked Questions
234
+
235
+
### 1. Which is better, `pytest` or `unittest`?
236
+
237
+
`unittest` is built into Python and follows an object-oriented approach. It is ideal for small to medium-sized projects.
238
+
`pytest` is a third-party framework that offers more concise syntax, better error messages, and additional plugins, making it a popular choice for larger projects.
239
+
240
+
### 2. What does `unittest.main()` do?
241
+
242
+
`unit test.main()` launches the test runner, which automatically discovers and executes all test methods in the file. It also provides a command-line interface to control test behavior (e.g., verbosity).
243
+
244
+
### 3. What does `if __name__ == '__main__'` mean in Python?
245
+
246
+
This statement ensures that the code inside runs only when the script is executed directly, not when it’s imported as a module. It's commonly used to run test scripts or demo code.
0 commit comments