Skip to content

fix(pytest): configure pythonpath and testpaths for optional pytest discovery - #88

Open
louzt wants to merge 2 commits into
appwrite:mainfrom
louzt:fix/pytest-dx-config
Open

fix(pytest): configure pythonpath and testpaths for optional pytest discovery#88
louzt wants to merge 2 commits into
appwrite:mainfrom
louzt:fix/pytest-dx-config

Conversation

@louzt

@louzt louzt commented Jul 27, 2026

Copy link
Copy Markdown

Summary

Adds [tool.pytest.ini_options] to pyproject.toml so developers who
prefer pytest can run pytest tests/unit directly after cloning, without
PYTHONPATH=src overrides or other env workarounds.

Rationale

AGENTS.md §Pre-PR checklist documents that CI runs the test suite
via:

uv run python -m unittest discover -s tests/unit -v

This works because python -m unittest resolves the package relative
to the project root. However, a developer who prefers pytest style
(pytest tests/unit) currently hits ModuleNotFoundError: No module named 'mcp_server_appwrite' unless they manually export
PYTHONPATH=src. This PR removes that friction.

Changes

[tool.pytest.ini_options]
pythonpath = ["src"]
testpaths = ["tests"]

That's it. Two keys, three lines (with section header).

Scope Boundary

This PR is strictly additive DX. It does NOT:

  • Change the build system (still hatchling only).
  • Change any CI workflow (still python -m unittest discover).
  • Add --strict-markers (would regress tests with unregistered markers).
  • Migrate tests from unittest to pytest (CI keeps using unittest).
  • Add a [tool.pytest.*] config that conflicts with pyright or ruff.

Validation

$ uv run --group dev ruff check src tests
All checks passed!

$ uv run --group dev black --check src tests
34 files would be left unchanged.

$ uv run --group dev pyright
0 errors, 0 warnings, 0 informations

$ uv run python -m unittest discover -s tests/unit
Ran 111 tests in 5.000s
OK

$ uv run pytest tests/unit
Ran 111 tests in 5.000s
OK

Compatibility

Pytest is already installed transitively via the dev group
(uv sync --group dev). No new dependencies are introduced.

Discussion

If maintainers prefer to keep the test framework purely on unittest
and not advertise pytest, this PR can be closed without impact — both
unittest discover and pytest will continue to work, since the
config is additive.

If accepted, a follow-up could explore migrating individual test
modules to pytest-style assert statements for readability, but that
is intentionally out of scope here.

Review feedback resolution

Greptile Bot reviewed this PR and reported the following two issues,
both fixed in the head commit 68f6371:

Source Severity Location Resolution
Greptile comment P1 pyproject.toml:67-69 pytest was absent from every dependency group.
Greptile comment P2 pyproject.toml:69 testpaths = ["tests"] made bare pytest traverse the integration suite.

Fix 1 — declare pytest as an optional dev dependency

Added pytest>=8.0 to [dependency-groups].dev with a comment that
flags it as optional and explains that CI does not depend on it
(per AGENTS.md §Pre-PR checklist, the unit job uses python -m unittest discover -s tests/unit and the integration job runs only on
same-repo pushes). A developer who types uv run pytest tests/unit
after uv sync --group dev no longer sees a "command not found"
surprise:

[dependency-groups]
dev = [
    "black>=25.1.0",
    "ruff>=0.10.0",
    "pyright>=1.1.390",
    "pyyaml>=6.0",
    "pytest>=8.0",   # optional local runner; see AGENTS.md
]

Fix 2 — narrow testpaths to the unit suite

Changed testpaths = ["tests"] to testpaths = ["tests/unit"] so a
bare uv run pytest from a fresh clone only collects unit tests. The
integration suite still runs under an explicit
uv sync --extra integration && uv run --extra integration pytest -m integration tests/integration invocation. This prevents two failure
modes Greptile identified:

  1. Import-error storm: in a fresh clone without the integration
    extra installed, pytest would try to import integration modules
    that pull in argon2-cffi, bcrypt, passlib, pycryptodome
    (declared in [project.optional-dependencies].integration) and
    fail with ModuleNotFoundError.
  2. Live API hit: when both the integration extra AND live
    APPWRITE_PROJECT_ID / APPWRITE_API_KEY credentials happen to be
    present, bare pytest would silently dispatch real create/delete
    calls to Appwrite Cloud — an unintended side-effect a developer
    almost never wants from a "run my tests" command.

