Page MenuHomePhabricator
Paste P93884

(An Untitled Masterwork)
ActivePublic

Authored by EBernhardson on Jun 4 2026, 6:47 PM.
Project Tags
None
Referenced Files
F86648974: raw-paste-data.txt
Jun 4 2026, 6:47 PM
Subscribers
None
## Execution & Testing
* Authoring tests: follow docs/agents/writing-tests.md (base classes, factory helpers, fixture conventions).
* Run Unit Tests: Execute tests locally using the following example command: ./run-unit-tests.sh extensions/CirrusSearch/tests/phpunit/unit/Dispatch/SemanticSearchQueryRouteTest.php
* API-Centric Testing: Focus test cases on public APIs. Ensure the surface area of the implementation is verified under various edge cases and assumptions.
* Meaningful Coverage: Prioritize the verification of functional correctness over 100% line coverage. Tests should demonstrate that the contract of the public API is honored.
## PHPUnit Test Runner Mechanics (`run-unit-tests.sh`)
* The script runs phpunit inside the `mediawiki` docker container. Pass paths relative to the MediaWiki core root, e.g. `extensions/CirrusSearch/tests/phpunit/...`. The container path `/var/www/html/w` maps to the host core checkout (e.g. `~/git/gerrit/mediawiki/core`); translate container paths in stack traces accordingly.
* Test layers: unit (`tests/phpunit/unit/`) has no DB or OpenSearch and runs without MediaWiki settings; integration (`tests/phpunit/integration/`) has a real DB but no OpenSearch and needs `PHPUNIT_WIKI` (the script defaults it to `cirrustestwiki`); Cucumber (`tests/integration/features/`) is the only layer with a live index. Cucumber has its own runner — `./run-integration.sh` (see below) — so it is simply out of scope for *this* script, NOT unavailable. "Not run by `run-unit-tests.sh`" never means "cannot be run."
* You can pass multiple test files in one invocation to run them together.
## Cucumber Integration Test Runner Mechanices (`./run-integration.sh`)
* A live OpenSearch environment IS available locally and you CAN run Cucumber. When an issue lists Cucumber acceptance criteria, running them is your job — author the scenario, run `./run-integration.sh`, and report the result. Do NOT mark Cucumber criteria "deferred to the live-index suite" or "not exercised by `run-unit-tests.sh`"; that is the unit runner's scope, not a statement about availability. Deferral is allowed ONLY when an explicit, prior environment failure proves the runner is broken — record that failure, don't assume it.
* The script runs cucumbre inside the mediawiki cli docker infra. Test selection is controlled by an env var defaulting to`CIRRUS_FEATURES="*.feature"`, e.g. `CIRRUS_FEATURES="redirect_documents_api.feature" ./run-integration.sh` to run one feature.
* The related script `./create-env.sh` resets the complete integration environment, otherwise database and indexes are preserved between test runs.
* All feature files are suffixed `_api.feature` or `_browser.feature` (by transport); name new files accordingly.
## Fixture-Based Tests (`assertFileContains` + `*.expected`)
* Many tests (e.g. `SearcherTest`, `MappingConfigBuilderTest`, `MoreLikeFeatureTest`) compare generated output against committed `tests/phpunit/fixtures/**/*.expected` files.
* `CIRRUS_REBUILD_FIXTURES` controls rebuild mode; the script defaults it to `yes`. Use `CIRRUS_REBUILD_FIXTURES=no` to verify against existing fixtures (the normal "did I break anything" run).
* IMPORTANT: `assertFileContains` only writes a fixture when the file is **missing** — it never overwrites. To regenerate changed fixtures: (1) `find ... -name '*.expected' -delete` the affected files, (2) run with `CIRRUS_REBUILD_FIXTURES=yes` (recreates them, marks those tests skipped), (3) run again with `CIRRUS_REBUILD_FIXTURES=no` to confirm they pass. Always `git diff` the regenerated fixtures to confirm the change is what you intended.
* `randomizeFixtures` samples only a random subset of cases per verification run (seed-based), so a passing `CIRRUS_REBUILD_FIXTURES=no` run does not exercise every fixture. When rebuilding (`=yes`) it returns ALL cases, so deleting + rebuilding regenerates the full set consistently — prefer regenerating the whole affected set over individual files.
* A change to a widely-assembled query (e.g. anything in `SearchContext::getQuery()`) will ripple through hundreds of `searchText/*.expected` fixtures; this is expected and produces a large but uniform diff.
## Workspace Etiquette
* Keep the Working Directory Clean: Leave all git operations (adding files, staging, or committing) to the human operator.
* Preserve Diff Integrity: Limit your actions to file modifications only. This allows the lead to use git diff to review and validate the full scope of your architectural changes before they are finalized.
* Internationalization: When adding i18n messages developers are required to populate en.json and qqq.json
## Test Construction & Dependency Injection
* Prefer Real Objects: Use actual implementation objects whenever possible to ensure tests reflect real-world behavior.
* Use Static Factories: Utilize existing test-specific static methods for dependency setup.
* Example: Use CirrusDebugOptions::forSemanticSearchUnitTests() instead of creating a mock object.
* Minimize Mocking: Resort to mocking only for external services or complex infrastructure that cannot be instantiated in a unit test environment. High-fidelity state is preferred over simulated behavior.
## Agent skills
### Issue tracker
Issues and PRDs live as local markdown files under `.scratch/<feature>/`. See `docs/agents/issue-tracker.md`.
### Triage labels
Default vocabulary (`needs-triage`, `needs-info`, `ready-for-agent`, `ready-for-human`, `wontfix`), recorded as `Status:` lines in each issue file. See `docs/agents/triage-labels.md`.
### Domain docs
Single-context: `CONTEXT.md` + `docs/adr/` at the repo root. See `docs/agents/domain.md`.