Home Accessibility Courses Twitter The Mouth Facebook Resources Site Map About Us Contact
 
Python and Tcl - public course schedule [here]
Private courses on your site - see [here]
Please ask about maintenance training for Perl, PHP, Lua, etc
 
Testing your Python classes with the unittest package - how to

Python's unittest module - supplied within the base distribution - allows you to define and run a series of tests for a class or group of classes, and correlate the results, reporting any transgressions in a standard format without having the whole test sequence break.

Testing your code and obtaining correct results is vital whatever your application, and unit tests allow you define a series of tests, state what the answers should be, and re-run those tests time and again. Making a small alteration to the code? Rerun the unittests so that you know you haven't accidentally introduced an error!

We have a short "hello testing world" example that we use on on ALL of our Python courses (testing your code to a level that you choose is important - this is not an example I will leave out!). Full source [here]. How does it work?

1. You load your class for testing.
2. You load unittest and extend unittest.TestCase into your own TestSequenceFunctions class.
3. You define a method called setUp within the test class which initialises any data that you may need for use during the tests
4. You define as few (or as many) methods as you like with name starting test... which make calls to the class your testing then use test class methods to check that the results returned are as expected.
5. You call unittest.main to run the tests.

Here are the results of running the tests in the "hello testing world" example, showing a correct set of results:

  wizard:oct11 graham$ python utes.py
  ...
  ----------------------------------------------------------------------
  Ran 3 tests in 0.000s
  
  OK
  wizard:oct11 graham$


And really THAT is how simple you want it. A quick running of the tests and it's saying "yes, they all worked as you predicted".

