#!/usr/bin/python3 # -*- mode: python; mode: auto-fill; fill-column: 80 -*- # # This file is part of Plinth. # # Derived from code sample at: # http://jeetworks.org/adding-test-code-coverage-analysis-to-a-python-projects-setup-command/ # # Copyright 2009 Jeet Sukumaran and Mark T. Holder. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program. If not, see . # """ Support for integration of code test coverage analysis with setuptools. """ import coverage import glob import setuptools import shutil import time # Project directories with testable source code SOURCE_DIRS = ['plinth'] + glob.glob('plinth/modules/*') # Files to exclude from coverage analysis and reporting FILES_TO_OMIT = [ 'plinth/tests/*.py', 'plinth/modules/*/tests/*.py' ] # Location of coverage HTML report files COVERAGE_REPORT_DIR = 'plinth/tests/coverage/report' class CoverageCommand(setuptools.Command): """ Subclass of setuptools Command to perform code test coverage analysis. """ description = 'Run test coverage analysis' user_options = [ ('test-module=', 't', 'Explicitly specify a single module to test') ] def initialize_options(self): """Initialize options to default values.""" self.test_module = None def finalize_options(self): pass def run(self): """Main command implementation.""" if self.distribution.install_requires: self.distribution.fetch_build_eggs( self.distribution.install_requires) if self.distribution.tests_require: self.distribution.fetch_build_eggs( self.distribution.tests_require) # Erase any existing HTML report files try: shutil.rmtree(COVERAGE_REPORT_DIR, True) except Exception: pass # Run the coverage analysis cov = coverage.coverage(auto_data=True, config_file=True, source=SOURCE_DIRS, omit=FILES_TO_OMIT) cov.erase() # Erase existing coverage data file cov.start() # Invoke the Django test setup and test runner logic from plinth.tests.runtests import run_tests run_tests(pattern=self.test_module, return_to_caller=True) cov.stop() # Generate an HTML report html_report_title = 'FreedomBox:Plinth -- Test Coverage as of ' + \ time.strftime('%x %X %Z') cov.html_report(directory=COVERAGE_REPORT_DIR, omit=FILES_TO_OMIT, title=html_report_title) # Print a detailed console report with the overall coverage percentage print() cov.report(omit=FILES_TO_OMIT) # Print the location of the HTML report print('\nThe HTML coverage report is located at {}.'.format( COVERAGE_REPORT_DIR))