简体   繁体   English

测试IPython笔记本

[英]Testing IPython Notebooks

I'm starting to use IPython notebooks to document some of my code with interactive usage examples. 我开始使用IPython笔记本来记录我的一些代码和交互式使用示例。 In order to avoid having the documentation get too far out of date from the code, I'd like the code in the notebook to get executed on a regular basis to catch any changes in output and to flag runtime errors. 为了避免文档从代码中过时,我希望笔记本中的代码能够定期执行以捕获输出中的任何更改并标记运行时错误。

I use nosetests to run regression tests and was wondering if there is a way to have it execute IPython Notebooks for this purpose. 我使用nosetests来运行回归测试,并想知道是否有办法让它为此目的执行IPython笔记本。 Note that I'm not trying to run nosetests from within the IPython notebook (as is done in ipython_nose ). 请注意,我不是试图从IPython笔记本中运行nosetests (就像在ipython_nose中一样 )。 Something more along the lines of the doctest plugin. 更多关于doctest插件的内容。 Does such a plugin exist? 这样的插件存在吗?

I don't know of an actual nose plugin to do it automatically, but here is a script showing the basic pieces that would be necessary for such a thing. 我不知道实际的鼻子插件是自动执行的,但这里有一个脚本,显示了这样的事情所必需的基本部分。 Others have since forked it to add some functionality. 其他人已经分叉它添加一些功能。

The gist is that you create the same Kernel object that the notebook uses, and run through the same execution that 'Run All' would do, and compare the resulting output. 要点是您创建了笔记本使用的相同内核对象,并执行“全部运行”所执行的相同执行,并比较结果输出。 It has some primitive sanitization, which could probably largely be replaced by the right doctest functions, but it's not super complicated. 它有一些原始的清理,可能很大程度上可以被正确的doctest函数取代,但它并不是非常复杂。

I had recently written a script that does something similar and most of it was based on this blog on 'Testing Jupyter Notebooks' 我最近编写了一个类似的脚本,其中大部分基于这个关于'测试Jupyter笔记本'的博客

Here's the slightly modified version from the one on the blog: 这是博客上稍微修改过的版本:

from glob import glob

import nbformat
from nbconvert.preprocessors import ExecutePreprocessor
from nbconvert.preprocessors.execute import CellExecutionError

def _notebook_run(path):
  """
  Execute a notebook via nbconvert and collect output.
   :returns (parsed nb object, execution errors)
  """
  kernel_name = 'python%d' % sys.version_info[0]
  this_file_directory = os.path.dirname(__file__)
  errors = []


  with open(path) as f:
    nb = nbformat.read(f, as_version=4)
    nb.metadata.get('kernelspec', {})['name'] = kernel_name
    ep = ExecutePreprocessor(kernel_name=kernel_name, timeout=10) #, allow_errors=True

    try:
      ep.preprocess(nb, {'metadata': {'path': this_file_directory}})

    except CellExecutionError as e: 
      if "SKIP" in e.traceback:
        print(str(e.traceback).split("\n")[-2])
      else:
        raise e

  return nb, errors

You could now use this function as: 您现在可以将此功能用作:

def test_notebooks():
  for notebook in glob("./*.ipynb"):
    nb, errors = _notebook_run(notebook)
    assert errors == []

nosebook may suit your purposes. nosebook可能适合您的目的。 I built it to handle just such cases: it requires no special markup in the notebook, and does some of the sanitization mentioned by @minrk. 我构建它来处理这样的情况:它不需要笔记本中的特殊标记,并进行@minrk提到的一些清理。

Recently Andrea Zonca published pytest-ipynb . 最近Andrea Zonca发表了pytest-ipynb I have not tested it yet but it seems to fit your requirements (well maybe is not targeted for nose, but it has neat features like cell indication on failures). 我还没有测试它,但它似乎符合你的要求(也许不是针对鼻子,但它具有像故障时的细胞指示一样的简洁功能)。 I will definitely use it to test assignments and material for students :) 我一定会用它来测试学生的作业和材料:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM