Skip to content

Commit 0d79325

Browse files
committed
introduce unittest
1 parent 72e3cbe commit 0d79325

File tree

5 files changed

+175
-273
lines changed

5 files changed

+175
-273
lines changed

06-edges.html

-159
This file was deleted.

06-unittest.md

+117
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
---
2+
layout: page
3+
title: Testing
4+
subtitle: The Unittest Module
5+
minutes: 10
6+
---
7+
> ## Learning Objectives {.objectives}
8+
>
9+
> - Understand how to use Unittest to write and run test cases
10+
> - Understand that Unittest can be used for many styles of test, not just unit tests
11+
> -
12+
> -
13+
14+
The Python standard library provides a module for writing and running tests, called `unittest`, which is documented for [Python3.6](https://docs.python.org/3.6/library/unittest.html?highlight=unittest#module-unittest) and [Python2.7](https://docs.python.org/2/library/unittest.html?highlight=unittest#module-unittest).
15+
16+
This module is useful for writing all styles of test, including unit tests and functional tests.
17+
18+
## Functional Tests
19+
20+
Functional testing is a way of checking software to ensure that it has all the required functionality that's specified within its functional requirements. This will test many methods and may interact with dependencies like file access.
21+
22+
Functional tests are often the first tests that are written as part of writing a program. They can link closely to a requirement: "This programme shall ...".
23+
24+
These tests are testing overall behaviour.
25+
26+
They are especially useful if code is being restructured or re-factored, to build confidence that the key behaviour is maintained during the restructuring.
27+
28+
Often true unit tests, as described in the previous page, test the implementation and may require changing at the same time as the code during a refactor.
29+
30+
## Unittest TestCases
31+
32+
unittest is part of the Python core library; it defines a class, unittest.TestCase which provides lots of useful machinery for writing tests. We define classes which inherit from unittest.TestCase, bringing in their useful behaviour for us to apply to our tests.
33+
34+
The reuse of objects in this way is a really useful programming approach. Don't worry if it is new to you. For testing with unittest, you can just think of it as a framework to fit your test cases into.
35+
36+
We can rewrite the tests from the previous page, using the Unittest approach.
37+
38+
~~~ {.python}
39+
import unittest
40+
41+
def mean(num_list):
42+
try:
43+
return sum(num_list)/len(num_list)
44+
except ZeroDivisionError :
45+
return 0
46+
except TypeError as detail :
47+
msg = ("The algebraic mean of an non-numerical list is undefined."
48+
" Please provide a list of numbers.")
49+
raise TypeError(detail.__str__() + "\n" + msg)
50+
51+
class TestMean(unittest.TestCase):
52+
def test_ints(self):
53+
num_list = [1,2,3,4,5]
54+
obs = mean(num_list)
55+
exp = 3
56+
self.assertEqual(obs, exp)
57+
58+
def test_zero(self):
59+
num_list=[0,2,4,6]
60+
obs = mean(num_list)
61+
exp = 3
62+
self.assertEqual(obs, exp)
63+
64+
def test_double(self):
65+
# This one will fail in Python 2
66+
num_list=[1,2,3,4]
67+
obs = mean(num_list)
68+
exp = 2.5
69+
self.assertEqual(obs, exp)
70+
71+
def test_long(self):
72+
big = 100000000
73+
obs = mean(range(1,big))
74+
exp = big/2.0
75+
self.assertEqual(obs, exp)
76+
77+
def test_complex(self):
78+
num_list = [2 + 3j, 3 + 4j, -32 + 2j]
79+
obs = mean(num_list)
80+
exp = -9 + 3j
81+
self.assertEqual(obs, exp)
82+
83+
if __name__ == '__main__':
84+
unittest.main()
85+
~~~
86+
87+
The naming of `class` and `def` entities is important. All classes should be named beginning `Test` and all methods should be named beginning `test-`. This enables the test runner to identify test cases to run.
88+
89+
Save this code to a file, e.g. `test_mean.py`, again beginning the name with `test_`. This module can be run directly with python:
90+
91+
~~~ {.bash}
92+
python test_mean.py
93+
~~~
94+
95+
~~~ {.output}
96+
.....
97+
----------------------------------------------------------------------
98+
Ran 5 tests in 2.053s
99+
100+
OK
101+
102+
~~~
103+
104+
Unittest reports failures and errors on test cases, which we can see if we run Python2, as one of our tests only passes in Python3:
105+
106+
~~~ {.bash}
107+
python2 test_mean.py
108+
~~~
109+
110+
~~~ {.output}
111+
.....
112+
----------------------------------------------------------------------
113+
Ran 5 tests in 2.053s
114+
115+
OK
116+
117+
~~~

0 commit comments

Comments
 (0)