python - Jupyter笔记本中的功能单元测试?

标签 python unit-testing testing jupyter reproducible-research

我有一个打算重复运行的 Jupyter 笔记本。里面有函数,代码结构是这样的:

def construct_url(data):
    ...
    return url

def scrape_url(url):
    ... # fetch url, extract data
    return parsed_data

for i in mylist: 
    url = construct_url(i)
    data = scrape_url(url)
    ... # use the data to do analysis

我想为 construct_urlscrape_url 编写测试。最明智的做法是什么?

我考虑过的一些方法:

  • 将函数移出实用程序文件,并在一些标准 Python 测试库中为该实用程序文件编写测试。可能是最好的选择,但这意味着并非所有代码都在笔记本中可见。
  • 使用测试数据在笔记本中写入断言(给笔记本添加噪音)。
  • 使用专门的 Jupyter 测试来测试单元格的内容(不要认为这行得通,因为单元格的内容会发生变化)。

最佳答案

Python 标准测试工具,例如 doctestunittest , 可以直接在笔记本中使用。

文档测试

在文档字符串中包含函数和测试用例的笔记本单元:

def add(a, b):
    '''
    This is a test:
    >>> add(2, 2)
    5
    '''
    return a + b

运行文档字符串中所有测试用例的笔记本单元(笔记本中的最后一个):

import doctest
doctest.testmod(verbose=True)

输出:

Trying:
    add(2, 2)
Expecting:
    5
**********************************************************************
File "__main__", line 4, in __main__.add
Failed example:
    add(2, 2)
Expected:
    5
Got:
    4
1 items had no tests:
    __main__
**********************************************************************
1 items had failures:
   1 of   1 in __main__.add
1 tests in 2 items.
0 passed and 1 failed.
***Test Failed*** 1 failures.

单元测试

具有功能的笔记本单元:

def add(a, b):
    return a + b

包含测试用例的笔记本单元(笔记本中的最后一个单元)。单元格中的最后一行在执行单元格时运行测试用例:

import unittest

class TestNotebook(unittest.TestCase):
    
    def test_add(self):
        self.assertEqual(add(2, 2), 5)
        

unittest.main(argv=[''], verbosity=2, exit=False)

输出:

test_add (__main__.TestNotebook) ... FAIL

======================================================================
FAIL: test_add (__main__.TestNotebook)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "<ipython-input-15-4409ad9ffaea>", line 6, in test_add
    self.assertEqual(add(2, 2), 5)
AssertionError: 4 != 5

----------------------------------------------------------------------
Ran 1 test in 0.001s

FAILED (failures=1)

调试失败的测试

在调试失败的测试时,在某个时间停止测试用例执行并运行调试器通常很有用。为此,在您希望停止执行的行之前插入以下代码:

import pdb; pdb.set_trace()

例如:

def add(a, b):
    '''
    This is the test:
    >>> add(2, 2)
    5
    '''
    import pdb; pdb.set_trace()
    return a + b

对于这个例子,下次运行 doctest 时,执行将在 return 语句和 Python debugger 之前停止。 (pdb) 将启动。您将直接在笔记本中获得 pdb 提示,这将允许您检查 ab 的值,跨行等。

注意:从 Python 3.7 开始,内置的 breakpoint()可以用来代替 import pdb; pdb.set_trace().

我创建了一个 Jupyter notebook for experimenting使用我刚才描述的技术。你可以试试 Binder

关于python - Jupyter笔记本中的功能单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40172281/

相关文章:

python - 导入模块时发生奇怪的事情

visual-studio-2008 - VSTestHost.exe 已停止工作 - 无法运行单元测试

xcode - 在 Xcode 8 中运行单元测试会导致错误 "could not load inserted library ' .../IDEBundleInjection' 因为找不到图像”

Python多线程单元测试

python - VTK Python 将相机的鼠标控制更改为轨迹球(la Blender、Meshlab、CloudCompare)

python - 如何让 Pip 遵守要求?

python - 如何在 El Capitan 上运行 psycopg2 而不会遇到 libssl 错误

c# - 从单元测试触发 UI 控制事件

javascript - jasmine.stringMatching 方法未定义

testing - Selenium RC 无法测试压缩的 html