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 person
    
  • I open test_person.py from the tests folder

  • I use pytest-watcher to run the tests automatically

    uv run pytest-watcher . --now
    

    the terminal shows

    tests/test_person.py ......                         [100%]
    
    =================== 6 passed in A.BCs ====================
    

close the project

  • I close test_person.py

  • I 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 person

    cd ..
    

    the terminal shows

    ...\pumping_python
    

    I am back in the pumping_python directory.


review


code from the chapter

Do you want to see all the CODE I typed in this chapter?


what is next?

You know

Would you like to test None (the simplest object)?


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.