Beginning Python - From Novice to Professional
Beginning Python - From Novice to Professional Beginning Python - From Novice to Professional
CHAPTER 16 ■ TESTING, 1-2-3 345 def square(x): ''' Squares a number and returns the result. >>> square(2) 4 >>> square(3) 9 ''' return x*x As you can see, I’ve included some text in the docstring, too. What does this have to do with testing? Let’s say the square function is defined in the module my_math (that is, a file called my_math.py). Then you could add the following code at the bottom: if __name__=='__main__': import doctest, my_math doctest.testmod(my_math) That’s not a lot, is it? You simply import doctest and the my_math module itself, and then run the testmod (for “test module”) function from doctest. What does this do? Let’s try it: $ python my_math.py $ Nothing seems to have happened, but that’s a good thing. The doctest.testmod function reads all the docstrings of a module and seeks out any text that looks like an example from the interactive interpreter; then it checks whether the example represents reality. ■Note If I were writing a real function here, I would (or should, according to the rules I laid down earlier) first write the docstring, run the script with doctest to see the test fail, add a dummy version (for example using if-statements to deal with the specific inputs in the docstring) so that the test succeeds, and then start working on getting the implementation right. On the other hand, if you’re going to do full-out “test-first, codelater” programming, the unittest framework (discussed later) might suit your needs better. To get some more input, you can just give the –v switch (for verbose) to your script: $ python my_math.py -v This command would result in the following output: Running my_math.__doc__ 0 of 0 examples failed in my_math.__doc__ Running my_math.square.__doc__ Trying: square(2) Expecting: 4 ok
346 CHAPTER 16 ■ TESTING, 1-2-3 Trying: square(3) Expecting: 9 ok 0 of 2 examples failed in my_math.square.__doc__ 1 items had no tests: test 1 items passed all tests: 2 tests in my_math.square 2 tests in 2 items. 2 passed and 0 failed. Test passed. As you can see, a lot happened behind the scenes. The testmod function checks both the module docstring (which, as you can see, contains no tests) and the function docstring (which contains two tests, both of which succeed). With this in place, you can safely change your code. Let’s say that you want to use the Python exponentiation operator instead of plain multiplication, and use x**2 instead of x*x. You edit the code, but accidentally forget to enter the number 2, and end up with x**x. Try it, and then run the script to test the code. What happens? This is the output you get: ***************************************************************** Failure in example: square(3) from line #5 of my_math.square Expected: 9 Got: 27 ***************************************************************** 1 items had failures: 1 of 2 in my_math.square ***Test Failed*** 1 failures. So the bug was caught, and you get a very clear description of what is wrong. Fixing the problem shouldn’t be difficult now. ■Caution Don’t trust your tests blindly, and be sure to test enough cases. As you can see, the test using square(2) does not catch the bug because for x==2, x**2 and x**x are the same thing! For more information about the doctest module, you should again check out the library reference (http://python.org/doc/lib/module-doctest.html).
- Page 326: CHAPTER 13 ■ DATABASE SUPPORT 295
- Page 329 and 330: 298 CHAPTER 14 ■ NETWORK PROGRAMM
- Page 331 and 332: 300 CHAPTER 14 ■ NETWORK PROGRAMM
- Page 333 and 334: 302 CHAPTER 14 ■ NETWORK PROGRAMM
- Page 335 and 336: 304 CHAPTER 14 ■ NETWORK PROGRAMM
- Page 337 and 338: 306 CHAPTER 14 ■ NETWORK PROGRAMM
- Page 339 and 340: 308 CHAPTER 14 ■ NETWORK PROGRAMM
- Page 341 and 342: 310 CHAPTER 14 ■ NETWORK PROGRAMM
- Page 343 and 344: 312 CHAPTER 14 ■ NETWORK PROGRAMM
- Page 345 and 346: 314 CHAPTER 15 ■ PYTHON AND THE W
- Page 347 and 348: 316 CHAPTER 15 ■ PYTHON AND THE W
- Page 349 and 350: 318 CHAPTER 15 ■ PYTHON AND THE W
- Page 351 and 352: 320 CHAPTER 15 ■ PYTHON AND THE W
- Page 353 and 354: 322 CHAPTER 15 ■ PYTHON AND THE W
- Page 355 and 356: 324 CHAPTER 15 ■ PYTHON AND THE W
- Page 357 and 358: 326 CHAPTER 15 ■ PYTHON AND THE W
- Page 359 and 360: 328 CHAPTER 15 ■ PYTHON AND THE W
- Page 361 and 362: 330 CHAPTER 15 ■ PYTHON AND THE W
- Page 363 and 364: 332 CHAPTER 15 ■ PYTHON AND THE W
- Page 365 and 366: 334 CHAPTER 15 ■ PYTHON AND THE W
- Page 367 and 368: 336 CHAPTER 15 ■ PYTHON AND THE W
- Page 369 and 370: 338 CHAPTER 15 ■ PYTHON AND THE W
- Page 372 and 373: CHAPTER 16 ■ ■ ■ Testing, 1-2
- Page 374 and 375: CHAPTER 16 ■ TESTING, 1-2-3 343 W
- Page 378 and 379: CHAPTER 16 ■ TESTING, 1-2-3 347 u
- Page 380 and 381: CHAPTER 16 ■ TESTING, 1-2-3 349 F
- Page 382 and 383: CHAPTER 16 ■ TESTING, 1-2-3 351 P
- Page 384 and 385: CHAPTER 16 ■ TESTING, 1-2-3 353 "
- Page 386: CHAPTER 16 ■ TESTING, 1-2-3 355 N
- Page 389 and 390: 358 CHAPTER 17 ■ EXTENDING PYTHON
- Page 391 and 392: 360 CHAPTER 17 ■ EXTENDING PYTHON
- Page 393 and 394: 362 CHAPTER 17 ■ EXTENDING PYTHON
- Page 395 and 396: 364 CHAPTER 17 ■ EXTENDING PYTHON
- Page 397 and 398: 366 CHAPTER 17 ■ EXTENDING PYTHON
- Page 399 and 400: 368 CHAPTER 17 ■ EXTENDING PYTHON
- Page 401 and 402: 370 CHAPTER 17 ■ EXTENDING PYTHON
- Page 404 and 405: CHAPTER 18 ■ ■ ■ Packaging Yo
- Page 406 and 407: CHAPTER 18 ■ PACKAGING YOUR PROGR
- Page 408 and 409: CHAPTER 18 ■ PACKAGING YOUR PROGR
- Page 410 and 411: CHAPTER 18 ■ PACKAGING YOUR PROGR
- Page 412 and 413: CHAPTER 19 ■ ■ ■ Playful Prog
- Page 414 and 415: CHAPTER 19 ■ PLAYFUL PROGRAMMING
- Page 416 and 417: CHAPTER 19 ■ PLAYFUL PROGRAMMING
- Page 418 and 419: CHAPTER 19 ■ PLAYFUL PROGRAMMING
- Page 420: CHAPTER 19 ■ PLAYFUL PROGRAMMING
- Page 423 and 424: 392 CHAPTER 20 ■ PROJECT 1: INSTA
- Page 425 and 426: 394 CHAPTER 20 ■ PROJECT 1: INSTA
346 CHAPTER 16 ■ TESTING, 1-2-3<br />
Trying: square(3)<br />
Expecting: 9<br />
ok<br />
0 of 2 examples failed in my_math.square.__doc__<br />
1 items had no tests:<br />
test<br />
1 items passed all tests:<br />
2 tests in my_math.square<br />
2 tests in 2 items.<br />
2 passed and 0 failed.<br />
Test passed.<br />
As you can see, a lot happened behind the scenes. The testmod function checks both the<br />
module docstring (which, as you can see, contains no tests) and the function docstring (which<br />
contains two tests, both of which succeed).<br />
With this in place, you can safely change your code. Let’s say that you want <strong>to</strong> use the<br />
<strong>Python</strong> exponentiation opera<strong>to</strong>r instead of plain multiplication, and use x**2 instead of x*x.<br />
You edit the code, but accidentally forget <strong>to</strong> enter the number 2, and end up with x**x. Try it,<br />
and then run the script <strong>to</strong> test the code. What happens? This is the output you get:<br />
*****************************************************************<br />
Failure in example: square(3)<br />
from line #5 of my_math.square<br />
Expected: 9<br />
Got: 27<br />
*****************************************************************<br />
1 items had failures:<br />
1 of 2 in my_math.square<br />
***Test Failed*** 1 failures.<br />
So the bug was caught, and you get a very clear description of what is wrong. Fixing the<br />
problem shouldn’t be difficult now.<br />
■Caution Don’t trust your tests blindly, and be sure <strong>to</strong> test enough cases. As you can see, the test using<br />
square(2) does not catch the bug because for x==2, x**2 and x**x are the same thing!<br />
For more information about the doctest module, you should again check out the library<br />
reference (http://python.org/doc/lib/module-doctest.html).