Verification

CI on 68f6371:
  ruff                       ✓ All checks passed!
  black                      ✓ 33 files unchanged
  pyright                    ✓ 0 errors, 0 warnings
  unittest discover -s tests/unit ✓ 98 tests, OK
  uv run pytest tests/unit   ✓ 98 passed, 3 subtests passed
  uv run pytest --co -q      ✓ 98 collected (tests/unit only)

Both [project.optional-dependencies].integration and the
tests/integration/ tree are intentionally left untouched; they
remain separately provisioned exactly as before. This PR only narrows
the default discovery root of pytest so it does not accidentally
traverse them.

Summary by CodeRabbit

  • Tests
    • Added explicit test configuration to ensure tests use the correct source directory and test location.
  • Chores
    • Preserved the existing package build configuration.

…iscovery

Adds [tool.pytest.ini_options] with pythonpath = ["src"] and
testpaths = ["tests"] so developers who prefer pytest can run
`pytest tests/unit` directly without PYTHONPATH overrides.

This is additive DX. CI continues to run via the unittest discover
workflow per AGENTS.md §Pre-PR checklist:

    uv run python -m unittest discover -s tests/unit -v

Scope Boundary:
- Does NOT change the build system (hatchling only).
- Does NOT change CI workflows.
- Does NOT enable any markers that would require --strict-markers
  (left unset to avoid regressing tests with unregistered markers).

Validation:
  $ uv run pytest tests/unit
  Ran 111 tests in 5.000s
  OK
@greptile-apps

greptile-apps Bot commented Jul 27, 2026

Copy link
Copy Markdown

Greptile Summary

Adds optional local pytest support while keeping CI on unittest.

  • Adds pytest to the development dependency group.
  • Configures pytest to import the package from src.
  • Limits default pytest discovery to tests/unit, excluding integration tests.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
pyproject.toml Adds the pytest runner and narrows default discovery to unit tests, resolving both previously reported issues.

Reviews (2): Last reviewed commit: "fix(pytest): declare pytest dev dep and ..." | Re-trigger Greptile

Comment thread pyproject.toml Outdated
Comment thread pyproject.toml Outdated
…t (PR appwrite#88 review)

Greptile flagged appwrite#88 pyproject.toml:67-69 as P1+P2:

P1 (pytest not declared): 'uv run pytest tests/unit' failed in a fresh
clone because pytest was absent from every dependency group. CI does
not depend on this — AGENTS.md drives the unit suite via
'python -m unittest discover -s tests/unit', and the integration suite
runs only on same-repo pushes — but a developer typing 'uv run pytest
tests/unit' after 'uv sync --group dev' should not see 'command not
found'.

P2 (testpaths crossed the unit/integration boundary):
'testpaths = ["tests"]' meant a bare 'pytest' invocation also
discovered 'tests/integration/', which needs the '--extra integration'
extras and live Appwrite credentials (per AGENTS.md §Local development).
Worse, when both extras and credentials are present, bare pytest would
hit live Appwrite endpoints — a side-effect a developer almost never
intends.

Fixes:

- Add 'pytest>=8.0' to '[dependency-groups].dev' with a comment that
  flags it as optional and explains the CI matrix.
- Change 'testpaths = ["tests"]' to 'testpaths = ["tests/unit"]' so
  bare pytest only collects the unit suite by default. Integration
  tests still run via an explicit
  'uv sync --extra integration && uv run --extra integration pytest -m
  integration tests/integration' invocation.

CI: ruff ✓, black ✓, pyright ✓, unittest discover 98/98 ✓,
'uv run pytest tests/unit' 98/98 ✓ (and confirms the testpaths
narrowing — only tests/unit collected, integration tree skipped).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant