Unit-tests Primer
Unit testing is now a part of our development culture but there's much more than meet the eye in the subject. This article will expose some details of ESSS unit-test culture.
Module unittest
(short introduction of unittest module)
ESSS Extensions
Short description of ESSS extensions on the original unittest modules.
Output Format
We modified the original output format for tests:
Before:
ok testPlatform (coilib50.platform._tests.test_platform.Test)
Current:
ok coilib50.platform._tests_test_platform: Test.testPlatform
Color Output
Show the test status (ok, error, fail) using colors. Green for "ok", yellow for "fail" and red for "error".
TODO methods
Using the prefix todo in a method instead of test mark it as a TODO. That means that the test will not break a project continuous build if it fails.
Test case for GUI
The GUITestCase, located in the xgui20 project, serves as a base class to test GUI elements using Qt.
runtests
Runtests is a command line tool that executes tests found in a python path. The tests package must be importable by python (that means that it must have an __init__.py file)
Data directory
Create a directory that starts with "test_XXX" and it will generated a "data_XXX.py" file with its contents zipped.
Extend this explanation !!!
Remarks: Do not add a init.py module inside the test_XXX directory or else python will import the test_XXX instead of the test_XXX.py.
ESSS Organization
How the unit-tests are organized in ESSS projects and applications.
Code conventions
Always use a ETK unittest module. Do not use the python's original unittest module
from coilib50 import unittest
Rationale: The output format of our unit-test classes differs from the original, so mixing unit-test classes will generate mixed output format.
Naming conventions
UT001 - Sub-package: _tests
The tests of a given package are placed in a sub-package called _tests.
\coilib50\basic\_tests
Rationale: The tests module is not an usual module but a "protected" module and the prefix signalizes that. Using the underscore as a prefix makes it easier to find it in a big list of packages (directories).
UT002 - Module: test_XXX.py
The tests modules filenames have the test_ prefix, and follow the module naming standards: lowercases with underscores.
The preffix test_gui_ is now deprecated and must be removed.
test_platform.py
Rationale: Using a standard name for test modules makes it easier to find them. The runtests tool requires this standard in order to conside the module a test.
UT003 - Test class name: Test
Each module should have only one TestCase instance that must be named simple "Test"
class Test( TestCase ):
If you need to declare more than one test module for a given module, suffix it with a sequencial number or another string to tell them apart.
test_alpha_1
test_alpha_2
test_alpha_initialization
test_alpha_view
Rationale: We already have a lot of information about the test from the test package and method. There is no use to another layer of information in the test-case class.
UT004 - Test methods: testXXX
The test methods declared in the test-case have following the "mixed" case:
testPlatform
UT005 - Test documentation for mantis
The documentation for a test of a mantis entry must be the mantis number and description as found in the mantis database:
'''
0010885: Show current time value
'''
Utilities symbols
Often when creating a test we need to define auxiliary symbols such as variables, classes and functions:
UT006 - Declare on test: prefix "_"
When declaring a symbol other than the test-case use a underscore as a prefix.
Rationale: This avoids the automatic import feature of PyDev to try to import a symbol defined in a test module.
UT007 - Reusable symbols for tests: unittest module
If you have a symbol that can be reusable in other tests, create an unittest module and place the symbol there.
UT008 - Reusable symbols for tests: prefix "My" or "Dummy"
When declaring a reusable symbol, in a unittest module, use the "My" or "Dummy" prefix.
In this case there is no need to prefix with "_" as when declaring the symbol in the test module.
Rationale: This provides a clear way to identify a test symbol that is not part of the project.
Tips and Tricks
Using unittest module
Always import the unittest module instead of the inner symbols.
Runing only one test in eclipse
Use the sys.argv attribute to change the command line parameters to the unit test execution. You can pass any command line accepted by the test itself, such as "-v" to a verbose output.
def __name__ == '__main__':
import sys
sys.argv = ['','Test.testPlatform']
unittest.main()
Thanks
Thanks to Ari and Menegazzo for promptly reviewing this article.




Leave a comment