Skip to content

Commit

Permalink
Merge pull request #227 from dynamicslab/external-examples
Browse files Browse the repository at this point in the history
External examples functionality
  • Loading branch information
akaptano committed Aug 15, 2022
2 parents 32c96aa + 5c18374 commit b831b16
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 7 deletions.
9 changes: 7 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,14 @@ At a minimum, we need to be able to run the example notebooks in the normal mode
|-example_data.py # has functions to create/load data
|-mock_data.py # has functions with same name as in example_data.py which create/load smaller datasets
|-example.ipynb # run python examples/publish_notebook/<name_of_example> to generate this. Needs packages in requirements-dev.txt
|-other files, if required (helper module, data, etc)
|-utils.py (Any other names example.py needs to import. Any additional local modules imported by example.py need to be submodules of utils.py, e.g. utils.plotting)
You can optimize your notebook for testing by checking ``__name__``. When our tests run ``example.py`` they set the ``__name__`` global to ``"testing"``. For instance, your notebook should determine whether to import from ``mock_data`` or ``example_data`` using this method (another example: you could also use this method to set ``max_iter``). It's a bit arbitrary, but try to make your examples run in under ten seconds using the mock data. You can use our test to verify your example in testing mode:

.. code-block::
pytest -k test_external --external-notebook="path/to/<name_of_example>"
You can optimize your notebook for testing by checking ``__name__``. When our tests run ``example.py`` they set the ``__name__`` global to ``"testing"``. For instance, your notebook should determine whether to import from ``mock_data`` or ``example_data`` using this method.
Contributing code
^^^^^^^^^^^^^^^^^
Expand Down
25 changes: 25 additions & 0 deletions test/conftest.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
"""
Shared pytest fixtures for unit tests.
"""
from pathlib import Path

import numpy as np
import pytest
from scipy.integrate import solve_ivp
Expand All @@ -19,6 +21,29 @@
from pysindy.utils.odes import lorenz_control


def pytest_addoption(parser):
parser.addoption(
"--external-notebook",
action="append",
default=[],
help=(
"name of notebook to test. Only valid if running"
" test_notebooks.test_external"
),
)


def pytest_generate_tests(metafunc):
if "external_notebook" in metafunc.fixturenames:
metafunc.parametrize(
"external_notebook",
[
Path(f.lstrip('"').rstrip('"'))
for f in metafunc.config.getoption("external_notebook")
],
)


@pytest.fixture
def data_1d():
t = np.linspace(0, 5, 100)
Expand Down
16 changes: 11 additions & 5 deletions test/test_notebooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,13 @@ def purge_notebook_modules():
This might be better served by fixing imports in notebooks using
importlib.
"""
SENTINEL = object()
sys.modules.pop("utils", SENTINEL)
sys.modules.pop("mock_data", SENTINEL)
local_modules = [
key for key in sys.modules if key[:5] == "utils" or key[:9] == "mock_data"
]
[sys.modules.pop(mod) for mod in local_modules]
yield
sys.modules.pop("utils", SENTINEL)
sys.modules.pop("mock_data", SENTINEL)
SENTINEL = object()
[sys.modules.pop(mod, SENTINEL) for mod in local_modules]


@pytest.mark.parametrize("directory", notebook_scripts)
Expand All @@ -70,6 +71,11 @@ def test_notebook_script(directory: Path, purge_notebook_modules):
runpy.run_path(str(notebook_dir / directory / "example.py"), run_name="testing")


def test_external(external_notebook: Path, purge_notebook_modules):
with _cwd(external_notebook.resolve()):
runpy.run_path(str("example.py"), run_name="testing")


@pytest.mark.parametrize("filename", notebooks)
@pytest.mark.slow
def test_notebook(filename):
Expand Down

0 comments on commit b831b16

Please sign in to comment.