Skip to content

improvements to install / testing [manually merge to master] #3659

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 12 commits into from
8 changes: 3 additions & 5 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ env:
- secure: RgJI7BBL8aX5FTOQe7xiXqWHMxWokd6GNUWp1NUV2mRLXPb9dI0RXqZt3UJwKTAzf1z/OtlHDmEkBoTVK81E9iUxK5npwyyjhJ8yTJmwfQtQF2n51Q1Ww9p+XSLORrOzZc7kAo6Kw6FIXN1pfctgYq2bQkrwJPRx/oPR8f6hcbY=
- secure: E7OCdqhZ+PlwJcn+Hd6ns9TDJgEUXiUNEI0wu7xjxB2vBRRIKtZMbuaZjd+iKDqCKuVOJKu0ClBUYxmgmpLicTwi34CfTUYt6D4uhrU+8hBBOn1iiK51cl/aBvlUUrqaRLVhukNEBGZcyqAjXSA/Qsnp2iELEmAfOUa92ZYo1sk=
- BUILD_DOCS=false
- TEST_ARGS=--no-pep8
- TEST_ARGS=--omit-pep8

language: python

Expand All @@ -16,7 +16,7 @@ matrix:
- python: 3.3
- python: 3.4
- python: 2.7
env: TEST_ARGS=--pep8
env: TEST_ARGS=--pep8-only
- python: 2.7
env: BUILD_DOCS=true

Expand All @@ -36,9 +36,7 @@ script:
# Generate the font caches in a single process before starting the
# multiple processes
- python -c "from matplotlib import font_manager"
- if [[ $BUILD_DOCS == false ]]; then mkdir ../tmp_test_dir; fi
- if [[ $BUILD_DOCS == false ]]; then cd ../tmp_test_dir; fi
- if [[ $BUILD_DOCS == false ]]; then python ../matplotlib/tests.py -sv --processes=8 --process-timeout=300 $TEST_ARGS; fi
- if [[ $BUILD_DOCS == false ]]; then python setup.py test --nocapture --nose-verbose --processes=8 --process-timeout=300 $TEST_ARGS; fi
- if [[ $BUILD_DOCS == true ]]; then cd doc; python make.py html --small; fi
# We don't build the LaTeX docs here, so linkchecker will complain
- if [[ $BUILD_DOCS == true ]]; then touch build/html/Matplotlib.pdf; fi
Expand Down
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Testing

After installation, you can launch the test suite::

python tests.py
python setup.py tests

Consider reading http://matplotlib.org/devel/coding_guide.html#testing for
more information.
104 changes: 104 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
# This needs to be the very first thing to use distribute
from distribute_setup import use_setuptools
use_setuptools()
from setuptools.command.test import test as TestCommand

import sys

Expand Down Expand Up @@ -122,6 +123,105 @@
'Topic :: Scientific/Engineering :: Visualization',
]


class NoseTestCommand(TestCommand):
"""Invoke unit tests using nose after an in-place build."""

description = "Invoke unit tests using nose after an in-place build."
user_options = [
("pep8-only", None, "pep8 checks"),
("omit-pep8", None, "Do not perform pep8 checks"),
("nocapture", None, "do not capture stdout (nosetests)"),
("nose-verbose", None, "be verbose (nosetests)"),
("processes=", None, "number of processes (nosetests)"),
("process-timeout=", None, "process timeout (nosetests)"),
]

def initialize_options(self):
self.pep8_only = None
self.omit_pep8 = None

# parameters passed to nose tests
self.processes = None
self.process_timeout = None
self.nose_verbose = None
self.nocapture = None

def finalize_options(self):
self.test_args = []
if self.pep8_only:
self.pep8_only = True
if self.omit_pep8:
self.omit_pep8 = True

if self.pep8_only and self.omit_pep8:
from distutils.errors import DistutilsOptionError
raise DistutilsOptionError(
"You are using several options for the test command in an "
"incompatible manner. Please use either one of --pep8-only,"
"--omit-pep8"
)

if self.processes:
self.test_args.append("--processes={prc}".format(
prc=self.processes))

if self.process_timeout:
self.test_args.append("--process-timeout={tout}".format(
tout=self.process_timeout))

if self.nose_verbose:
self.test_args.append("--verbose")

if self.nocapture:
self.test_args.append("--nocapture")

def run(self):
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)

self.announce('running unittests with nose')
self.with_project_on_sys_path(self.run_tests)


def run_tests(self):
try:
import matplotlib
matplotlib.use('agg')
import nose
from matplotlib.testing.noseclasses import KnownFailure
from matplotlib import default_test_modules as testmodules
from matplotlib import font_manager
import time
# Make sure the font caches are created before starting any possibly
# parallel tests
if font_manager._fmcache is not None:
while not os.path.exists(font_manager._fmcache):
time.sleep(0.5)
plugins = [KnownFailure]

# Nose doesn't automatically instantiate all of the plugins in the
# child processes, so we have to provide the multiprocess plugin
# with a list.
from nose.plugins import multiprocess
multiprocess._instantiate_plugins = plugins

if self.omit_pep8:
testmodules.remove('matplotlib.tests.test_coding_standards')
elif self.pep8_only:
testmodules = ['matplotlib.tests.test_coding_standards']

nose.main(addplugins=[x() for x in plugins],
defaultTest=testmodules,
argv=['nosetests'] + self.test_args,
exit=False)
except ImportError:
sys.exit(-1)


# One doesn't normally see `if __name__ == '__main__'` blocks in a setup.py,
# however, this is needed on Windows to avoid creating infinite subprocesses
# when using multiprocessing.
Expand All @@ -136,6 +236,7 @@
package_dir = {'': 'lib'}
install_requires = []
setup_requires = []
tests_require = []
default_backend = None


Expand Down Expand Up @@ -199,6 +300,7 @@
package_data[key] = list(set(val + package_data[key]))
install_requires.extend(package.get_install_requires())
setup_requires.extend(package.get_setup_requires())
tests_require.extend(package.get_tests_require())

# Write the default matplotlibrc file
if default_backend is None:
Expand Down Expand Up @@ -259,11 +361,13 @@
# List third-party Python packages that we require
install_requires=install_requires,
setup_requires=setup_requires,
tests_require=tests_require,

# matplotlib has C/C++ extensions, so it's not zip safe.
# Telling setuptools this prevents it from doing an automatic
# check for zip safety.
zip_safe=False,
cmdclass={'test': NoseTestCommand},

**extra_args
)
8 changes: 7 additions & 1 deletion setupext.py
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,12 @@ def get_setup_requires(self):
"""
return []

def get_tests_require(self):
"""
Get a list of Python packages that we require for executing tests.
"""
return []

def _check_for_pkg_config(self, package, include_file, min_version=None,
version=None):
"""
Expand Down Expand Up @@ -688,7 +694,7 @@ def get_package_data(self):
'tests/test_rcparams.rc'
]}

def get_install_requires(self):
def get_tests_require(self):
requires = ['nose>=%s' % self.nose_min_version]
if not sys.version_info >= (3, 3):
requires += ['mock']
Expand Down
50 changes: 0 additions & 50 deletions tests.py

This file was deleted.

1 change: 1 addition & 0 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ commands =
{envpython} {toxinidir}/tests.py --processes=-1 --process-timeout=300
deps =
nose
mock
numpy