This guide contains questions that were submitted to our survey on testing.
This guide covers:¶
What are the best practices to test a plugin with multiple sequential steps?¶
e.g. Is it ok to rely on the “results” of a test to run the next test or should they all be fully independent?
Ideally, aim for unit testing.
Tests should not pass/fail together.
Use fixtures to provide a test with inputs, even if you have to make them up.
Use mocks (mock-ups) to assert that specific calls are made, without necessarily caring about what happens after that call is made.
This is definitely an art form. It takes time. Be patient.
How do you test widgets, the napari viewer, graphical user interfaces, and Qt in general?¶
Try not to!
You should generally trust that a button click (for example) will call your callback and focus on testing that your callback does what it’s supposed to do given that it gets called following some UI interaction.
However: If you have a scenario where you are actually creating a complicated widget directly in Qt, see
pytest-qtfor lots of tips, specifically
Oftentimes, this comes down to knowing and/or learning the Qt API really well.
Please see also the In-depth guide to plugin testing.
How to find the different signals or slots?¶
Question: How can we find the different signals/slots we can connect callbacks to as the user interacts with the core napari interface e.g. creating/editing/deleting a
Granted, this is a work in progress.
For example, these events are emitted when the user interacts with the layer list:
Viewer.layers.events.inserted Viewer.layers.events.removed Viewer.layers.events.moved Viewer.layers.events.changed Viewer.layers.events.reordered
Getting an event when the user is editing the data inside a
shapes layer (outside of the GUI interface) is complicated, because the user will be directly editing the native array object.
How do you avoid github tests failing?¶
First make sure all your tests are passing locally.
After that, it’s complicated. More background or context is needed to answer this question.
How do you make a process cancellable?¶
Question: How do you make a process cancellable to interrupt a method that is running in a for loop, for example?
In single-threaded python, use
In multithreaded python, there are many different patterns. Consider using a generator-based thread worker.
Are there testing environments in napari?¶
Answer: Napari does not create or otherwise manage environments.
Introduction to npe2? Migrating to new plugin architecture?¶
The primary difference is in how plugins are discovered:
npe1 used decorators, requiring module import.
npe2 uses static manifests (
napari.yaml), describing contributions without requiring import.
See also the Your First Plugin tutorial
What is the optimal setup to quickly iterate in widget development?¶
Create a script that will start napari and load your widget without any UI interaction.
Don’t test as a plugin. Start by directly calling
viewer.window.add_dock_widgetwith a manually created widget.
Familiarize yourself with the IPython auto-reload features.
watchmedofrom watchdog. This will monitor a file/directory for changes, and re-run a command each time (which is why step #1 is also useful).
Other guides in this series:¶
This is the last guide in this series.