The solution is an integrated UnitTest + CodeCoverage that will yeld user friendy code coverage report. This is a frequenctly used solution for determining the code coverage used on a Python project.
CODE COVERAGE is often requested on projects that needs to follow certain quality measurements.
It is a measurement tool to determine how much of the written code can be covered by certain test scenarios. It's a way also to detect bugs, test the code and to verify all code branches and scenarios.
The code coverage is achieved with unit tests, so all the test scenarios will be reached. Best way to develop unit tests is with a unit test framework that will povide all necessary means to develop the tests so you can only focus on test scenarios and not on the "administrative" part.
A UNIT TEST framework can offer a integrated process to setup-run-destroy the tests. It needs to support automation of test execution, grouping tests in testsuites or test collections and it also needs a reporting mechanism easy to use and understand.
For Unit tests I used unittest library, it's part of the Python standard library group. For coverage tests I used Coverage.py. You can install coverage by running "pip install coverage"
For a simple test run I created the following method to test:
def absolut(a, b):
retVal = 0
if a > b:
retVal = a-b
retVal = b-a
The unittest code for it:
a = 1
b = 2
self.assertEqual(MathFunctions.absolut(a, b), 1)
if __name__ == '__main__':
Now to generate the coverage report run in a cmd line:
coverage run Main.py
This will create a folder called "htmlcov" where the test is. The index.html is the main file of the report. For this test it looks like this:
Coverage is 83% only the a>b branch is not covered.
The useful part of the framework, besides what is done in the Hello World example refers to having a SETUP/TEAR-DOWN functionality.
So, I added a Logger class:Functions/Log.py
f = None
WARN_LEVEL = -1
self.f = open('logs.txt', 'w')
self.WARN_LEVEL = 0
def write(self, warnLevel, text):
if self.WARN_LEVEL <= warnLevel:
def setWarnLevel(self, lvl):
self.WARN_LEVEL = lvl
For it I added a unit test functionality:
log = None
self.log = Log.Logger()
Here the utility of having some setup/teardown method that executes automatically makes sense.
The methods are overwriteen, so they are virtual in the base class(TestCase class) and they are executed in the order:
The output should look like this:..html
A way to group everythoing in test suites for a better grasp of what's running and skiped tests we can use: unittest.main(defaultTest='suite') a param wich is set to all in default mode. I created this file that will describe the test suites.
modules_to_test = ('Log', )
alltests = unittest.TestSuite()
for module in map(__import__, modules_to_test):
if __name__ == '__main__':
Now every test suite can be managed from var modules_to_test
I created a .bat file runall.bat containing:
coverage run alltests.py