280 print "All tests passed!" |
302 print "All tests passed!" |
281 |
303 |
282 When we execute the gcd.py script again we will notice that all the |
304 When we execute the gcd.py script again we will notice that all the |
283 tests passed. |
305 tests passed. |
284 |
306 |
285 Running at the **nose** |
307 Python Testing Framework |
286 ======================= |
308 ======================== |
287 |
309 |
288 Not too far ahead we go we will start running at the nose saying of |
310 Python provides two ways to test the code we have written. One of them |
289 Python developers saying that this is not sufficient to write |
311 is the unittest framework and the the other is the doctest module. |
290 complicated tests in an efficient manner and writing tests for the |
312 |
291 programs are so important that Python should provide a tool for |
313 doctest |
292 managing large tests. To further explain, the idea of placing the |
314 ~~~~~~~ |
293 tests with in the Python scripts and to execute them when the script |
315 |
294 is run as a stand-alone script works well as long as we have our code |
316 To start with let us discuss the doctest module. As we have already |
295 in a single Python file or as long as the tests for each script can be |
317 discussed a well written piece of code must always be accompanied by |
296 run separately. But in a more realistic software development scenario, |
318 its documentation. For a function or a module we document them in their |
|
319 respective docstrings. In addition to this, we can also place the |
|
320 samples of using these functions or modules in the Python interactive |
|
321 interpreter in the docstrings. When we run the doctest module it picks |
|
322 up all such interactive session samples, executes them and determines |
|
323 if the documented piece of code runs as it is documented. Let us see |
|
324 how to write doctests for our gcd function:: |
|
325 |
|
326 def gcd(a, b): |
|
327 """Returns the Greatest Common Divisor of the two integers |
|
328 passed as arguments. |
|
329 |
|
330 Args: |
|
331 a: an integer |
|
332 b: another integer |
|
333 |
|
334 Returns: Greatest Common Divisor of a and b |
|
335 |
|
336 >>> gcd(48, 64) |
|
337 16 |
|
338 >>> gcd(44, 19) |
|
339 1 |
|
340 """ |
|
341 if b == 0: |
|
342 return a |
|
343 return gcd(b, a%b) |
|
344 |
|
345 This is all a doctest is. To explain it in more simple terms tests |
|
346 which are written as part of the docstrings are called as |
|
347 doctests. Now how do we use our doctest module to execute this |
|
348 tests. That is fairly straight forward as well. All we need to do is |
|
349 tell the doctest module to execute. Let us place this piece of code at |
|
350 the same place where we placed our tests earlier. So putting all these |
|
351 together we have our gcd.py module which looks as follows:: |
|
352 |
|
353 def gcd(a, b): |
|
354 """Returns the Greatest Common Divisor of the two integers |
|
355 passed as arguments. |
|
356 |
|
357 Args: |
|
358 a: an integer |
|
359 b: another integer |
|
360 |
|
361 Returns: Greatest Common Divisor of a and b |
|
362 |
|
363 >>> gcd(48, 64) |
|
364 16 |
|
365 >>> gcd(44, 19) |
|
366 1 |
|
367 """ |
|
368 if b == 0: |
|
369 return a |
|
370 return gcd(b, a%b) |
|
371 |
|
372 if __name__ == "__main__": |
|
373 import doctest |
|
374 doctest.testmod() |
|
375 |
|
376 All we need to do is import the doctest module that is part of the |
|
377 Python's standard library. Call the testmod() function in this |
|
378 module. This function automatically checks for all the docstrings that |
|
379 have sample sessions from the interactive interpreter, if they exist |
|
380 it executes them and compares the output with the results as specified |
|
381 in the sample sessions. It complains if the results don't match as |
|
382 documented. When we execute this script as a stand-alone script we |
|
383 will get back the prompt with no messages which means all the tests |
|
384 passed:: |
|
385 |
|
386 madhu@madhu:~$ python gcd.py |
|
387 madhu@madhu:~$ |
|
388 |
|
389 If we further want to get a more detailed report of the tests that |
|
390 were executed we can run python with -v as the command line option |
|
391 to the script:: |
|
392 |
|
393 madhu@madhu:~$ python gcd.py -v |
|
394 Trying: |
|
395 gcd(48, 64) |
|
396 Expecting: |
|
397 16 |
|
398 ok |
|
399 Trying: |
|
400 gcd(44, 19) |
|
401 Expecting: |
|
402 1 |
|
403 ok |
|
404 1 items had no tests: |
|
405 __main__ |
|
406 1 items passed all tests: |
|
407 2 tests in __main__.gcd |
|
408 2 tests in 2 items. |
|
409 2 passed and 0 failed. |
|
410 Test passed. |
|
411 |
|
412 |
|
413 **Note:** We can have the sample sessions as test cases as long as the |
|
414 outputs of the test cases do not contain any blank lines. In such |
|
415 cases we may have to use the exact string *<BLANKLINE>* |
|
416 |
|
417 For the sake of illustrating a failing test case, let us assume that |
|
418 we made a small mistake in our code. Instead of returning **a** when b |
|
419 = 0 we typed it as return b when b = 0. So all the gcds returned will |
|
420 have the value of 0 in such a piece of code. The code looks as |
|
421 follows:: |
|
422 |
|
423 def gcd(a, b): |
|
424 """Returns the Greatest Common Divisor of the two integers |
|
425 passed as arguments. |
|
426 |
|
427 Args: |
|
428 a: an integer |
|
429 b: another integer |
|
430 |
|
431 Returns: Greatest Common Divisor of a and b |
|
432 |
|
433 >>> gcd(48, 64) |
|
434 16 |
|
435 >>> gcd(44, 19) |
|
436 1 |
|
437 """ |
|
438 if b == 0: |
|
439 return a |
|
440 return gcd(b, a%b) |
|
441 |
|
442 Executing this code snippet without -v option to the script:: |
|
443 |
|
444 madhu@madhu:~$ python gcd.py |
|
445 ********************************************************************** |
|
446 File "gcd.py", line 11, in __main__.gcd |
|
447 Failed example: |
|
448 gcd(48, 64) |
|
449 Expected: |
|
450 16 |
|
451 Got: |
|
452 0 |
|
453 ********************************************************************** |
|
454 File "gcd.py", line 13, in __main__.gcd |
|
455 Failed example: |
|
456 gcd(44, 19) |
|
457 Expected: |
|
458 1 |
|
459 Got: |
|
460 0 |
|
461 ********************************************************************** |
|
462 1 items had failures: |
|
463 2 of 2 in __main__.gcd |
|
464 ***Test Failed*** 2 failures. |
|
465 |
|
466 The output clearly complains that there were exactly two test cases |
|
467 that failed. If we want a more verbose report we can pass -v option to |
|
468 the script. This is pretty much about the doctest module in |
|
469 Python. doctest is extremely useful when we want to test each Python |
|
470 function or module individually. For more information about the |
|
471 doctest module refer to the Python library reference on doctest[0]. |
|
472 |
|
473 unittest framework |
|
474 ~~~~~~~~~~~~~~~~~~ |
|
475 |
|
476 Not too far ahead we go we, we will start complaining that the doctest |
|
477 is not sufficient to write complicated tests especially when we want |
|
478 to automate our tests, write tests that need to test for more |
|
479 convoluted code pieces. For such scenarios Python provides a unittest |
|
480 framework. unittest framework provides methods to efficiently |
|
481 automate tests, setup and teardown functionalities which helps to |
|
482 setup the initializing code and data for executing the specific tests |
|
483 and cleanly shutting them down once the tests are executed and ways to |
|
484 aggregate tests into collections and better way of reporting the |
|
485 tests. |
|
486 |
|
487 Let us continue testing our gcd function in the Python module named |
|
488 gcd.py. To get ourselves started, the unittest framework expects us to |
|
489 subclass TestCase class in unittest module and place all our test code |
|
490 as methods of this class. We will begin the name of the test method |
|
491 with **test_** so that the test runner knows which methods are to be |
|
492 executed as tests. We will use the test cases supplied by |
|
493 gcd_testcases.dat. Lastly, to illustrate the way to test Python code |
|
494 as a module let create a new file called test_gcd.py following the |
|
495 same convention used to name the test methods. We will place our test |
|
496 code within test_gcd.py module. Our test code looks like this:: |
|
497 |
|
498 import gcd |
|
499 import unittest |
|
500 |
|
501 class TestGcdFunction(unittest.TestCase): |
|
502 |
|
503 def setUp(self): |
|
504 self.test_file = open('gcd_testcases.dat') |
|
505 self.test_cases = [] |
|
506 for line in self.test_file: |
|
507 values = line.split(', ') |
|
508 a = int(values[0]) |
|
509 b = int(values[1]) |
|
510 g = int(values[2]) |
|
511 |
|
512 self.test_cases.append([a, b, g]) |
|
513 |
|
514 def test_gcd(self): |
|
515 for case in self.test_cases: |
|
516 a = case[0] |
|
517 b = case[1] |
|
518 g = case[2] |
|
519 self.assertEqual(gcd.gcd(a, b), g) |
|
520 |
|
521 def tearDown(self): |
|
522 self.test_file.close() |
|
523 del self.test_cases |
|
524 |
|
525 if __name__ == '__main__': |
|
526 unittest.main() |
|
527 |
|
528 |
|
529 |
|
530 Since we don't want to read this file into memory each time we run a |
|
531 separate test method, we will read all the data in the file into |
|
532 Python lists in the setUp function and in the tearDown function of the |
|
533 |
|
534 |
|
535 |
|
536 |
|
537 To further explain the idea, the idea of placing tests with in the |
|
538 Python scripts and to execute them when the script is run as a |
|
539 stand-alone script works well as long as we have our code in a single |
|
540 Python file or as long as the tests for each script can be run |
|
541 separately. But in a more realistic software development scenario, |
297 often this is not the case. The code is spread around multiple Python |
542 often this is not the case. The code is spread around multiple Python |
298 scripts, each script also called as a Python module, and also across |
543 scripts, each script, also called as a Python module, and may be even |
299 several Python packages. |
544 across several Python packages. |
300 |
545 |
301 In such a scenario what we would like to do is to create a separate |
546 In such a scenario what we would like to do is to create a separate |
302 directory for holding these test. The structure of this directory is |
547 directory for holding these test. The structure of this directory is |
303 the exact replica of the Python package hierarchy of our software to |
548 the exact replica of the Python package hierarchy of our software to |
304 be tested. This structure is especially useful because of the fact |
549 be tested. This structure is especially useful because of the fact |