-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
FEATURE: run pytest in Jupyter notebooks #2268
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
Comments
i had prior discussions about enabling this with @userzimmermann |
For reference, there are a few plugins that run tests on full .ipynb files ,e.g. # Jupyter cell
%%pytest
def test_my_stuff():
assert 42 == 42 His implementation appears concise. However, rather than inserting multiple cell magics throughout the notebook in various test cells, it would be favorable to initiate the Ideas are welcome. Many thanks. |
@pylang, another shortcoming in ipython_pytest compared to my fork of ipython_nose (original by @taavi) is that I couldn't find a way to run tests in-process and inject the notebook's environment into the test. In other words, what This approach works great in With I tried to study |
As @RonnyPfannschmidt pointed out I am also - and still ;) - very interested in this feature! I will also try to come up with some concept asap... Or we try to work on some concept together somehow... Sharing effort to make it reasonable ;) |
Is the Assertion rewriter that introspects and annotates the exceptions thrown by the tests available? |
AFAIK the assertion rewriter only works on .py files, it might be possible to refactor its logic to support rewriting the assertions transparently inside Jupyter notebooks |
Just for the record, this solution seems to work: |
I am the author of For reference: %%run_pytest
def test_foo():
assert [] == [1, 2, 3] If there is interest in integration of this functionality in |
@pylang, for testing a whole notebook you could use:
|
Hi @chmp, thanks for chipping in! I see that you are using the https://github.com/chmp/ipytest/blob/master/ipytest/magics.py#L43 If you managed to use that successfully, I believe that's the way to go. It also doesn't need any changes to pytest itself. 👍 |
While I have to admit, that it did seem a bit hacky to use pytest internals, it works quite nicely in practice. The hardest part was getting stack traces to work :) (I typed up the details here). I have been using pytest from inside notebooks pretty regulary the last couple of months and did not run into any problems so far. Edit: I changed the implementation. It is now using the |
FYI: link is now a 404. |
Perhaps this should be a new issue, but I noticed the new subtests plugin. This part caught my attention: ...
with self.subTest("custom message", i=i):
self.assertEqual(i % 2, 0) The result is pytest-flavored tracebacks by way of context managers. Might it be possible to make a context manager that hooks into the traceback rewriter? Example: with pytest.assertions:
def test_a():
assert 1
assert 0
test_a() ================================== FAILURES ===================================
___________________________________ test_a ____________________________________
def test_a():
assert 1
> assert 0
E assert 0
Having a way to hook into the assertion writer, decoupled from the test runner, could more generally extend pytest-flavored tracebacks to interactive Python, i.e. the REPL, jupyter notebooks (not solely |
Having worked a bit on this issue, my guess is a context manager will not work, as you do need to to inject the rewriter before the cell is executed. Therefore it's most likely going to be either a magic or spreading out the code between cells. If you're happy to install # cell 1
import ipytest
ipytest.config(magics=True)
# cell 2
%%rewrite_asserts
def test_a():
assert 1
assert 0 or # cell 1
import ipytest
ipytest.config(rewrite_asserts=True)
# cell 2
def test_a():
assert 1
assert 0
# cell 3
ipytest.config(rewrite_asserts=False) In both cases, the asserts will be pytest flavoured. You can execute If installing As an aside: I fundamentally changed the way rewrites work. The implementation is now much more lightweight by using jupyter's |
Stumbled upon similar case. But my environment is a bit special - i am working with databricks and they have their custom "notebooks" based on ipython. So, |
Hi, is this still under consideration? Being able to run pytest in jupyter out of the box would be fantastic. There seem to be some other packages which aim to do this, but it is difficult to see which ones are actively maintained! |
@sashgorokhov Looks quite neat! Is there any interest to try and integrate it into pytest? |
@Chris-hughes10 pytest is not the place for hacky-whacky kind of code like mine 🌝 |
its a neat hack to give some base ideas it would be much more neat if note books could have fixture cells, test cells, and a runtest magic, the idea being that inside one notebook you can run the tests, but youd also be able to collect and run them with pytest that however requires far more work to be attainble |
Is this something that you would be interested in adding to the roadmap? Assuming that people are interested in contributing |
I don't think this belongs in the pytest core. It should be a pytest plugin, a Jupyter plugin, or perhaps a mixture of the two. Another related project FWIW: testbook |
certainly a mixture - this should be a own plugin, for both jupyter/ipython and pytest enablement for those is still something that might make sense for a roadmap, but i currently cannot commit to help it |
@The-Compiler thanks for the reference, testbook looks like a nice tool to have for testing example content |
Just for reference. For ipytest (still maintained), I moved away from using a module collector plugin and am now inject a fake module into In general, I think most of the functionality to run pytest inside notebooks should be doable with an external package. However, some of the details like parameterize are quite hard-wired to pytest being run from the command line (See here)
Using cells tags for this is afaik pretty much impossible as the kernel does not have access to this information. If you would rely on magics I think all of this functionality is doable. Simply package the impl into a function and then go the usual route of calling pytest. |
To add to the list, I also made a similar plugin: https://pytest-exploratory.readthedocs.io/en/latest/ The goal is to control a pytest session interactively against an existing codebase and do manual testing, rather than writing tests inside a Jupyter notebook, even if it should be possible to support both. It's implemented by executing the pytest hooks through IPython magics. It works but it's quite hacky, and as @chmp mentions there's a need for APIs to support those use-cases. |
closing this as not planned for pytest core - we should open extra issues to create/teste enabling apis |
nose.tools
offers functions for testing assertions, e.g.assert_equal()
. These functions are callable in a Jupyter notebook (REPL) and produce a detailed output if an error is raised. I've looked through the pytest docs, but those relative invocation methods seem to focus on the commandline.I request an interactive,
nose
-like feature in pytest, i.e. invokepytest
in a Jupyter notebook and generate the pytest, detailed output for each cell.The text was updated successfully, but these errors were encountered: