-
Notifications
You must be signed in to change notification settings - Fork 35
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add automatic tests with IPython notebooks #7
Comments
One way to do this, is to use a script like this: https://github.com/paulgb/runipy A disadvantage here is that you have to manually look at the notebooks to see if everything went fine. Another way would be to define unit tests in an ipy-notebook and run them from the command line (e.g., using py.test https://pypi.python.org/pypi/pytest-ipynb). However, I'm not sure if that works with the magics etc. |
I think that would be the best solution. I'm sure we can find a way to make the magic commands work (see e.g. this class). The idea would be to loop over all input cells, execute the code using the InteractiveShell, capture the output, and compare the output with the expected output stored in the |
Interesting idea! But comparing cell output to previously generated output may break when minor changes are made (could also happen when minor changes to external libraries are made?). Say we generate a plot and some default in |
It's true that comparing the base64-encoded plots would not be very robust. Maybe at first we could just compare text output? WDYM exactly by inserting assert/throw errors? |
Example: cell 1 %%cache test.pkl a
a=[i for i in range(10000)] cell 2 import ipycache
try:
a=ipycache.load_vars('./test.pkl', ['a'])
except:
raise CustomErrorThatTellsUsSomething Then run all the cells (from the command line in the IPython Kernel) and catch any raised error and report it as usual. |
OK I see. That's a possibility indeed. Maybe it would be worth encapsulating the code in cell 2 in some private testing function like Also, I think what you describe is rather close to the unit tests that already exist. We could definitely do that, but I think another sort of notebook-based test would be useful as well. You would have an actual example notebook that would only contain user-exposed commands (so basically just Something roughly like this:
# cell 1
%%cache test.pkl a
print("Computing...")
a=[i for i in range(10000)]
# cell 2
print(len(a))
nb = Notebook('example.ipynb')
nb.run_all()
assert check_nb_outputs(nb, ['Computing...', '10000'])
nb.run_all()
assert check_nb_outputs(nb, ['', '10000']) |
Actually, your second test should produce exactly the same output, i.e., The difference between what I suggested and the tests we currently have is that the magic is directly run through ipython's magic interface instead of the mock functions used in Anyway, we could of course mix the approaches: since the output of the cell is always stored in io=ipycache.load_vars('./test.pkl', ['_captured_io'])
assert check_cell_output(io['stdout'].getvalue(), 'Computing...') after having run the cell. That would also decouple testing logic from ipython-notebook code (but actually, I would prefer to run the tests in the NB because it's easier to develop and run). |
Ha I had forgotten that! I'm wondering whether that's a good behavior...? Seeing I do agree that testing logic should be decoupled from the notebook. That being said, having minimal assertions in the notebooks would be fine as long as these are just a couple of lines of code demonstrating what would be expected from normal behavior. Then we could have an "examples" folder with some notebooks demonstrating how ipycache works, and these examples would also be tested by the testing suite (like "doctests" in a way). |
Ok, but how do we define if the notebook passes the test? In a %%cache test.pkl a
print("Computing...")
a=[i for i in range(10000)]
"""
#doctest
assert len(a)==10000
assert os.path.exists('test.pkl')
""" |
Why not just putting this doctest code in the next cell? We say that the test fails if an assertion is raised during the notebook execution, otherwise it passes. |
I added a |
FYI I just found this: https://github.com/bollwyvl/nosebook |
No description provided.
The text was updated successfully, but these errors were encountered: