对Jupyter笔记本中的功能进行单元测试?

Ric*_*ard 30 python testing unit-testing reproducible-research jupyter

我有一台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
Run Code Online (Sandbox Code Playgroud)

我想为construct_url和写测试scrape_url.什么是最明智的方法呢?

我考虑过的一些方法:

  • 将函数移出到实用程序文件中,并在某个标准Python测试库中为该实用程序文件编写测试.可能是最好的选择,但这意味着并非所有代码都在笔记本中可见.
  • 使用测试数据在笔记本电脑内写入断言(为笔记本添加噪声).
  • 使用专门的Jupyter测试来测试细胞的内容(不要认为这是有效的,因为细胞的含量会发生变化).

Ser*_*kov 34

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

文档测试

具有函数的笔记本单元格和文档字符串中的测试用例:

def add(a, b):
    '''
    This is a test:
    >>> add(2, 2)
    5
    '''
    return a + b
Run Code Online (Sandbox Code Playgroud)

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

import doctest
doctest.testmod(verbose=True)
Run Code Online (Sandbox Code Playgroud)

输出:

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.
Run Code Online (Sandbox Code Playgroud)

单元测试

具有功能的笔记本电池:

def add(a, b):
    return a + b
Run Code Online (Sandbox Code Playgroud)

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

import unittest

class TestNotebook(unittest.TestCase):

    def test_add(self):
        self.assertEqual(add(2, 2), 5)


unittest.main(argv=[''], verbosity=2, exit=False)
Run Code Online (Sandbox Code Playgroud)

输出:

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)
Run Code Online (Sandbox Code Playgroud)

调试失败的测试

在调试失败的测试时,在某些时候停止测试用例执行并运行调试器通常很有用.为此,请在要执行停止的行之前插入以下代码:

import pdb; pdb.set_trace()
Run Code Online (Sandbox Code Playgroud)

例如:

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

对于此示例,下次运行doctest时,执行将在return语句和Python调试器(pdb)启动之前暂停.您将直接在笔记本中获得一个pdb提示符,这将允许您检查和的值,ab跨越行等.

我创建了一个Jupyter笔记本,用于试验我刚才描述的技术.


Roh*_*jay 11

我是testbooknteract下的一个项目)的作者和维护者。它是用于在 Jupyter Notebooks 中测试代码的单元测试框架。

testbook解决了您提到的所有三种方法,因为它允许将 Jupyter Notebooks 作为.py文件进行测试。

这是使用 testbook 编写的单元测试示例

考虑 Jupyter Notebook 中的以下代码单元:

def func(a, b):
    return a + b
Run Code Online (Sandbox Code Playgroud)

您将使用 Python 文件中的 testbook 编写单元测试,如下所示:

import testbook


@testbook.testbook('/path/to/notebook.ipynb', execute=True)
def test_func(tb):
    func = tb.ref("func")

    assert func(1, 2) == 3
Run Code Online (Sandbox Code Playgroud)

让我们知道 testbook 是否对您的用例有帮助!如果没有,请随时在GitHub 上提出问题:)


试卷特点

  • 为 Jupyter Notebooks 编写常规单元测试
  • 在单元测试之前执行所有或某些特定单元格
  • 在多个测试中共享内核上下文(使用 pytest 固定装置)
  • 将代码注入 Jupyter 笔记本
  • 适用于任何单元测试库 - unittest、pytest 或nose

链接

PyPI GitHub 文档


Ben*_*kin 6

运行单个测试用例:

from unittest import TestCase, TextTestRunner, defaultTestLoader
class MyTestCase(TestCase):
    def test_something(self):
        self.assertTrue(True)
TextTestRunner().run(defaultTestLoader.loadTestsFromTestCase(MyTestCase))
Run Code Online (Sandbox Code Playgroud)


Mic*_*l D 5

在我看来,在 Jupyter notebook 中进行单元测试的最佳方法是以下包:https : //github.com/JoaoFelipe/ipython-unittest

包文档中的示例:

%%unittest_testcase
def test_1_plus_1_equals_2(self):
    sum = 1 + 1
    self.assertEqual(sum, 2)

def test_2_plus_2_equals_4(self):
    self.assertEqual(2 + 2, 4)

Success
..
----------------------------------------------------------------------
Ran 2 tests in 0.000s

OK
Run Code Online (Sandbox Code Playgroud)