Skip to content

Commit

Permalink
Get test execution working (#9)
Browse files Browse the repository at this point in the history
  • Loading branch information
MusicalNinjaDad authored Feb 14, 2025
1 parent 8fe8f1d commit fa2760d
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 6 deletions.
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
## [0.1.0] - 2025-02-14

### Added

- Pytest plugin can collect jupyter notebooks and cells which use the `%%ipytest` magic
- Pytest plugin collects jupyter notebooks and cells which use the `%%ipytest` magic
- Published documentation for `CollectionTree`.

## [0.0.2] - 2025-02-12
Expand Down
2 changes: 1 addition & 1 deletion __pyversion__
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.0.3
0.1.0
6 changes: 4 additions & 2 deletions pytest_ipynb2/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,19 @@ def collect(self) -> Generator[Cell, None, None]:
class Cell(pytest.Module):
"""
A collector for jupyter notebook cells.
`pytest` will recognise these cells as `pytest.Module`s and use standard collection on them as it would any other
python module.
"""

def _getobj(self) -> ModuleType:
notebook = self.stash[ipynb2_notebook]
cellsabove = [source for cellid, source in notebook.getcodecells().items() if cellid < int(self.nodeid)]
othercells = "\n".join(cellsabove)
cellsource = notebook.gettestcells()[int(self.nodeid)]
cellspec = importlib.util.spec_from_loader(f"Cell{self.name}", loader=None)
cell = importlib.util.module_from_spec(cellspec)
exec(cellsource, cell.__dict__) # noqa: S102
exec(f"{othercells}\n{cellsource}", cell.__dict__) # noqa: S102
return cell


Expand Down
2 changes: 1 addition & 1 deletion pytest_ipynb2/pytester_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class CollectionTree:
"""

@classmethod
#TODO(MusicalNinjaDad): #8 Refactor CollectionTree.from_items to be easier to understand.
# TODO(MusicalNinjaDad): #8 Refactor CollectionTree.from_items to be easier to understand.
def from_items(cls, items: list[pytest.Item]) -> Self:
"""Create a CollectionTree from a list of collection items, as returned by `pytester.genitems()`."""

Expand Down
73 changes: 73 additions & 0 deletions tests/test_runtests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
from pathlib import Path
from typing import TYPE_CHECKING

import pytest

from pytest_ipynb2.pytester_helpers import CollectedDir, ExampleDir

if TYPE_CHECKING:
from pytest_ipynb2.plugin import Cell


@pytest.mark.parametrize(
["example_dir", "outcomes"],
[
pytest.param(
ExampleDir(
files=[Path("tests/assets/notebook.ipynb").absolute()],
conftest="pytest_plugins = ['pytest_ipynb2.plugin']",
),
{
"passed": 2,
},
id="Simple Notebook",
),
pytest.param(
ExampleDir(
files=[Path("tests/assets/notebook_2tests.ipynb").absolute()],
conftest="pytest_plugins = ['pytest_ipynb2.plugin']",
),
{
"passed": 3,
},
id="Notebook 2 test cells",
),
pytest.param(
ExampleDir(
files=[
Path("tests/assets/notebook_2tests.ipynb").absolute(),
Path("tests/assets/notebook.ipynb").absolute(),
],
conftest="pytest_plugins = ['pytest_ipynb2.plugin']",
),
{
"passed": 5,
},
id="Both notebooks - unsorted",
),
],
indirect=["example_dir"],
)
def test_runtests(example_dir: CollectedDir, outcomes: dict):
results = example_dir.pytester_instance.runpytest()
results.assert_outcomes(**outcomes)


@pytest.mark.parametrize(
"example_dir",
[
pytest.param(
ExampleDir(
files=[Path("tests/assets/notebook.ipynb").absolute()],
conftest="pytest_plugins = ['pytest_ipynb2.plugin']",
),
id="Simple Notebook",
),
],
indirect=True,
)
def test_cellmodule_contents(example_dir: CollectedDir):
cell: Cell = example_dir.items[0].parent
expected_attrs = ["x", "y", "adder", "test_adder", "test_globals"]
public_attrs = [attr for attr in cell._obj.__dict__ if not attr.startswith("__")] # noqa: SLF001
assert public_attrs == expected_attrs

0 comments on commit fa2760d

Please sign in to comment.