CSS Terms: D.2.5 Testing and Debugging [PRIMARY], D.3.2 Python
Automated unit testing is a crucial part of the "Agile" and "DevOps" approaches to software creation and deployment. The ability to get code into production with great regularity (companies good at this may deploy code into production hundreds or thousands of times per day) requires that code is regularly and thoroughly tested as it is developed, and not just "thrown over the wall" into QA just before it is released. To achieve this result, it is necessary to write automated tests (since such thorough, regular testing simply cannot be done "by hand" by busy developers) that cover all common use cases (including erroneous use) and that give clear reports on what problems, if any, have been uncovered. A good test framework makes such a test suite easy to write, and integrates well into build tools such as make and Jenkins.
Given the importance of automated testing to these contemporary development styles, Ashwin Pajankar's book is a timely addition to the literature. He has written a nice introduction to unit test automation in Python, albeit one with several flaws. If one needs a succinct overview of this topic, this book will certainly do the job,
Pajankar surveys five main testing frameworks: doctest, a very elementary testing framework in which tests are written into Python comments, unittest, Python's built-in, more sophisticated testing module, nose and nose2, two extensions of unittest, and finally pytest. As the author points out, Doctest is too primitive a tool to use for continuous-integration-style development. Its tests are limited to comparing single examples against a known value -- an important aspect of more sophiticated testing is the ability to test against random, unexpected input -- but Pajankar is justified in using it to introduce the concept of unit testing, due to this very simplicity.
After describing the various pros and cons of unittest, nose and nose2, Pajankar recommends the pytest as the best choice, due to its wealth of features and compatibility with both unittest- and nose-style tests.
The first problematic thing that struck me about this book is that Chapter One seems a very strange inclusion. The chapter is a very brief, high-level introduction to the Python programming language, aimed at someone who knows almost nothing about it. But... Is that reader likely to buy a book called Python Unit Test Automation as their first introduction to the language?! Won't they pick up something with a name like Beginning Python?
This book also includes a very large number of screen shots and copies of the output of running some command or other. Now certainly, a bit of this can be useful. But I suggest that, say, for a series of very similar tests, it is enough to put in, "Here is an example of the output of test A," and not also show the nearly identical output for tests B, C, D and E.
There are also some minor technical problems in this work. For instance, Pajankar claims "You must use [the verbose mode of doctest] because without it, the test will not produce any output unless it fails" (25). However, in many cases, that outcome might be exactly what one wants: produce output only on failure.
Another technical quibble is that Pajankar apparently does not understand the meaning of the "all" keyword in a __init__.py file. He asserts that one has to include a file in the "all" section of __init__.py to make it part of that directory's package. But that is wrong: what including a file in "all" does is to make it imported when one writes "from package import *".
Also, on page 57, Pajankar writes, "Many times, you might want to have a method that explicitly fails a test when it's called." But he does not offer any explanation of what those "many times" might be. For someone trying to learn how to write good tests, an example or two here would have been very valuable.
Despite this book's shortcomings, it provides a clear introduction to the options available for Python unit test automation, while at the same time introducing many general points about what one needs in a testing framework. For anyone who has begun writing Python programs, but is unsure about how to write automated tests for those programs, this book provides excellent guidance on how to get started.