When I'm writing code, or updating existing code, I need to test it before I release it as generally available.
There are lots of tests I might want to perform, to ensure that all conditions are checked, and that all past bugs have been fixed and have not re-appeared. And indeed as I develop the application, it's a good idea starting off with working out what it should do. All this lot comes under the enormous subject of "unittesting", "Test Driven Development" and "Behaviour Driven Development". For not only do you want to write good and thorough tests, but you also want to be able to run the all consistently, efficiently (= automatically) and have a system in place for managing the results of the tests so you can get a very quick "yes, all is fine" or a much more detailed "you have the following problems" report. Keywords / key packages in this business include things like
unit test in Python and
Cucumber and
Gherkin in Ruby - though those latter form part of a system that you can use to test (web sites) no matter what language they're written in.
But one of the problems you have when testing is - its just that - TESTING. You don't want database changes that would result from your tests to actually appear in the live databases, and you want to get consistent results from the system even if it calls up data which is distincly inconsistent over time. For example, I look after a web application which displays train cancellations across the South West and I need to test it ... without having to wait for a train to be cancelled to do so (99.5% of services run!)
So - at the
front of the application I'll use something like
unittest and at the
back I'll use
mock objects. A mock object / mock method is where I replace the production API (application / programmer interface) of my database or remote data access class with another method of the same name, but one which does something much simpler and different for testing purposes. As long as the call is consistent and the returned results work in the narrow circumstanced that I need, it'll all work nicely and sweetly for testing, and the same code can work later on the real databse / connection.
Recent versions of Python (from 3.3) include a
unittest.Mock class which allows you to define mocks through a provided structure. Within mock objects / methods you can include coverage checking (to make sure that all your calls have been exercised), call logging, and patches for individual methods rather than total class replacement - for example, my database accessors could remain unaltereed except that
commit calls got replaces internally by
rollbacks - allowing data read of live data during testing, but no changes being made to the database.
I've written a tiny ("hello mocking world") demo
[here] in which I have mocked out the random number generator in favour of returing a single known fixed value. The source code for my application:
import random
def value():
return random.randint(0,100)
for k in range(6):
print (value())
and when run, it might return something like:
WomanWithCat:flask grahamellis$ python3 mzz
47
99
46
17
33
89
WomanWithCat:flask grahamellis$
Add in a mock method to replace
random.randint:
import sys
from unittest.mock import Mock
random.randint = Mock(return_value = 456)
and when I run that now, I get a consistent result:
WomanWithCat:flask grahamellis$ python3 mzz
456
456
456
456
456
456
WomanWithCat:flask grahamellis$
A very simple example, but it gets you started. You can now embed that code in your application, add testing on the front
The Mock library is documented
[here]. There is a LOT more you can do ...
(written 2015-10-17)
Associated topics are indexed as below, or enter http://melksh.am/nnnn for individual articles
Q456 - Object Orientation and General technical topics - Test Driven Development and Behaviour Driven Development [4326] Learning to program - comments, documentation and test code - (2014-11-22)
[4336] Test Driven Development - a first example of principle in C - (2014-12-01)
[4346] A behaviour driven example of writing a Java program - (2014-12-09)
[4374] Test driven development, and class design, from first principles (using C++) - (2014-12-30)
[4380] Behaviour Driven Development / Ruby and Cucumber - (2015-01-02)
[4387] Regression Testing my website - Cucumber and Watir - (2015-01-07)
[4457] Test framework for TCL - Tcltest - some examples - (2015-03-11)
[4634] Regression testing - via a very short C testing framework - (2016-01-29)
[4652] Testing new algorithms in PHP - (2016-02-20)
Y212 - Python - Code testing, patterns, profiles and optimisation. [235] Preparation for a day's work - (2005-03-04)
[1140] Python GTK - Widget, Packing, Event and Feedback example - (2007-04-09)
[1146] __new__ v __init__ - python constructor alternatives? - (2007-04-14)
[1148] Python decorators - wrapping a method call in extra code - (2007-04-15)
[1555] Advanced Python, Perl, PHP and Tcl training courses / classes - (2008-02-25)
[2123] Using Python with OpenOffice - (2009-04-09)
[2616] Defining a static method - Java, Python and Ruby - (2010-02-01)
[3441] Pressing ^C in a Python program. Also Progress Bar. - (2011-09-15)
[3442] A demonstration of how many Python facilities work together - (2011-09-16)
[3464] Passing optional and named parameters to python methods - (2011-10-04)
[3478] Testing your Python classes with the unittest package - how to - (2011-10-14)
[3658] Using Make for a distribution - (2012-03-17)
[4090] Test Driven Development in Python - Customer Comes First - (2013-05-16)
[4344] Python base and inherited classes, test harness and unit testing - new examples - (2014-12-07)
[4446] Combining tests into suites, and suites into bigger suites - Python and unittest - (2015-03-01)
[4470] Testing in Python 3 - unittest, doctest and __name__ == __main__ too. - (2015-04-21)
[4538] Flask and unittest - hello web app test world - (2015-10-15)
[4540] Unittest of a Flask application including forms - (2015-10-15)
[4617] Pytest - starting example - (2016-01-07)
[4618] Pytest - second example beyond hello world - (2016-01-08)
[4716] Profiling your Python program - (2016-11-01)
Some other Articles
Is the RUH hopper a limited, duplicate service running unnecessarily and at high cost?Method, Class, Module, Package - how to they relate in Python?RSpec - Ruby testing (stand alone example / no cucumber)Saturday morning at Well House ManorThe principle of mocking - and the Python Mock packageSetting up and tearing down with the Python with keywordTransWilts public transport corridorexample of SQLite using a local database file through SQLalchemy