In this collection, We will cover these two: unittest - part of the Python library, similar to JUnit 3
DocTest - test by example, part of the Python library
And Other testing frameworks: Py.Test - very simple "assert" syntax.
– can also run unittest style tests
Mock objects - create "fake" external components
Run Your Tests
cmd>
python -m unittest test_average.py
FFF
-----------------------------------------
Ran 3 tests in 0.001s
FAILED (failures=3)
The test should all fail.
Exercise: Write
average(lst)
Write the code for
average()
so it passes all
tests.
Do you
feel
any difference while coding?
Test involving Floating Point
def test_with_limited_precision( self ):
self.
assertAlmostEqual
(
2.33333333, average([1,2,4]),
places=8
)
Calculations using floating point values often result in
rounding error
or
finite-precision error
.
This is normal.
To test a result which may have
rounding error
, use
assertAlmostEqual
Doctest
def average(lst):
"""Return the average of a list of numbers.
>>> average([2, 4, 0, 4])
2.5
>>> average([5])
5.0
"""
return sum(lst)/len(lst)
Include runnable code inside Python DocStrings.
Provides
example
of how to use the code
and
executable tests
!
doctest
comments
Running Doctest
if ___name__ == "__main__":
import doctest
doctest.testmod(verbose=True)
Run doctest using command line:
Or run doctest in the code:
cmd>
python -m doctest -v listutil.py
2 tests in 5 items.
2 passed and 0 failed.
Test passed.
Testing is Not So Easy!
These examples are
trivial
tests
to show the syntax.
Real
tests
are much more
thoughtful
and
demanding
.
Designing good tests makes you
think
about what the
code should do
, and what may go wrong.
Good tests are often
short
... but many of them.
References
Python Official Docs - easy to read, many examples
https://docs.python.org/3/library/unittest.html
Real Python - good explanation & how to run unit tests in IDE
https://realpython.com/python-testing/
Python Hitchhiker's Guide to Testing
https://docs.python-guide.org/writing/tests/
Examples of common testing tools
Python Cookbook, Chapter 14
How to test many common situations, including I/O
Assignment: Tests for a Stack
A
Stack
implements common stack data structure.
You can push(), pop(), and peek() elements.
Throws
StackException
if you do something stupid.
Stack
+ Stack( capacity )
+ capacity( ): int
+ size( ): int
+ isEmpty( ): boolean
+ isFull( ): boolean
+ push( T ): void
+ pop( ): T
+ peek( ): T
Stack Tests all Need a Stack
In each test we need to create a new stack (so the tests
are independent).
That's a lot of
duplicate code
.
How to eliminate duplicate code?
def
test_new_stack_is_empty
(self):
stack = Stack(5)
self.assertTrue( stack.isEmpty() )
def
test_push_and_pop
(self):
stack = Stack(5)
stack.push("foo")
self.assertEqual("foo", stack.pop() )
self.assertTrue( stack.isEmpty() )
Use setUp() to create
test fixture
import unittest
class StackTest(
unittest.TestCase
):
#
Create a new
test fixture
before each test
def
setUp
(self):
self.capacity = 5
self.stack = Stack(capacity)
def
test
_new_stack_is_empty
(self):
self.assertTrue( self.
stack.isEmpty()
)
self.assertFalse( self.
stack.isFull()
)
self.assertEqual( 0, self.
stack.size()
)
setUp() is called
before each test
.
Use tearDown() to clean up after tests
class FileTest(
unittest.TestCase
):
def
setUp
(self):
# open file containing test data
self.file = open("testdata", "r")
def
tearDown
(self):
self.file.close()
tearDown() is called
after each test
. Its not usually
needed, since setUp will re-initialize test fixture.