opencode-config/docs/decisions/044-pr-102-e2e-memory-tests.md
Sergey 9d1373a51b
test(memory): E2E coverage for 4 scenarios (#102)
* test(memory): E2E coverage for 4 scenarios

* docs(handoff): set PR number

* style(memory): ruff format e2e test

* docs(project-map): add test_memory_tools_e2e.py after PR#102

---------

Co-authored-by: opencode-agent <agent@opencode.local>
2026-07-27 01:32:53 +03:00

2.9 KiB
Raw Blame History

ADR-044: E2E test structure for hybrid memory (subprocess-based)

Статус

Accepted (2026-07-26)

Контекст

Гибридная память (keyword ripgrep + semantic Python OpenRouter) после рефактора (PR #100 lazy-init, PR #101 5 TS tools) нуждалась в E2E гарантии стабильности. Существующие unit-тесты (test_search.py, test_index.py, test_embedder.py) мокают embed_texts — не проверяют реальный keyword path (ripgrep subprocess) и не проверяют fallback при реальном падении OpenRouter.

Нужно было решить: как структурировать E2E тесты — через TS tools (spawnSync TS plugin) или напрямую через Python src.memory + ripgrep subprocess.

Решение

Тесты вызывают Python src.memory (search/index) и ripgrep напрямую через subprocess.run из Python тестов, НЕ через TS tools. Причины:

  1. Изоляция — тесты проверяют Python backend + ripgrep отдельно от TS обёртки. TS tool — тонкий слой spawnSync, его логика (scoring, merge) уже покрыта unit-тестами плагина.
  2. Простота env — Python subprocess принимает env dict напрямую, можно удалить OPENAI_BASE_URL (сценарий 1) или подменить OPENAI_API_KEY (сценарий 3) без манипуляций с process.env в TS.
  3. Скорость — 4 теста прошли за 34с с реальным OpenRouter. TS tool добавил бы накладные расходы на import/compile.
  4. Переиспользование паттернаtest_embedder_live.py уже использует @pytest.mark.skipif(not RUN_LIVE) — тот же маркер на module level.

Каждый сценарий создаёт tmp memoryDir через tmp_path fixture, пишет .md с уникальным термином zzuniqtestterm42, вызывает _reindex (poll reindex.log) и _semantic_search/_rg_search, сравнивает результаты.

Альтернативы

  • TS tool через subprocess (npx opencode-tool memory-search) — отклонено: сложно передать кастомный env, медленнее, тестирует TS обёртку а не backend.
  • pytest + import src.memory in-process — отклонено: embed_texts читает os.environ при вызове (lazy после PR #100), но monkeypatch на module-level ломает параллельные тесты. Subprocess даёт полную изоляцию env per-test.
  • Mock OpenRouter через httpx mock — отклонено: цель E2E = реальный API, мок = unit-тест (уже есть test_embedder.py).