One of the things that I like about Django is that it allows you to run unit tests on the code with relative ease. So I have a bunch of unit tests now, and I was looking to expand it. For that I first needed to know which parts of the code had good coverage and which parts had no coverage. I needed to integrate code coverage with the unit testing framework. In the end, it involved modifying a few files. This is what I did:
- First, I downloaded Ned Batchelder's coverage.py module.
- Next, get this script to colorize the coverage output. I saved it as coverage_color.py
- Put both files somewhere on the python path. I put it at Python24\Lib\site-packages
- Now we need to modify the django unit test runner to include coverage. Head over to your django\test directory and edit the simple.py file
- At the top, add the following line:
import os, coverage, coverage_color
- Scroll down to the run_tests function. You will see a line like this:
unittest.TextTestRunner(verbosity=verbosity).run(suite)
destroy_test_db(old_name, verbosity) - Modify it to read like this:
coverage.start()
unittest.TextTestRunner(verbosity=verbosity).run(suite)
coverage.stop()
if not os.path.exists(settings.COVERAGE_DIR):
os.makedirs(settings.COVERAGE_DIR)
for module_string in settings.COVERAGE_MODULES:
module = __import__(module_string, globals(), locals(), [""])
f,s,m,mf = coverage.analysis(module)
fp = file(os.path.join(settings.COVERAGE_DIR, module_string + ".html"), "wb")
coverage_color.colorize_file(f, outstream=fp, not_covered=mf)
fp.close()
coverage.erase()
destroy_test_db(old_name, verbosity) - What that does is to record the coverage when running the tests. It then creates a directory for putting the HTML output, creates the colorized version of the source and dumps it into the output directory. At the end of everything, it cleans up the coverage data
- We now need to configure the COVERAGE_DIR and COVERAGE_MODULES settings. Open your Django settings.py file and add the following lines:
COVERAGE_DIR = "scripts/build/coverage" # Where the HTML output should go
COVERAGE_MODULES = ["apps.catalyst.views", "apps.catalyst.models"] # The modules that you want colorized - Save and run your Django unit tests. After running, you will have a html file for each module in the specified directory with the colorized coverage output