测试 Jupyter Notebook
Testing a Jupyter Notebook
我正在尝试想出一种方法来测试许多 Jupyter 笔记本。当在 Github 分支中实施新笔记本并提交拉取请求时,测试应该 运行。测试并没有那么复杂,它们主要只是测试笔记本 运行 是否端到端且没有任何错误,也许还有一些断言。然而:
- 某些单元格中的某些调用需要被模拟,例如从数据库下载数据的调用。
- 笔记本中可能有一些魔法单元运行 pip 命令或其他东西。
我愿意使用任何测试库,例如 'pytest' 或 unittest
,尽管 pytest
是首选。
我查看了一些用于测试笔记本的库,例如 nbmake, treon, and testbook,但无法使它们正常工作。我还尝试将笔记本转换为 python 文件,但魔法单元被转换为 get_ipython().run_cell_magic(...)
调用,这成为一个问题,因为 pytest
使用 python 而不是 ipython,而 get_ipython()
仅适用于 ipython。
所以,我想知道在考虑所有这些情况下测试 jupyter 笔记本的好方法是什么。感谢任何帮助。
我已经使用过的一种直接方法是使用 nbconvert
.
执行整个笔记本
由于 --execute
选项告诉 nbconvert
在转换前执行笔记本,因此引发异常的笔记本 failed.ipynb
将导致失败 运行。
jupyter nbconvert --to notebook --execute failed.ipynb
# ...
# Exception: FAILED
echo $?
# 1
另一个正确的笔记本 passed.ipynb
将导致成功导出。
jupyter nbconvert --to notebook --execute passed.ipynb
# [NbConvertApp] Converting notebook passed.ipynb to notebook
# [NbConvertApp] Writing 1172 bytes to passed.nbconvert.ipynb
echo $?
# 0
蛋糕上的樱桃,你也可以这样做through the API然后用 Pytest 把它包起来!
import nbformat
import pytest
from nbconvert.preprocessors import ExecutePreprocessor
@pytest.mark.parametrize("notebook", ["passed.ipynb", "failed.ipynb"])
def test_notebook_exec(notebook):
with open(notebook) as f:
nb = nbformat.read(f, as_version=4)
ep = ExecutePreprocessor(timeout=600, kernel_name='python3')
try:
assert ep.preprocess(nb) is not None, f"Got empty notebook for {notebook}"
except Exception:
assert False, f"Failed executing {notebook}"
运行 测试给出。
pytest test_nbconv.py
# FAILED test_nbconv.py::test_notebook_exec[failed.ipynb] - AssertionError: Failed executing failed.ipynb
# PASSED test_nbconv.py::test_notebook_exec[passed.ipynb]
备注
- 有几个output formats,我这里用过
notebook
。
This doesn’t convert a notebook to a different format per se, instead it allows the running of nbconvert preprocessors on a notebook, and/or conversion to other notebook formats.
- python 代码示例只是一个草稿,可以在很大程度上进行改进。
这是我自己使用 testbook 的解决方案。假设这是我有一个名为 my_notebook.ipynb
的笔记本,其中包含以下内容:
诀窍是在我调用 bigquery.Client
之前注入一个单元格并模拟它:
from testbook import testbook
@testbook('./my_notebook.ipynb')
def test_get_details(tb):
tb.inject(
"""
import mock
mock_client = mock.MagicMock()
mock_df = pd.DataFrame()
mock_df['week'] = range(10)
mock_df['count'] = 5
p1 = mock.patch.object(bigquery, 'Client', return_value=mock_client)
mock_client.query().result().to_dataframe.return_value = mock_df
p1.start()
""",
before=2,
run=False
)
tb.execute()
dataframe = tb.get('dataframe')
assert dataframe.shape == (10, 2)
x = tb.get('x')
assert x == 7
我正在尝试想出一种方法来测试许多 Jupyter 笔记本。当在 Github 分支中实施新笔记本并提交拉取请求时,测试应该 运行。测试并没有那么复杂,它们主要只是测试笔记本 运行 是否端到端且没有任何错误,也许还有一些断言。然而:
- 某些单元格中的某些调用需要被模拟,例如从数据库下载数据的调用。
- 笔记本中可能有一些魔法单元运行 pip 命令或其他东西。
我愿意使用任何测试库,例如 'pytest' 或 unittest
,尽管 pytest
是首选。
我查看了一些用于测试笔记本的库,例如 nbmake, treon, and testbook,但无法使它们正常工作。我还尝试将笔记本转换为 python 文件,但魔法单元被转换为 get_ipython().run_cell_magic(...)
调用,这成为一个问题,因为 pytest
使用 python 而不是 ipython,而 get_ipython()
仅适用于 ipython。
所以,我想知道在考虑所有这些情况下测试 jupyter 笔记本的好方法是什么。感谢任何帮助。
我已经使用过的一种直接方法是使用 nbconvert
.
由于 --execute
选项告诉 nbconvert
在转换前执行笔记本,因此引发异常的笔记本 failed.ipynb
将导致失败 运行。
jupyter nbconvert --to notebook --execute failed.ipynb
# ...
# Exception: FAILED
echo $?
# 1
另一个正确的笔记本 passed.ipynb
将导致成功导出。
jupyter nbconvert --to notebook --execute passed.ipynb
# [NbConvertApp] Converting notebook passed.ipynb to notebook
# [NbConvertApp] Writing 1172 bytes to passed.nbconvert.ipynb
echo $?
# 0
蛋糕上的樱桃,你也可以这样做through the API然后用 Pytest 把它包起来!
import nbformat
import pytest
from nbconvert.preprocessors import ExecutePreprocessor
@pytest.mark.parametrize("notebook", ["passed.ipynb", "failed.ipynb"])
def test_notebook_exec(notebook):
with open(notebook) as f:
nb = nbformat.read(f, as_version=4)
ep = ExecutePreprocessor(timeout=600, kernel_name='python3')
try:
assert ep.preprocess(nb) is not None, f"Got empty notebook for {notebook}"
except Exception:
assert False, f"Failed executing {notebook}"
运行 测试给出。
pytest test_nbconv.py
# FAILED test_nbconv.py::test_notebook_exec[failed.ipynb] - AssertionError: Failed executing failed.ipynb
# PASSED test_nbconv.py::test_notebook_exec[passed.ipynb]
备注
- 有几个output formats,我这里用过
notebook
。
This doesn’t convert a notebook to a different format per se, instead it allows the running of nbconvert preprocessors on a notebook, and/or conversion to other notebook formats.
- python 代码示例只是一个草稿,可以在很大程度上进行改进。
这是我自己使用 testbook 的解决方案。假设这是我有一个名为 my_notebook.ipynb
的笔记本,其中包含以下内容:
诀窍是在我调用 bigquery.Client
之前注入一个单元格并模拟它:
from testbook import testbook
@testbook('./my_notebook.ipynb')
def test_get_details(tb):
tb.inject(
"""
import mock
mock_client = mock.MagicMock()
mock_df = pd.DataFrame()
mock_df['week'] = range(10)
mock_df['count'] = 5
p1 = mock.patch.object(bigquery, 'Client', return_value=mock_client)
mock_client.query().result().to_dataframe.return_value = mock_df
p1.start()
""",
before=2,
run=False
)
tb.execute()
dataframe = tb.get('dataframe')
assert dataframe.shape == (10, 2)
x = tb.get('x')
assert x == 7