Skip to content

Commit d0975a2

Browse files
authored
WIP: Test: notebooks (#47)
* Conditionally skip when not testing jupyter * Make notebook testing a separate job This should have the nice benefit of no testing examples across the board when not running nbval and * Fix ci build * Glob notebooks * pre-commit: Exclude examples from mypy check * Just exclude examples/conftest.py * See if -s shows the error * TEMP: Skip comparing stderr on CI Just checking if this passes the build * WIP: Try to figure out why pygfx+jupyter has problems Claude thinks this will work? * Ignore all stderr on pygfx Not sure we could do better with the current state of nbval
1 parent 130e6d9 commit d0975a2

4 files changed

Lines changed: 54 additions & 1 deletion

File tree

.github/workflows/ci.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,17 @@ jobs:
8181
sudo apt install -y libegl1-mesa-dev libgl1-mesa-dri libxcb-xfixes0-dev mesa-vulkan-drivers
8282
8383
- name: Install dependencies
84-
run: uv sync --no-dev --group test --extra ${{ matrix.gfx }} --extra ${{matrix.canvas}} ${{ matrix.python-version >= '3.12' && matrix.gfx == 'pygfx' && '--extra imgui' || '' }} ${{ matrix.canvas == 'pyqt6' && '--group testqt' || '' }}
84+
run: uv sync --no-dev --group test --extra ${{ matrix.gfx }} --extra ${{matrix.canvas}} ${{ matrix.python-version >= '3.12' && matrix.gfx == 'pygfx' && '--extra imgui' || '' }} ${{ matrix.canvas == 'pyqt6' && '--group testqt' || '' }} ${{ matrix.canvas == 'jupyter' && '--group testjupyter' || '' }}
8585

8686
- name: Test
8787
shell: bash
8888
run: uv run --no-sync coverage run -p -m pytest -v
8989

90+
- name: Test notebooks
91+
if: matrix.canvas == 'jupyter'
92+
shell: bash
93+
run: uv run --no-sync coverage run -p -m pytest -v --nbval examples/*.ipynb
94+
9095
- name: Upload coverage
9196
uses: actions/upload-artifact@v6
9297
with:

.pre-commit-config.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ repos:
4141
types_or: [python, pyi]
4242
require_serial: true
4343
entry: uv run mypy
44+
# Prevents mypy from complaining about multiple conftest modules
45+
# this one is the least necessary to check
46+
exclude: "^examples/conftest\\.py$"
4447
- id: pyright
4548
name: pyright
4649
language: system

examples/conftest.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
"""Pytest setup for notebook tests."""
2+
3+
from typing import TYPE_CHECKING
4+
5+
from nbval.plugin import IPyNbCell # type: ignore
6+
7+
if TYPE_CHECKING:
8+
import pytest
9+
10+
11+
def pytest_collection_modifyitems(
12+
session: "pytest.Session", config: "pytest.Config", items: "list[pytest.Item]"
13+
) -> None:
14+
"""Add sanitizers to Notebook tests."""
15+
for item in items:
16+
# For each notebook cell being tested...
17+
if not isinstance(item, IPyNbCell):
18+
continue
19+
try:
20+
# FIXME: On pygfx some lines are printed to stderr that we don't want to
21+
# compare. Ideally we could ignore ONLY these lines, e.g.
22+
# libEGL warning: DRI3 error: Could not get DRI3 device
23+
# libEGL warning: Ensure your X server supports DRI3 to get accelerated...
24+
# Unable to find extension: VK_EXT_physical_device_drm
25+
import pygfx # noqa: F401
26+
27+
item.parent.skip_compare += ("stderr",) # pyright: ignore
28+
except ImportError:
29+
pass
30+
31+
# Add the following (regex) sanitations...
32+
# (Note that both the expected and actual cell outputs will be sanitized)
33+
item.parent.sanitize_patterns.update( # pyright: ignore
34+
{
35+
# -- Convert all jupyter canvases to the same (pygfx) class name -- #
36+
r"CanvasBackend": "JupyterRenderCanvas",
37+
# -- Convert canvas sizes to integers (vispy uses floats) -- #
38+
r"(\d+)\.0px": r"\1px", # e.g. 600.0px -> 600px
39+
# -- Normalize div snapshot ids (unique to each run) -- #
40+
r"snapshot-[a-f0-9]+": "snapshot-XXXXX",
41+
# -- Normalize canvas data (within the img tag) -- #
42+
r"data:image/png;base64,[A-Za-z0-9+/=]+": "data:image/png;base64,XXXXX",
43+
}
44+
)

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ imgui = [
7777
[dependency-groups]
7878
test = ["pytest>=8", "pytest-cov>=6"]
7979
testqt = [{ include-group = "test" }, "pytest-qt >=4.4"]
80+
testjupyter = [{ include-group = "test" }, "nbval"]
8081
docs = [
8182
"mike>=2.1.3",
8283
"mkdocs>=1.6.1",

0 commit comments

Comments
 (0)