224 come a long way with respect to writing tests. But our thirst is still |
224 come a long way with respect to writing tests. But our thirst is still |
225 unquenched! We want to do more and more tests! Not just write better |
225 unquenched! We want to do more and more tests! Not just write better |
226 code but also better tests! So let us keep building upon what we have |
226 code but also better tests! So let us keep building upon what we have |
227 learnt so far. |
227 learnt so far. |
228 |
228 |
229 Let us start writing tests for more realistic test cases. Generally |
229 Let us start writing tests for more realistic test cases. Generally |
230 tests are predetermined as said above, if not the code itself is |
230 tests are predetermined as said above, if not the software design in |
231 flawed. The predetermined tests are stored along with the test code in |
231 itself is flawed. The predetermined tests are stored along with the |
232 some persistent way like in a database, a text file, a file of |
232 test code in some persistent format like in a database, a text file, a |
233 specific format like XML or in other way. Let us continue with our |
233 file of specific format like XML or in some other way. Let us continue |
234 example of GCD function. We will keep all our test cases in a text |
234 with our example of GCD function. We will keep all our test cases in a |
235 file, which is indeed persistent. Let our file have multiple |
235 text file, which is indeed persistent. Let us specify the format of |
236 lines. Each line in this file corresponds to a single test case. Each |
236 the test data in our file as follows. |
237 line consists of three coloumns: first two coloumns are the integers |
237 |
238 for which the GCD has to be computed and the last coloumn is the |
238 1. The file has multiple lines of test data. |
239 expected GCD to the preceding two numbers. So how do we write our |
239 2. Each line in this file corresponds to a single test case. |
240 tests to use these test cases? Pretty simple, let us review the |
240 3. Each line consists of three comma separated coloumns: |
241 machinery required first. |
241 |
242 |
242 i. First two coloumns are the integers for which the GCD has to |
243 1. File reading: We already have learnt this in our chapters on |
243 be computed |
|
244 ii. Third coloumn is the expected GCD to the preceding two |
|
245 numbers. |
|
246 |
|
247 So how do we write our tests to use these test cases? Pretty simple, let |
|
248 us review the machinery required first. |
|
249 |
|
250 1. File reading: We already have learnt this in the modules on |
244 Basic Python. |
251 Basic Python. |
245 2. Parsing read data from file: This just involves a for loop over |
252 2. Parsing the read data from the file: This just involves a using a |
246 the data since we know that file contains lines which are |
253 **for** loop which iterates over the data line by line since we |
247 equivalent to file records and hence parse the data line by line |
254 know that the file contains each test case as a sepate line which |
248 as strings as we iterate Over it and convert it to required data |
255 are equivalent to the file records and hence parse the data line |
249 type. |
256 by line as strings as we iterate over it and convert it to the |
|
257 required data type. |
250 |
258 |
251 Since we already have all the machinery required, let us proceed writing |
259 Since we already have all the machinery required, let us proceed writing |
252 our test cases. |
260 our test cases. We do not need not make any changes to the gcd |
253 |
261 function so we will just write down the test here. Let us call our |
254 |
262 data file gcd_testcases.dat:: |
255 |
263 |
256 |
264 if __name__ == '__main__': |
257 |
265 for line in open('gcd_testcases.dat'): |
258 %%%%%%%%% Much Later %%%%%%%%%%%%%%%%% |
266 values = line.split(', ') |
259 The idea of placing the tests with in the Python scripts and to |
267 a = int(values[0]) |
260 execute them when the script is run as a stand-alone script works well |
268 b = int(values[1]) |
261 as long as we have our code in a single Python file or the tests for |
269 g = int(values[2]) |
262 each script can be run separately. But in a more realistic software |
270 |
263 development scenario, often this is not the case. The code is spread |
271 tc = gcd(a, b) |
264 around multiple Python scripts, each Python script also being called |
272 if tc != g: |
265 as a Python module, and across several Python packages. In such a |
273 print "Test failed for the case a=%d and b=%d. Expected %d. Obtained %d instead." % (a, b, g, tc) |
266 scenario we may want to do more. |
274 exit(1) |
|
275 |
|
276 print "All tests passed!" |
|
277 |
|
278 When we execute the gcd.py script again we will notice that all the |
|
279 tests passed. |
|
280 |
|
281 Running at the **nose** |
|
282 ======================= |
|
283 |
|
284 Not too far ahead we go we will start running at the nose saying of |
|
285 Python developers saying that this is not sufficient to write |
|
286 complicated tests in an efficient manner and writing tests for the |
|
287 programs are so important that Python should provide a tool for |
|
288 managing large tests. To further explain, the idea of placing the |
|
289 tests with in the Python scripts and to execute them when the script |
|
290 is run as a stand-alone script works well as long as we have our code |
|
291 in a single Python file or as long as the tests for each script can be |
|
292 run separately. But in a more realistic software development scenario, |
|
293 often this is not the case. The code is spread around multiple Python |
|
294 scripts, each script also called as a Python module, and also across |
|
295 several Python packages. |
|
296 |
|
297 In such a scenario what we would like to do is to create a separate |
|
298 directory for holding these test. The structure of this directory is |
|
299 the exact replica of the Python package hierarchy of our software to |
|
300 be tested. This structure is especially useful because of the fact |
|
301 that we have a one to one correspondence to our code and to its test. |
|
302 Hence it is easy for us to navigate through the tests as we maintain |
|
303 the existing tests and to add new tests as the code evolves. We have a |
|
304 collection of tests in the specified structure. Any collection of |
|
305 tests is called as the test suite for the *software package*. Hence we |
|
306 shall call this directory of tests as our test suite. |
|
307 |
|
308 Fine we have all these, but how do we make our tests aware that they |
|
309 are the tests for such and such a Python module or code and when |
|
310 executed must test that corresponding code? To make the lives of |
|
311 Python developers and testers easy Python provides a very handy tool |
|
312 called as **nose**. The name should have been pretty evident from the |
|
313 heading of this section! So in the rest of this module let us discuss |
|
314 how to use **nose** to write, maintain and extend our tests as the |
|
315 code evolves. |