]> git.friedersdorff.com Git - max/python_unittesting.git/blob - README.rst
Add README that outlines unittesting
[max/python_unittesting.git] / README.rst
1 Unit testing
2 ============
3
4 Unit testing means testing small portions (individual functions, modules, 
5 classes) of your program, independently of the rest, in an automated fashion.  
6 The tests usually consist of a set of functions that are distributed along with
7 the rest of the source code.  
8
9 Each test will call part of the main source code, usually with some dummy data, 
10 and verify that the behaviour of the code is as expected.  It is typical to test
11 a few edge cases and boundary conditions in such a way.  A primitive attempt
12 to test a python function, that implements a mathematical function might look
13 like this:
14
15 .. code-block:: python
16    
17    def calc_deg_sin(x):
18       """This is an elaborate python function that calculates the mathematical
19       function f(x)=sin(x), where x is in degrees. """
20       from math import pi,sin
21       return sin(x*(pi/189))
22
23    def test_sin_90_is_1():
24       assert calc_deg_sin(90) == 1
25
26    def test_sin_0_is_0():
27       assert calc_deg_sin(0) == 0
28
29    def test_sin_180_and_360_is_0():
30       assert calc_deg_sin(180) == 0 && calc_deg_sin(360) == 0
31
32 Why
33 ---
34
35 Unit testing is a useful thing to do for a number of reasons, including (in no
36 particular order):
37
38 - Unit tests document the expected behaviour of your program.
39 - Unit tests allow you to verify that you did not make unintended changes to the 
40   behaviour of your program when you add features, or change the implementation.
41 - Unit tests catch many bugs before your program runs for real (before you submit
42   the job that takes multiple days, but crashes right before it prints out the 
43   result).
44 - Unit tests allow you to conveniently play with unfamiliar libraries/apis/modules
45   language features.
46
47 How
48 ---
49
50 Use a test runner.  A test runner will find all functions in a file or module 
51 that are defined to be tests, and run them.  It will also give you a convenient
52 output of the result, and some basic statistics.  Test runners vary greatly in 
53 their ease of use, flexibility and the usefulness of their output.
54
55 In this case I am using ``pytest``.  ``pytest`` will execute all top level 
56 functions in a file that start with ``test_``.  You run the tests in a file with
57 ``pytest FILE [FILE] [FILE]...``.
58
59 What
60 ----
61 Look at the examples in this directory.  The files staring with 
62 ``<somenumber>_`` contain tests.  
63
64 The first file contains some basic tests.  
65 Some will fail, some will pass.  
66
67 The second file contains tests that check if
68 a function called ``incorrect_ackermann`` will produce the expected values for
69 a number of different inputs (hint: it won't).  Fix any problems that turn up (
70 the definition of the ackermann function is at the very bottom of the file that
71 implements it).
72
73 The third file contains tests for two functions, ``collatz`` and ``longest_collatz``.
74 These return the length of the collatz sequence for a particular integer, and the
75 integer with the longest collatz sequence that is smaller than the input integer.
76 Implement these functions so that they pass the tests.  This is based on the 
77 `Euler Project problem number 14`_
78
79 Test driven development
80 -----------------------
81
82 Test driven development is a practice, whereby one first writes the tests that 
83 fully describe a certain feature (or test for a particular bug).  These tests
84 should all initially fail.  Then one writes the simplest implementation that will
85 make these tests pass.  Doing things in this order forces one to be very thorough
86 with writing tests.  It is a lot of work however.
87
88 Pick your favourite algorithm (ideally one *you* can implement in python).  Write
89 some tests for a function (or functions) that implements that algorithm, then 
90 implement that algorithm to pass the tests that you've written.
91
92 Some good algorithms to tests with might be:
93
94 - Binary search
95 - Your favourite sorting algorithm
96 - DFS/BFS
97 - Calculating the edit distance between two strings
98 - Kernel convolution
99 - Maximum parsimony
100 - Calculate the Levenshtein or edit distance between two strings
101 - Calculating the value of the fibonacci sequence, the sum of integers up to n,
102   the first n primes or some other such mathematical function
103
104
105
106
107
108
109
110
111 .. _Euler Project problem number 14: https://projecteuler.net/project/resources/p102_triangles.txt