What happens if something goes wrong? I have introduced a small bug into the program so that one of the tests fails, and my results from running the test suite are very different:

  wizard:oct11 graham$ python utes.py
  ..F
  ======================================================================
  FAIL: testshuffle (__main__.TestSequenceFunctions)
  ----------------------------------------------------------------------
  Traceback (most recent call last):
    File "utes.py", line 13, in testshuffle
      self.assertEqual(self.seq, range(10))
  AssertionError: Lists differ: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9,... != [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
  
  First list contains 1 additional elements.
  First extra element 10:
  10
  
  - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
  ?                              ----
  
  + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
  
  ----------------------------------------------------------------------
  Ran 3 tests in 0.002s
  
  FAILED (failures=1)
  wizard:oct11 graham$


Plenty of information there - and all because I passed an 11 element list into a test where I asserted it would be just 10 elements long. The error message shows me where the error is in general terms - "these lists are not the same" and then goes on to tell be how - "look - this list is longer because there's an extra element 10" and even "Look - it's HERE!".

The three tests used in this example are illustrative - there are a number of test methods available in the unittest.Testcase class:

assertEqual to check if two objects are equal after test code has been run
assert_ or assertTrue to check if something is true after test code has been run
assertRaises to check if a particular expection is raise by test code
and you can probably see from their names what the following do:
assertNotEqual, assertFalse, assertAlmostEqual, assertAlmostEqual

The above example is heavily based on the one in the standard Python documentation [link] ... and we've also got an extended alternative on our website [here] which gives a more vervose report:

  wizard:oct11 graham$ python utes2
  testchoice (__main__.TestSequenceFunctions) ... ok
  testsample (__main__.TestSequenceFunctions) ... ok
  testshuffle (__main__.TestSequenceFunctions) ... ok
  
  ----------------------------------------------------------------------
  Ran 3 tests in 0.000s
  
  OK
  wizard:oct11 graham$





On the private Python course I was running earlier this week, we spent more time than usual on testing - and I added a test harness into a class which I had written to illustrate oveloaded operators - adding and multiplying "mean time between failure" objects.

As is usual with modules that I write, I included a short piece of code which is to be run only of the class is run on its own - starting with
  if __name__ == "__main__":
Actually within that conditional code, I imported the unittest module and defined and ran my test sequence - dynamic and conditional loading is great as it means that the test cases and unittest module will NOT be loaded if the module is loaded as part of a full application.

Also within the test code I have printed out the __doc__ documentation string for the module so that testing automatically provides a brief description of the module / class being tested. See [here] for the full source code of the new demo, onto which I have added a full set of sample output.




As of Python 2.7, a considerable number of extra test case assertion methods have been added, allowing (for example) for testing against regular expressions. There's a new capability of running tests from the command line too ... the various additions showing how important the team at the core of Python consider testing to be. I'm mentioning these new methods on our courses, but concentrating on the well estanblished methods at present since - at the time of writing - many of you are using modules / code / systems which still require / use an earlier version of Python such as 2.6.
(written 2011-10-14)

 
Associated topics are indexed as below, or enter http://melksh.am/nnnn for individual articles
Y212 - Python - Code testing, patterns, profiles and optimisation.
  [4716] Profiling your Python program - (2016-11-01)
  [4618] Pytest - second example beyond hello world - (2016-01-08)
  [4617] Pytest - starting example - (2016-01-07)
  [4542] The principle of mocking - and the Python Mock package - (2015-10-17)
  [4540] Unittest of a Flask application including forms - (2015-10-15)
  [4538] Flask and unittest - hello web app test world - (2015-10-15)
  [4470] Testing in Python 3 - unittest, doctest and __name__ == __main__ too. - (2015-04-21)
  [4446] Combining tests into suites, and suites into bigger suites - Python and unittest - (2015-03-01)
  [4344] Python base and inherited classes, test harness and unit testing - new examples - (2014-12-07)
  [4326] Learning to program - comments, documentation and test code - (2014-11-22)
  [4090] Test Driven Development in Python - Customer Comes First - (2013-05-16)
  [3658] Using Make for a distribution - (2012-03-17)
  [3464] Passing optional and named parameters to python methods - (2011-10-04)
  [3442] A demonstration of how many Python facilities work together - (2011-09-16)
  [3441] Pressing ^C in a Python program. Also Progress Bar. - (2011-09-15)
  [2616] Defining a static method - Java, Python and Ruby - (2010-02-01)
  [2123] Using Python with OpenOffice - (2009-04-09)
  [1555] Advanced Python, Perl, PHP and Tcl training courses / classes - (2008-02-25)
  [1148] Python decorators - wrapping a method call in extra code - (2007-04-15)
  [1146] __new__ v __init__ - python constructor alternatives? - (2007-04-14)
  [1140] Python GTK - Widget, Packing, Event and Feedback example - (2007-04-09)
  [235] Preparation for a day's work - (2005-03-04)


Back to
Choosing your Python GUI - wx, Qt, Tk or GTK?
Previous and next
or
Horse's mouth home
Forward to
Practical Extraction and Reporting - using Python and Extreme Programming
Some other Articles
Taking a boat down Caen Hill Locks
Some thoughts in answer to some Melksham Campus questions
Direct Message: Really horrible blog about you ... a clever phishing trip, said to be from an MP
Practical Extraction and Reporting - using Python and Extreme Programming
Testing your Python classes with the unittest package - how to
Choosing your Python GUI - wx, Qt, Tk or GTK?
Tkinter - an easy to use Python Graphic User Interface - introductory examples
Havant - Shop Frontages.
Python Packages - groupings of modules. An introduction
Picture - Havant Station at Dusk
4759 posts, page by page
Link to page ... 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96 at 50 posts per page


This is a page archived from The Horse's Mouth at http://www.wellho.net/horse/ - the diary and writings of Graham Ellis. Every attempt was made to provide current information at the time the page was written, but things do move forward in our business - new software releases, price changes, new techniques. Please check back via our main site for current courses, prices, versions, etc - any mention of a price in "The Horse's Mouth" cannot be taken as an offer to supply at that price.

Link to Ezine home page (for reading).
Link to Blogging home page (to add comments).

You can Add a comment or ranking to this page

© WELL HOUSE CONSULTANTS LTD., 2019: 404 The Spa • Melksham, Wiltshire • United Kingdom • SN12 6QL
PH: 01225 708225 • EMAIL: info@wellho.net • WEB: http://www.wellho.net • SKYPE: wellho

PAGE: http://www.wellho.net/mouth/3478_Tes ... ow-to.html • PAGE BUILT: Sat May 27 16:49:10 2017 • BUILD SYSTEM: WomanWithCat