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:
Functions/MathFunctions.py
def absolut(a, b):
retVal = 0
if a > b:
retVal = a-b
else:
retVal = b-a
return retVal
The unittest code for it:
Main.py
import unittest
import sys
sys.path.append("Functions")
import MathFunctions
class TestMathMethods(unittest.TestCase):
def test_abs(self):
a = 1
b = 2
self.assertEqual(MathFunctions.absolut(a, b), 1)
if __name__ == '__main__':
unittest.main()
Now to generate the coverage report run in a cmd line:
coverage run Main.py
coverage html
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
class Logger:
f = None
WARN_LEVEL = -1
def __init__(self):
self.f = open('logs.txt', 'w')
self.WARN_LEVEL = 0
def write(self, warnLevel, text):
if self.WARN_LEVEL <= warnLevel:
self.f.write(text)
def setWarnLevel(self, lvl):
self.WARN_LEVEL = lvl
def closeFile(self):
self.f.close()
For it I added a unit test functionality:
class TestLogMethods(unittest.TestCase):
log = None
def setUp(self):
self.log = Log.Logger()
self.log.setWarnLevel(1)
def tearDown(self):
self.log.closeFile()
def test_logFile(self):
self.log.write(1, "test")
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:
..htmlA 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.
import unittest
import sys
sys.path.append('Functions')
def suite():
modules_to_test = ('Log', )
alltests = unittest.TestSuite()
for module in map(__import__, modules_to_test):
alltests.addTest(unittest.findTestCases(module))
return alltests
if __name__ == '__main__':
unittest.main(defaultTest='suite')
Now every test suite can be managed from var modules_to_test
I created a .bat file runall.bat containing:
coverage run alltests.py
coverage html
If you need some guidance in engineering field or you're seeking for some help don't hesitate to write me.