2013-12-09 208 views
12

我開始使用IPython筆記本來記錄我的一些代碼和交互式用法示例。爲了避免文檔與代碼過於過時,我希望筆記本中的代碼能夠定期執行,以捕獲輸出中的任何更改並標記運行時錯誤。測試IPython筆記本

我使用nosetests來運行迴歸測試,並想知道是否有辦法讓它爲此執行IPython筆記本。請注意,我並不試圖在IPython筆記本中運行nosetests(如在ipython_nose中所做的那樣)。更多沿着doctest插件的行。這樣的插件是否存在?

回答

5

我不知道一個實際的鼻子插件自動執行它,但here是一個腳本,顯示了這種事情所需的基本部分。其他人已經從forked它添加一些功能。

要點是您創建筆記本使用的相同內核對象,然後運行與「全部運行」相同的執行,並比較結果輸出。它有一些原始的消毒功能,可能在很大程度上被正確的文檔測試功能取代,但它並不是非常複雜。

2

nosebook可能適合您的目的。我建立它來處理這種情況:它不需要特殊的標記在筆記本上,並做了@minrk提到的一些消毒。

1

最近Andrea Zonca已發佈pytest-ipynb。我還沒有測試它,但它似乎符合你的要求(也許不是針對鼻子,但它具有整齊的功能,如細胞指示失敗)。我一定會用它來測試作業和材料的學生:)

2

我最近寫了一個腳本,做類似的東西,大部分是基於this blog on 'Testing Jupyter Notebooks'

下面是在一個稍微修改後的版本博客:

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 

現在你可以使用這個功能:

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