Open bogdantoader opened 2 years ago
Excellent idea! Something like this could help (copy-pasted from ioSPI):
"""Unit tests for the notebooks."""
import glob
import os
import subprocess
import tempfile
import pytest
NOTEBOOKS_DIR = "notebooks"
NOTEBOOKS_TO_SKIP = os.path.join(NOTEBOOKS_DIR, "download_and_upload_with_osf.ipynb")
def _exec_notebook(path):
"""Execute notebook at path.
Parameters
----------
path : str
Relative path of the notebook.
E.g. notebooks/particle_metadata.ipynb
"""
file_name = tempfile.NamedTemporaryFile(suffix=".ipynb").name
args = [
"jupyter",
"nbconvert",
"--to",
"notebook",
"--execute",
"--ExecutePreprocessor.timeout=1000",
"--ExecutePreprocessor.kernel_name=python3",
"--output",
file_name,
path,
]
subprocess.check_call(args)
paths = sorted(glob.glob(f"{NOTEBOOKS_DIR}/*.ipynb"))
@pytest.mark.parametrize("path", paths)
def test_notebook(path):
"""Test the notebook at path by executing it.
Parameters
----------
path : str
Relative path of the notebooks.
E.g. notebooks/particle_metadata.ipynb
"""
if path in NOTEBOOKS_TO_SKIP:
pytest.skip()
_exec_notebook(path)
Currently when a new notebook is added, one needs to either create a new test_x.py file that replicates a lot of the code in tests/test_notebooks.py, or add a new set of functions in test_notebooks (test_resources, _exec_notebook, test_new_notebook). I think it's possible to change the _exec_notebook and test_X functions so that for each new notebook we only need to add a new test_resources function, and then have a test_notebooks function that loops through each of these resources functions and calls _exec_notebook with the parameters in them.