Skip to content
ocx
install

Test against a pinned tool in pytest

Give each test a locked project and run a pinned tool inside it, without installing the tool on the test machine. This page follows the “test against a pinned tool in pytest” need from the docs use-case note.

You need pytest, the SDK, and an ocx binary found through PATH, OCX_SDK_EXE or bootstrap.ensure().

Put the setup in one plain function. It writes an ocx.toml, locks it and returns the Project handle:

import tempfile
from pathlib import Path
from ocx_sdk import Ocx, Project
def make_project(root: Path, body: str) -> Project:
(root / "ocx.toml").write_text(body)
project = Ocx().project(root)
project.lock()
return project
project = make_project(Path(tempfile.mkdtemp()), '[tools]\ntask = "ocx.sh/go-task/task:3"\n')
assert project.exec(["task", "--version"]).exit_code == 0

The SDK’s own contract suite builds its projects the same way in tests/contract/conftest.py.

# illustrative: a fixture only runs under pytest, and its body is the factory above.
import pytest
from ocx_sdk import Ocx, Project
@pytest.fixture(scope="session")
def ocx() -> Ocx:
return Ocx()
@pytest.fixture
def project(ocx: Ocx, tmp_path) -> Project:
(tmp_path / "ocx.toml").write_text('[tools]\ntask = "ocx.sh/go-task/task:3"\n')
handle = ocx.project(tmp_path)
handle.lock()
return handle
def test_task_runs(project: Project) -> None:
assert project.exec(["task", "--version"]).exit_code == 0

Build the Ocx handle once per session. It is frozen and safe to share. Use tmp_path for the project so tests cannot see each other’s lock files.

Continues on Test against a pinned tool in pytest: Keep the test hermetic.