diff --git a/allennlp/commands/__init__.py b/allennlp/commands/__init__.py index 92ce75e9782..7922b3fe31c 100644 --- a/allennlp/commands/__init__.py +++ b/allennlp/commands/__init__.py @@ -1,7 +1,6 @@ from typing import Dict import argparse import logging -import sys from allennlp.commands.elmo import Elmo from allennlp.commands.evaluate import Evaluate @@ -11,8 +10,8 @@ from allennlp.commands.serve import Serve from allennlp.commands.dry_run import DryRun from allennlp.commands.subcommand import Subcommand +from allennlp.commands.test_install import TestInstall from allennlp.commands.train import Train -from allennlp.service.predictors import DemoModel from allennlp.common.util import import_submodules logger = logging.getLogger(__name__) # pylint: disable=invalid-name @@ -40,6 +39,7 @@ def main(prog: str = None, "elmo": Elmo(), "fine-tune": FineTune(), "dry-run": DryRun(), + "test-install": TestInstall(), # Superseded by overrides **subcommand_overrides diff --git a/allennlp/commands/test_install.py b/allennlp/commands/test_install.py new file mode 100644 index 00000000000..03421d49ef5 --- /dev/null +++ b/allennlp/commands/test_install.py @@ -0,0 +1,66 @@ +""" +The ``test-install`` subcommand verifies +an installation by running the unit tests. + +.. code-block:: bash + + $ allennlp test-install --help + usage: allennlp test-install [-h] [--run-all] + [--include-package INCLUDE_PACKAGE] + + Test that installation works by running the unit tests. + + optional arguments: + -h, --help show this help message and exit + --run-all By default, we skip tests that are slow or download + large files. This flag will run all tests. + --include-package INCLUDE_PACKAGE + additional packages to include +""" + +import argparse +import logging +import os + +import pytest + +from allennlp.commands.subcommand import Subcommand + +logger = logging.getLogger(__name__) # pylint: disable=invalid-name + +class TestInstall(Subcommand): + def add_subparser(self, name: str, parser: argparse._SubParsersAction) -> argparse.ArgumentParser: + # pylint: disable=protected-access + description = '''Test that installation works by running the unit tests.''' + subparser = parser.add_parser( + name, description=description, help='Run the unit tests.') + + subparser.add_argument('--run-all', action="store_true", + help="By default, we skip tests that are slow " + "or download large files. This flag will run all tests.") + + subparser.set_defaults(func=_run_test) + + return subparser + + +def _get_project_root(): + return os.path.abspath( + os.path.join( + os.path.dirname(os.path.realpath(__file__)), + os.pardir, os.pardir)) + + +def _run_test(args: argparse.Namespace): + initial_working_dir = os.getcwd() + project_root = _get_project_root() + logger.info("Changing directory to %s", project_root) + os.chdir(project_root) + test_dir = os.path.join(project_root, "tests") + logger.info("Running tests at %s", test_dir) + if args.run_all: + pytest.main([test_dir]) + else: + pytest.main([test_dir, '-k', 'not sniff_test and not notebooks_test']) + # Change back to original working directory after running tests + os.chdir(initial_working_dir) diff --git a/doc/api/allennlp.commands.rst b/doc/api/allennlp.commands.rst index 2761bbecdd4..865c97ac806 100644 --- a/doc/api/allennlp.commands.rst +++ b/doc/api/allennlp.commands.rst @@ -17,14 +17,17 @@ The included module ``allennlp.run`` is such a script: -h, --help show this help message and exit Commands: - train Train a model - evaluate Evaluate the specified model + dataset - predict Use a trained model to make predictions. - serve Run the web service and demo. - make-vocab - Create a vocabulary - elmo Use a trained model to make predictions. - dry-run Create a vocabulary, compute dataset statistics and other training utilities. + train Train a model + evaluate Evaluate the specified model + dataset + predict Use a trained model to make predictions. + serve Run the web service and demo. + make-vocab Create a vocabulary + elmo Use a trained model to make predictions. + fine-tune Continue training a model on a new dataset + dry-run Create a vocabulary, compute dataset statistics and other + training utilities. + test-install + Run the unit tests. However, it only knows about the models and classes that are included with AllenNLP. Once you start creating custom models, @@ -41,6 +44,7 @@ calls ``main()``. allennlp.commands.fine_tune allennlp.commands.elmo allennlp.commands.dry_run + allennlp.commands.test_install .. automodule:: allennlp.commands :members: diff --git a/doc/api/allennlp.commands.test_install.rst b/doc/api/allennlp.commands.test_install.rst new file mode 100644 index 00000000000..40fda6b8687 --- /dev/null +++ b/doc/api/allennlp.commands.test_install.rst @@ -0,0 +1,4 @@ +allennlp.commands.test_install +============================== + +.. automodule:: allennlp.commands.test_install diff --git a/requirements.txt b/requirements.txt index b0cc945fe0a..8df25db27c7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -66,3 +66,14 @@ h5py # For timezone utilities pytz==2017.3 + +#### ESSENTIAL TESTING-RELATED PACKAGES #### +# We'll use pytest to run our tests; this isn't really necessary to run the code, but it is to run +# the tests. With this here, you can run the tests with `py.test` from the base directory. +pytest + +# Allows marking tests as flaky, to be rerun if they fail +flaky + +# Required to mock out `requests` calls +responses>=0.7 diff --git a/requirements_test.txt b/requirements_test.txt index 3905175b992..403f6be02ed 100644 --- a/requirements_test.txt +++ b/requirements_test.txt @@ -3,10 +3,6 @@ # Checks style, syntax, and other useful errors. pylint==1.8.1 -# We'll use pytest to run our tests; this isn't really necessary to run the code, but it is to run -# the tests. With this here, you can run the tests with `py.test` from the base directory. -pytest - # Tutorial notebooks jupyter @@ -16,9 +12,6 @@ mypy==0.521 # Allows generation of coverage reports with pytest. pytest-cov -# Allows marking tests as flaky, to be rerun if they fail -flaky - # Allows codecov to generate coverage reports coverage codecov @@ -26,9 +19,6 @@ codecov # Required to run sanic tests aiohttp -# Required to mock out `requests` calls -responses>=0.7 - #### DOC-RELATED PACKAGES #### # Builds our documentation. diff --git a/setup.py b/setup.py index 8335eed245f..7341ecac9c0 100644 --- a/setup.py +++ b/setup.py @@ -120,7 +120,10 @@ 'scikit-learn', 'scipy', 'pytz==2017.3', - 'unidecode' + 'unidecode', + 'pytest', + 'flaky', + 'responses>=0.7' ], scripts=["bin/allennlp"], setup_requires=setup_requirements, diff --git a/tests/commands/test_install_test.py b/tests/commands/test_install_test.py new file mode 100644 index 00000000000..0fb56546a8a --- /dev/null +++ b/tests/commands/test_install_test.py @@ -0,0 +1,13 @@ +# pylint: disable=invalid-name,no-self-use +import os + +from allennlp.common.testing import AllenNlpTestCase +from allennlp.commands.test_install import _get_project_root + + +class TestTestInstall(AllenNlpTestCase): + def test_get_project_root(self): + project_root = _get_project_root() + assert os.path.exists(os.path.join(project_root, "tests")) + assert os.path.exists(os.path.join(project_root, "LICENSE")) + assert os.path.exists(os.path.join(project_root, "setup.py")) diff --git a/tests/notebooks_test.py b/tests/notebooks_test.py index 9d23a76439e..4d999b5dc19 100644 --- a/tests/notebooks_test.py +++ b/tests/notebooks_test.py @@ -1,8 +1,12 @@ import os -import nbformat -from nbconvert.preprocessors.execute import CellExecutionError -from nbconvert.preprocessors import ExecutePreprocessor +try: + import nbformat + from nbconvert.preprocessors.execute import CellExecutionError + from nbconvert.preprocessors import ExecutePreprocessor +except ModuleNotFoundError: + print("jupyter must be installed in order to run notebook tests. " + "To install with pip, run: pip install jupyter") from allennlp.common.testing import AllenNlpTestCase