The functions that grab the cells containing tests (filtering with potential flags) and execute them

Everything that is not an exported cell is considered a test, so you should make sure your notebooks can all run smoothly (and fast) if you want to use this functionality as the CLI. You can mark some cells with special flags (like slow) to make sure they are only executed when you authorize it. Those flags should be configured in your settings.ini (separated by a | if you have several of them). You can also apply flags to one entire notebook by using the all option of the test flag, e.g. %nbdev_slow_test all, in code cells.

If tst_flags=slow|fastai2 in settings.ini, you can:

  • mark slow tests with the %nbdev_slow_test flag
  • mark tests that depend on fastai2 with the %nbdev_fastai2_test flag.

Detect flags

The following functions detect the cells that should be excluded from the tests (unless their special flag is passed).

get_all_flags[source]

get_all_flags(cells)

Check for all test flags in cells

nb = read_nb("04_test.ipynb")
assert get_all_flags(nb['cells']) == set()

get_cell_flags[source]

get_cell_flags(cell)

Check for any special test flag in cell

test_eq(get_cell_flags({'cell_type': 'code', 'source': "%nbdev_hide\n%nbdev_fastai2_test\n"}), ['fastai2'])
test_eq(get_cell_flags({'cell_type': 'code', 'source': "%nbdev_hide\n"}), [])

Testing a notebook

class NoExportPreprocessor[source]

NoExportPreprocessor(*args, **kwargs) :: ExecutePreprocessor

An ExecutePreprocessor that executes cells that don't have a flag in flags

test_nb[source]

test_nb(fn, flags=None)

Execute tests in notebook in fn with flags

class TestCallbacks:
    def begin_test_nb(self, nb, file_name, flags):
        self.begin_test_nb_data=dict(nb=nb,file_name=file_name,flags=flags)
        return nb
    def after_test_nb(self, file_name):
        self.after_test_nb_data=dict(file_name=file_name)
test_callbacks=TestCallbacks()
call_cb('this makes sure nbdev_callbacks is loaded from the right place')
import nbdev_callbacks
original_callbacks=nbdev_callbacks.begin_test_nb,nbdev_callbacks.after_test_nb
try:
    nbdev_callbacks.begin_test_nb=test_callbacks.begin_test_nb
    nbdev_callbacks.after_test_nb=test_callbacks.after_test_nb
    assert not hasattr(test_callbacks,'begin_test_nb_data')
    expected_file_name,expected_flags='../test/single-cell-index.ipynb',['slow','cuda']
    test_nb(expected_file_name,expected_flags)
    assert len(test_callbacks.begin_test_nb_data['nb']['cells']) == 1
    assert test_callbacks.begin_test_nb_data['file_name'] == expected_file_name
    assert test_callbacks.begin_test_nb_data['flags'] == expected_flags
    assert test_callbacks.after_test_nb_data['file_name'] == expected_file_name
finally:
    nbdev_callbacks.begin_test_nb,nbdev_callbacks.after_test_nb=original_callbacks
---------------------------------------------------------------------------
FileNotFoundError                         Traceback (most recent call last)
<ipython-input-7-1f8e42f6c306> in <module>
     14     assert not hasattr(test_callbacks,'begin_test_nb_data')
     15     expected_file_name,expected_flags='../test/single-cell-index.ipynb',['slow','cuda']
---> 16     test_nb(expected_file_name,expected_flags)
     17     assert len(test_callbacks.begin_test_nb_data['nb']['cells']) == 1
     18     assert test_callbacks.begin_test_nb_data['file_name'] == expected_file_name

~/git/nbdev/nbdev/test.py in test_nb(fn, flags)
     53     if flags is None: flags = []
     54     try:
---> 55         nb = read_nb(fn)
     56         nb = call_cb('begin_test_nb', nb, fn, flags)
     57         for f in get_all_flags(nb['cells']):

~/git/nbdev/nbdev/export.py in read_nb(fname)
     21 def read_nb(fname):
     22     "Read the notebook in `fname`."
---> 23     with open(Path(fname),'r', encoding='utf8') as f: return nbformat.reads(f.read(), as_version=4)
     24 
     25 # Cell

FileNotFoundError: [Errno 2] No such file or directory: '../test/single-cell-index.ipynb'