Testing & Environment Requirements¶
Development Environment¶
This project manages conflicting binary dependencies through isolated pixi
environments. We avoid a monolithic environment to prevent version resolution
failures and import-time crashes.
Initial Setup¶
pixi install
Local Development & Editable Installs¶
By default, the rgpycrumbs dispatcher runs scripts using uv run. This enforces strict environment isolation by resolving and fetching a script’s PEP 723 inline dependencies on the fly.
While excellent for reproducibility, this behavior bypasses your local Python environment. If you are actively developing a dependent package (e.g., you installed it locally via pip install -e . or pixi add --editable), uv run will ignore your local edits and fetch the published version instead.
To force rgpycrumbs to use your active environment and respect your editable installs, use the --dev flag:
# Standard execution (Isolated: uv resolves dependencies from scratch)
rgpycrumbs mygroup myscript
# Development execution (Active Env: uses sys.executable, respects editable installs)
rgpycrumbs --dev mygroup myscript
Workflow for Dependent Packages¶
Activate your desired
pixienvironment (e.g.,pixi shell -e test).Install your dependent package in editable mode if not already managed by pixi (e.g.,
pip install -e /path/to/local/dependency).Run your script using the
--devflag to test your local package modifications:rgpycrumbs --dev <group> <script>.
Debugging Execution with Verbose Mode¶
Because the dispatcher dynamically resolves script paths and environment execution contexts (switching between uv run and sys.executable), it can occasionally be helpful to inspect the underlying commands.
Pass the --verbose (or -v) flag to print the fully resolved path to the PEP 723 script and the exact command array being constructed before it is executed.
# Check standard isolated execution
rgpycrumbs --verbose mygroup myscript
# Check local development execution
rgpycrumbs --dev -v mygroup myscript
Testing Guidelines¶
The test suite utilizes custom markers to scope tests to specific environments.
This prevents ModuleNotFoundError during the pytest collection phase.
Adding New Tests¶
When creating a new test file, you must protect the collection phase:
- Define requirements
Add any required external modules to the
ENVIRONMENT_REQUIREMENTSdictionary intests/conftest.py.- Guard imports
Call
skip_if_not_env("marker_name")at the top of your test file. This must occur before you import any package modules that depend on external binaries.- Mark your tests
Assign the corresponding marker to the file or functions.
Example Test Structure¶
import pytest
from tests.conftest import skip_if_not_env
# Guard collection: prevents imports from executing if dependencies are missing
skip_if_not_env("my_marker")
# Imports are now safe to execute
from rgpycrumbs.submodule.logic import core_feature
def test_feature_execution():
assert core_feature() is True
Dispatcher Scripts and Test Markers¶
Scripts under rgpycrumbs/eon/ (and similar groups) declare their own
dependencies via PEP 723 inline metadata. These scripts import heavy packages
(polars, chemparseplot, ase, etc.) at the top level, because uv run resolves
those dependencies before execution.
When writing tests that import these scripts directly (e.g., to test CLI
--help output), the test file must use the corresponding marker (e.g.,
eon, not pure) and the skip_if_not_env guard. Otherwise the top-level
imports will fail during collection in environments that lack the script’s
dependencies.
import pytest
from tests.conftest import skip_if_not_env
skip_if_not_env("eon")
from rgpycrumbs.eon.plt_neb import main as plt_neb_main # noqa: E402
pytestmark = pytest.mark.eon
def test_plt_neb_help(runner):
result = runner.invoke(plt_neb_main, ["--help"])
assert result.exit_code == 0
The pure marker is reserved for tests that depend only on core packages
(numpy, click). The ensure_import and lazy_import tests also run under
pure since they mock all optional dependencies. Never place tests that import
dispatcher scripts under the pure marker.
Note that [all] is a best-effort convenience extra covering pip-installable
optional dependencies only. Conda-only packages (tblite, ovito, ira_mod)
require pixi.
Available Markers & Environments¶
The following markers and their corresponding pixi environments are available:
Marker |
Environment |
Dependencies |
What it tests |
|---|---|---|---|
|
|
|
Core utilities, basetypes, ensureimport |
|
|
|
Structure analysis, alignment |
|
|
|
Fragment detection with tight-binding |
|
|
|
Surface fitting kernels and models |
|
|
|
Polyhedral template matching |
|
|
|
eOn integration, NEB CLI |
|
(requires |
|
IRA matching and RMSD comparison |
Running Tests¶
Execute tests within the specific environment that provides the necessary dependencies:
# Run tests for a specific suite
pixi run -e <env_name> pytest -m <marker_name>
# Examples
pixi run -e test pytest -m pure
pixi run -e test pytest -m align
pixi run -e surfaces pytest -m surfaces
pixi run -e fragments pytest -m fragments