A comparison of different testing tools in Python.
Covered yet: unittest and nosetest
Not covered yet: pytest
unittest
Installation
Unittest is built in to Python and part of the standard library since version 2.1. and thereby one of the ready to use ‘Battery included’ modules of Python.
Using
Inside the project-folder run:
python -m unittest
unittest will start in the test discovery mode and automaticaly detect all files which start with test_
. Example:
test_ex47.property
test_some_name.py
But you can run any file which has tests. Just specify the path:
python -m unittest tests/something_to_test.py
Style
Import
import unittest
Testcases
unittest
provides a base class, TestCase
, which may be used to create new test cases. In this case, write a class that inherits from unittest.TestCase
:
import unittest
from ex47.game import Room
class MyTest(unittest.TestCase):
def test_room(self):
gold = Room("GoldRoom",
"""This room has gold in it you can grab. There's a
door to the north.""")
self.assertEqual(gold.name, "GoldRoom")
self.assertEqual(gold.paths, {})
if __name__ == '__main__':
unittest.main()
Start every test function with test_
. This naming convention informs the test runner about which methods represent tests.
The final block if __name__ == '__main__':
shows a simple way to run the tests. unittest.main() provides a command-line interface to the test script. So you have to include the main function on the end of your script to run the tests from the command line.
Specialty
The test cases inherit from the base class unittest.TestCase. So you have to subclass all of your testclasses from it. For example: class MyTest(unittest.TestCase)
.
To let unittest automaticaly detect and call your tests you need to set the main function on the end of your tests:
if __name__ == '__main__':
unittest.main()
Example
test_ex47.py
import unittest
from ex47.game import Room
class MyTest(unittest.TestCase):
def test_room(self):
gold = Room("GoldRoom",
"""This room has gold in it you can grab. There's a
door to the north.""")
self.assertEqual(gold.name, "GoldRoom")
self.assertEqual(gold.paths, {})
def test_room_paths(self):
center = Room("Center", "Test room in the center.")
north = Room("North", "Test room in the north.")
south = Room("South", "Test room in the south.")
center.add_paths({'north': north, 'south': south})
self.assertEqual(center.go('north'), north)
self.assertEqual(center.go('south'), south)
def test_map(self):
start = Room("Start", "You can go west and down a hole.")
west = Room("Trees", "There are trees here, you can go east.")
down = Room("Dungeon", "It's dark down here, you can go up.")
start.add_paths({'west': west, 'down': down})
west.add_paths({'east': start})
down.add_paths({'up': start})
self.assertEqual(start.go('west'), west)
self.assertEqual(start.go('west').go('east'), start)
self.assertEqual(start.go('down').go('up'), start)
if __name__ == '__main__':
unittest.main()
Docs
https://docs.python.org/3.6/library/unittest.html
nose
Installation
You have to install nose to use it.
pip install nose
Using
Inside the project-folder run:
# python 2
nosetests
# python 3
nosetests3
nose will automaticaly detect all files with the following regex-Pattern, and run it.
(?:^|[\\b_\\.-])[Tt]est
Style
Import
from nose.tools.import *
Testcases
Write your tests directly. They will be automaticaly inherit from the unittest.TestCase class. So, don’t wrapp it in a class.
It should look something like this:
def test_room():
gold = Room("GoldRoom", "Test sentence")
assert_equal(gold.name, "GoldRoom")
assert_equal(gold.paths, {})
Specialty
Differently to unittest you need no main function.
You can use all assertX methods found in unittest.TestCase but spell it in PEP 8#function-names fashion, so assert_equal rather than assertEqual.
Example
ex47_tests.py
from nose.tools import *
from ex47.game import Room
def test_room():
gold = Room("GoldRoom",
"""This room has gold in it you can grab. There's a
door to the north.""")
assert_equal(gold.name, "GoldRoom")
assert_equal(gold.paths, {})
def test_room_paths():
center = Room("Center", "Test room in the center.")
north = Room("North", "Test room in the north.")
south = Room("South", "Test room in the south.")
center.add_paths({'north': north, 'south': south})
assert_equal(center.go('north'), north)
assert_equal(center.go('south'), south)
def test_map():
start = Room("Start", "You can go west and down a hole.")
west = Room("Trees", "There are trees here, you can go east.")
down = Room("Dungeon", "It's dark down here, you can go up.")
start.add_paths({'west': west, 'down': down})
west.add_paths({'east': start})
down.add_paths({'up': start})
assert_equal(start.go('west'), west)
assert_equal(start.go('west').go('east'), start)
assert_equal(start.go('down').go('up'), start)
Docs
http://nose.readthedocs.io/en/latest/index.html
pytest
TODO