54 doctest.testmod() function and using nosetests command. |
54 doctest.testmod() function and using nosetests command. |
55 |
55 |
56 Lab - 4 |
56 Lab - 4 |
57 ======= |
57 ======= |
58 |
58 |
59 1. |
59 1. Consider the following use case: We are given a large list of |
|
60 items called *data* where each item is a again a list with three |
|
61 values: username, which is a string; status of the user which |
|
62 can be one of the following three strings 'new', 'valid' or |
|
63 'invalid'; and the last login time which is a datetime Python |
|
64 object. Write a function called **query** that takes a filter |
|
65 dictionary as a parameter and returns the result of the items in |
|
66 the *data* list. They keys of the dictionary can be 'user', |
|
67 'status' and 'logtime' and their corresponding values can be any |
|
68 of the valid values for the corresponding key. Example filter |
|
69 dictionary:: |
|
70 |
|
71 filter = { |
|
72 'user': 'john' |
|
73 'status': 'new' |
|
74 } |
|
75 |
|
76 Place your function in a file called query.py. Before writing the |
|
77 actual function, follow the test driven development |
|
78 approach. First write a stub, fail the tests and then write the |
|
79 code and make sure the tests pass. Specifically use unittest |
|
80 framework to test this function. Place your tests in a file |
|
81 called test_query.py |
|
82 |
|
83 A developer wrote a small utility function in a file named |
|
84 user_utils.py which uses your **query** function which looks as |
|
85 follows:: |
|
86 |
|
87 def login_util(user=None): |
|
88 """Takes a user name and returns his last login time if the |
|
89 user is a valid user, else return None. If the user is |
|
90 'host' it returns the last login time of all the users. |
|
91 """ |
|
92 |
|
93 filter_dict = { |
|
94 'user': user |
|
95 'status': 'active' |
|
96 } |
|
97 |
|
98 if user == 'host': |
|
99 filter_dict['status'] + ['new', 'invalid'] |
|
100 |
|
101 return query(filter_dict) |
|
102 |
|
103 Unfortunately the developer did not provide us with the test |
|
104 cases. We wrote the following test cases for you to only discover |
|
105 that the function miserably fails. |
|
106 |
|
107 The tests were placed in a file called test_user_utils.py and we |
|
108 have used the unittest framework:: |
|
109 |
|
110 import query |
|
111 import user_utils |
|
112 import unittest |
|
113 |
|
114 class TestUserUtils(unittest.TestCase): |
|
115 |
|
116 def setUp(self): |
|
117 """Boiler plate method to provide common data to all |
|
118 the test methods. |
|
119 """ |
|
120 self.test_names = ['Alex', 'Guido', 'Thomas', 'host', |
|
121 'Tom', 'James'] |
|
122 self.data_len = len(query.data) |
|
123 |
|
124 def test_login_utils(self): |
|
125 """Tests for the login_utils function. |
|
126 """ |
|
127 |
|
128 for name in self.test_names: |
|
129 if name == 'host': |
|
130 assertEqual(len(user_utils.login_utils(name)), self.data_len) |
|
131 else: |
|
132 assertLess(len(user_utils.login_utils(name)), self.data_len) |
|
133 |
|
134 def tearDown(self): |
|
135 """Boiler plate method to clean up all the data created |
|
136 for tests. |
|
137 """ |
|
138 |
|
139 del self.test_names |
|
140 del self.data_len |
|
141 |
|
142 Fix the bug, run the tests to make sure the function passes the |
|
143 tests and if possible refactor the code with a better approach. |