{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "`importnb` and [`nbval`](https://github.com/computationalmodelling/nbval)\n", "\n", "`importnb, pidgin` are complimented nicely by `nbval`. `nbval` + `importnb` performs\n", "normal test discovery AND compares the out results. Doctests may be included also. " ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ " with __import__('IPython').utils.capture.capture_output(stdout=True):\n", " if __name__ == '__main__':\n", " no_nbval = !ipython -m pytest -- 2018-11-23-importnb-and-nbval.ipynb --collect-only\n", " with_nbval = !ipython -m pytest -- 2018-11-23-importnb-and-nbval.ipynb --nbval --collect-only\n", " with_nbval_doctests = !ipython -m pytest -- 2018-11-23-importnb-and-nbval.ipynb --doctest-modules --nbval --collect-only\n", " no_nbval_doctests = !ipython -m pytest -- 2018-11-23-importnb-and-nbval.ipynb --doctest-modules --collect-only\n", "\n", " for report in (no_nbval, with_nbval, with_nbval_doctests, no_nbval_doctests):\n", " while not report[0].startswith('collected'): report.pop(0)\n", " while report[-1].startswith('==='): report.pop()\n", " while not report[-1].strip(): report.pop()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Include a function that is found with normal `pytest` discovery." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ " def test_function(): \"\"\"This will not be tested.\"\"\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Include a `doctest`" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ " def a_function_with_a_doctest(): \"\"\">>> assert True\"\"\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Don't forget about the underutilized [`__test__` `object` recognized by `doctest`](https://docs.python.org/2/library/doctest.html#which-docstrings-are-examined)." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ " __test__ = {'another doctest': \">>> assert 100\"}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Assert that __test__ is found." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ " if __name__ == '__main__': \n", " assert '.__test__.' in ''.join(with_nbval_doctests)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'There are 8 code cells.'" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ " with open('2018-11-23-importnb-and-nbval.ipynb') as file: cells = len(\n", " list(object for object in __import__('nbformat').read(file, 4)['cells']\n", " if object['cell_type'] == 'code' and ''.join(object['source']).strip()))\n", " \n", " F\"\"\"There are {cells} code cells.\"\"\"" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", " | DoctestItem | \n", "Function | \n", "IPyNbCell | \n", "IPyNbFile | \n", "NotebookModule | \n", "total | \n", "
---|---|---|---|---|---|---|
(all, collected 11 items) | \n", "2 | \n", "1.0 | \n", "8 | \n", "1 | \n", "1.0 | \n", "13.0 | \n", "
(doctests, collected 3 items) | \n", "2 | \n", "1.0 | \n", "\n", " | \n", " | 1.0 | \n", "4.0 | \n", "
(importnb, collected 1 item) | \n", "\n", " | 1.0 | \n", "\n", " | \n", " | 1.0 | \n", "2.0 | \n", "
(nbval, collected 9 items) | \n", "\n", " | 1.0 | \n", "8 | \n", "1 | \n", "1.0 | \n", "11.0 | \n", "
--nbval --doctest-modules
& `importnb` ensure that a notebook can be tested in a quite a few ways. An author should not be limited in their mode of testing."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"It would be great ideal to focus on notebooks as tests rather than experimentation. Early in the ideation process there is a little difference between source code and test code. There are tools in the notebook ecosystem that seamlessly work with a stack of existing notebooks. Using the suite of `pytest` notebook testing tools `nbval` and `importnb` will assist authors in writing more durable notebooks."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.6"
}
},
"nbformat": 4,
"nbformat_minor": 2
}