Update the project-level script to generate HTML, XML, and console coverage reports as runnable options.
pip
install
coverage
.With these steps, we will explore how to use coverage programmatically in a project management script.
recipe58.py
to store this command-line script.getopt
to parse command-line arguments.import getopt import logging import nose import os import os.path import re import sys from glob import glob def usage(): print print "Usage: python recipe58.py [command]" print print " --help" print " --test" print " --package" print " --publish" print " --register" print try: optlist, args = getopt.getopt(sys.argv[1:], "h", ["help", "test", "package", "publish", "register"]) except getopt.GetoptError: # print help information and exit: print "Invalid command found in %s" % sys.argv usage() sys.exit(2)
def test(): from coverage import coverage cov = coverage() cov.start() suite = ["recipe52", "recipe52b", "recipe55", "recipe56", "recipe57"] print("Running suite %s" % suite) args = [""] args.extend(suite) nose.run(argv=args) cov.stop() modules_to_report = [module + ".py" for module in suite] modules_to_report.append("network.py") cov.report(morfs=modules_to_report) cov.html_report(morfs=modules_to_report, directory="recipe58") cov.xml_report(morfs=modules_to_report, outfile="recipe58.xml")
def package(): print "This is where we can plug in code to run " + "setup.py to generate a bundle." def publish(): print "This is where we can plug in code to upload " + "our tarball to S3 or some other download site." def register(): print "setup.py has a built in function to " + "'register' a release to PyPI. It's " + "convenient to put a hook in here." # os.system("%s setup.py register" % sys.executable)
if len(optlist) == 0: usage() sys.exit(1) # Check for help requests, which cause all other # options to be ignored. for option in optlist: if option[0] in ("--help", "-h"): usage() sys.exit(1) # Parse the arguments, in order for option in optlist: if option[0] in ("--test"): test() if option[0] in ("--package"): package() if option[0] in ("--publish"): publish() if option[0] in ("--register"): register()
--test
option.recipe58.xml
.The coverage API is easy to use as shown in the following steps:
coverage()
instance.from coverage import coverage cov = coverage()
start
method to begin tracing.cov.start()
suite = ["recipe52", "recipe52b", "recipe55", "recipe56", "recipe57"] print("Running suite %s" % suite) args = [""] args.extend(suite) nose.run(argv=args)
cov.stop()
modules_to_report = [module + ".py" for module in suite] modules_to_report.append("network.py") cov.report(morfs=modules_to_report) cov.html_report(morfs=modules_to_report, directory="recipe58") cov.xml_report(morfs=modules_to_report, outfile="recipe58.xml")
The first report is a console report. The second report is an HTML report written into the subdirectory recipe58
. The third report is an XML report in Cobertura format written to recipe58.xml
.
There are many more options to fine tune the gathering as well as reporting. Just visit the online documentation at http://nedbatchelder.com/code/coverage/api.html for more details.
Python 2.7 introduces argparse
as an alternative. Current documentation gives no indication that getopt
is deprecated, so it's safe to use as we have just done. The getopt
module is a nice, easy-to-use command-line parser.
There is nothing wrong with using tools like nosetests
, the coverage tool
, setup.py
, and the many other tools that come with the Python libraries. The purpose of this recipe is to offer a convenient, alternative approach that brings all these tools into one central script. By investing a little bit of time in this script, we don't have to remember how to use all these features, but instead can develop our script to support the development workflow of our project.
3.142.36.146