test person with datetime
The person project has a problem with the calculation of the ages. It only shows the right age if the program is run in 2026, because the year is hardcoded. If I run it in a different year or change the year on my computer, the tests for say_hello will fail.
I want the calculation to always be right, which means the program should always know the correct year.
I can do that with the datetime module from The Python Standard Library. You can think of it as a toolbox with different tools I can use to do things with dates and times.
preview
I have these tests by the end of the chapter
1import datetime
2import src.person
3import unittest
4
5
6class TestPerson(unittest.TestCase):
7
8 @staticmethod
9 def calculate_age(year_of_birth):
10 return (
11 datetime.datetime.now().year
12 - year_of_birth
13 )
14
15 def test_joe(self):
16 first_name = 'joe'
17 last_name = 'blow'
18 sex = 'M'
19 year_of_birth = 1996
20
21 reality = src.person.factory(
22 first_name=first_name,
23 last_name=last_name,
24 sex=sex,
25 year_of_birth=year_of_birth,
26 )
27 my_expectation = (
28 f'{first_name}, {last_name},'
29 f' {sex}, {year_of_birth}'
30 )
31 assert reality == my_expectation
32 self.assertEqual(reality, my_expectation)
33
34 reality = src.person.say_hello(
35 first_name=first_name,
36 last_name=last_name,
37 year_of_birth=year_of_birth,
38 )
39 my_expectation = (
40 f'Hello, my name is {first_name}'
41 f' {last_name} and I am'
42 f' {self.calculate_age(year_of_birth)}.'
43 )
44 assert reality == my_expectation
45 self.assertEqual(reality, my_expectation)
46
47 joe = src.person.Person(
48 first_name=first_name,
49 last_name=last_name,
50 sex=sex,
51 year_of_birth=year_of_birth,
52 )
53
54 reality = joe.say_hello()
55 assert reality == my_expectation
56 self.assertEqual(reality, my_expectation)
57
58 def test_jane(self):
59 first_name = 'jane'
60 last_name = 'doe'
61 sex = 'F'
62 year_of_birth = 1991
63
64 reality = src.person.factory(
65 first_name=first_name,
66 last_name=last_name,
67 sex=sex,
68 year_of_birth=year_of_birth,
69 )
70 my_expectation = (
71 f'{first_name}, {last_name},'
72 f' {self.calculate_age(year_of_birth)}.'
73 )
74 assert reality == my_expectation
75 self.assertEqual(reality, my_expectation)
76
77 reality = src.person.say_hello(
78 first_name=first_name,
79 last_name=last_name,
80 year_of_birth=year_of_birth,
81 )
82 my_expectation = (
83 f'Hello, my name is {first_name}'
84 f' {last_name} and I am'
85 f' {self.calculate_age(year_of_birth)}.'
86 )
87 assert reality == my_expectation
88 self.assertEqual(reality, my_expectation)
89
90 jane = src.person.Person(
91 first_name=first_name,
92 last_name=last_name,
93 sex=sex,
94 year_of_birth=year_of_birth,
95 )
96
97 reality = jane.say_hello()
98 assert reality == my_expectation
99 self.assertEqual(reality, my_expectation)
100
101 def test_john(self):
102 first_name = 'john'
103 last_name = 'smith'
104 sex = 'M'
105 year_of_birth = 1580
106
107 reality = src.person.factory(
108 first_name=first_name,
109 last_name=last_name,
110 sex=sex,
111 year_of_birth=year_of_birth,
112 )
113 my_expectation = (
114 f'{first_name}, {last_name},'
115 f' {sex}, {year_of_birth}'
116 )
117 assert reality == my_expectation
118 self.assertEqual(reality, my_expectation)
119
120 reality = src.person.say_hello(
121 first_name=first_name,
122 last_name=last_name,
123 year_of_birth=year_of_birth,
124 )
125 my_expectation = (
126 f'Hello, my name is {first_name}'
127 f' {last_name} and I am'
128 f' {self.calculate_age(year_of_birth)}.'
129 )
130 assert reality == my_expectation
131 self.assertEqual(reality, my_expectation)
132
133 john = src.person.Person(
134 first_name=first_name,
135 last_name=last_name,
136 sex=sex,
137 year_of_birth=year_of_birth,
138 )
139
140 reality = john.say_hello()
141 assert reality == my_expectation
142 self.assertEqual(reality, my_expectation)
143
144 def test_mary(self):
145 first_name = 'mary'
146 last_name = 'public'
147 sex = 'F'
148 year_of_birth = 2000
149
150 reality = src.person.factory(
151 first_name=first_name,
152 last_name=last_name,
153 sex=sex,
154 year_of_birth=year_of_birth,
155 )
156 my_expectation = (
157 f'{first_name}, {last_name},'
158 f' {sex}, {year_of_birth}'
159 )
160 assert reality == my_expectation
161 self.assertEqual(reality, my_expectation)
162
163 reality = src.person.say_hello(
164 first_name=first_name,
165 last_name=last_name,
166 year_of_birth=year_of_birth,
167 )
168 my_expectation = (
169 f'Hello, my name is {first_name}'
170 f' {last_name} and I am'
171 f' {self.calculate_age(year_of_birth)}.'
172 )
173 assert reality == my_expectation
174 self.assertEqual(reality, my_expectation)
175
176 mary = src.person.Person(
177 first_name=first_name,
178 last_name=last_name,
179 sex=sex,
180 year_of_birth=year_of_birth,
181 )
182
183 reality = mary.say_hello()
184 assert reality == my_expectation
185 self.assertEqual(reality, my_expectation)
186
187 def test_person_when_year_of_birth_is_none(self):
188 # raises AssertionError
189 # an_instance_of_person = src.person.Person(
190 # first_name='first_name',
191 # last_name='last_name',
192 # sex='M',
193 # )
194
195 def test_dir_person_class(self):
196 reality = dir(src.person.Person)
197 my_expectation = [
198 '__class__',
199 '__delattr__',
200 '__dict__',
201 '__dir__',
202 '__doc__',
203 '__eq__',
204 '__firstlineno__',
205 '__format__',
206 '__ge__',
207 '__getattribute__',
208 '__getstate__',
209 '__gt__',
210 '__hash__',
211 '__init__',
212 '__init_subclass__',
213 '__le__',
214 '__lt__',
215 '__module__',
216 '__ne__',
217 '__new__',
218 '__reduce__',
219 '__reduce_ex__',
220 '__repr__',
221 '__setattr__',
222 '__sizeof__',
223 '__static_attributes__',
224 '__str__',
225 '__subclasshook__',
226 '__weakref__',
227 'say_hello'
228 ]
229 assert reality == my_expectation
230 self.assertEqual(reality, my_expectation)
231
232 def test_dir_person_instance(self):
233 an_instance_of_person = src.person.Person(
234 first_name='first_name',
235 last_name='last_name',
236 sex='M',
237 year_of_birth=2026,
238 )
239
240 reality = dir(an_instance_of_person)
241 my_expectation = [
242 '__class__',
243 '__delattr__',
244 '__dict__',
245 '__dir__',
246 '__doc__',
247 '__eq__',
248 '__firstlineno__',
249 '__format__',
250 '__ge__',
251 '__getattribute__',
252 '__getstate__',
253 '__gt__',
254 '__hash__',
255 '__init__',
256 '__init_subclass__',
257 '__le__',
258 '__lt__',
259 '__module__',
260 '__ne__',
261 '__new__',
262 '__reduce__',
263 '__reduce_ex__',
264 '__repr__',
265 '__setattr__',
266 '__sizeof__',
267 '__static_attributes__',
268 '__str__',
269 '__subclasshook__',
270 '__weakref__',
271 'first_name',
272 'last_name',
273 'say_hello',
274 'sex',
275 'year_of_birth',
276 ]
277 assert reality == my_expectation
278 self.assertEqual(reality, my_expectation)
279
280
281# Exceptions seen
282# AssertionError
283# NameError
284# TypeError
285# AttributeError
286# SyntaxError
open the project
I open a terminal
I change directory to the project
cd personI open
test_person.pyfrom thetestsfolderI use pytest-watcher to run the tests automatically
uv run pytest-watcher . --nowthe terminal shows
tests/test_person.py ...... [100%] =================== 6 passed in A.BCs ====================
close the project
I close
test_person.pyI click in the terminal where the tests are running
I use q on the keyboard to leave the tests. The terminal goes back to the command line.
I change directory to the parent of
personcd ..the terminal shows
...\pumping_pythonI am back in the
pumping_pythondirectory.
review
I can use the unittest library to write tests with the methods of the unittest.TestCase class or I can write them with bare assert statements.
My tests for a person still have the problem where they are the same three tests. There has to be a way that I can use one test for all the people.
code from the chapter
Do you want to see all the CODE I typed in this chapter?
what is next?
You know
rate pumping python
If this has been a 7 star experience for you, please CLICK HERE to leave a 5 star review of pumping python. It helps other people get into the book too.