Skip to content

Commit

Permalink
🎨 Pair and lint test_ipynb notebook using jupytext and black
Browse files Browse the repository at this point in the history
Only a few newlines added to the actual code with black linter. This notebook/script pairing almost goes without saying. But I do wonder if I can simplify the _load_ipynb_modules function in environment.py now that we have paired notebooks.
  • Loading branch information
weiji14 committed Nov 26, 2018
1 parent 8487e88 commit c30567d
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 2 deletions.
16 changes: 14 additions & 2 deletions test_ipynb.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"metadata": {
"lines_to_next_cell": 2
},
"outputs": [],
"source": [
"from features.environment import _load_ipynb_modules\n",
Expand All @@ -29,6 +31,7 @@
"import os\n",
"import sys\n",
"\n",
"\n",
"def _unit_test_ipynb(path: str):\n",
" \"\"\"\n",
" Unit tests on loaded modules from a .ipynb file.\n",
Expand All @@ -41,6 +44,7 @@
" if num_failures > 0:\n",
" sys.exit(num_failures)\n",
"\n",
"\n",
"def _integration_test_ipynb(path: str, summary: bool = False):\n",
" \"\"\"\n",
" Integration tests on various feature behaviours inside a .feature file.\n",
Expand All @@ -64,7 +68,6 @@
"metadata": {},
"source": [
"## Unit tests\n",
"\n",
"Uses [doctest](https://en.wikipedia.org/wiki/Doctest).\n",
"Small tests for each individual function."
]
Expand Down Expand Up @@ -450,6 +453,15 @@
}
],
"metadata": {
"jupytext": {
"formats": "ipynb,py:percent",
"text_representation": {
"extension": ".py",
"format_name": "percent",
"format_version": "1.2",
"jupytext_version": "0.8.6rc0"
}
},
"kernelspec": {
"display_name": "deepbedmap",
"language": "python",
Expand Down
87 changes: 87 additions & 0 deletions test_ipynb.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# ---
# jupyter:
# jupytext:
# formats: ipynb,py:percent
# text_representation:
# extension: .py
# format_name: percent
# format_version: '1.2'
# jupytext_version: 0.8.6rc0
# kernelspec:
# display_name: deepbedmap
# language: python
# name: deepbedmap
# ---

# %% [markdown]
# # Behavioural Driven Development Testing for Jupyter Notebooks
#
# Handy way to process the run unit tests (via doctest) and integration tests (via behave) in jupyter notebooks (.ipynb) containing Python functions.
# The script will convert an .ipynb to a string format (basically a .py file), loads them as modules, and runs the tests on them.
# To run it in the console, do:
#
# python -m pytest --verbose --disable-warnings --nbval test_ipynb.ipynb
#
# The script should tell you which ipynb file's doctests has failed (e.g. srgan_train.ipynb).
# You can then open up this very jupyter notebook to debug and inspect the situation further.

# %%
from features.environment import _load_ipynb_modules
import behave.__main__

import doctest
import os
import sys


def _unit_test_ipynb(path: str):
"""
Unit tests on loaded modules from a .ipynb file.
Uses doctest.
"""
assert path.endswith(".ipynb")

module = _load_ipynb_modules(ipynb_path=path)
num_failures, num_attempted = doctest.testmod(m=module, verbose=True)
if num_failures > 0:
sys.exit(num_failures)


def _integration_test_ipynb(path: str, summary: bool = False):
"""
Integration tests on various feature behaviours inside a .feature file.
Uses behave.
"""
assert os.path.exists(path=path)
assert path.endswith(".feature")

if summary == False:
args = f"--tags ~@skip --no-summary {path}"
elif summary == True:
args = f"--tags ~@skip {path}"

num_failures = behave.__main__.main(args=args)
if num_failures > 0:
sys.exit(num_failures)


# %% [markdown]
# ## Unit tests
# Uses [doctest](https://en.wikipedia.org/wiki/Doctest).
# Small tests for each individual function.

# %%
_unit_test_ipynb(path="data_prep.ipynb")

# %%
_unit_test_ipynb(path="srgan_train.ipynb")

# %% [markdown]
# ## Integration tests
#
# Uses [behave](https://github.com/behave/behave).
# Medium sized tests which checks that components work together properly.
# Ensures that the behaviour of features (made up of units) is sound.

# %%
_integration_test_ipynb(path="features/data_prep.feature")

0 comments on commit c30567d

Please sign in to comment.