OpenProgram test system
This page defines test categories, directories, dependency boundaries, commands and CI responsibilities. Runtime dependencies determine test levels; product domains follow module names in openprogram/ . Structural migration does not change product behavior; genuine product defects found by tests are fixed and verified in separate batches.
1. Current implementation
There are currently 394 Git-tracked Python test files: 226 unit, 138 component, 14 contracts, 9 integration, 4 e2e and 3 live. Execution-level cases all reside in tests/<layer>/<product-domain>/, with no tracked test files directly at a level root.
Repository contracts enumerate only Git-tracked files. Structural contracts and autouse runtime guards jointly prohibit TestClient, subprocess, sockets, real threads/thread pools, fixed waits and global thread-class replacement in unit tests. CI separately runs contracts, unit on three Python versions, component, integration, non-browser e2e, built-Web browser, Web, CLI, Desktop and coverage.
The remaining structural gap concerns top-level repository constraints, not test levels: prevent new root development scripts, undeclared top-level directories and deleted source paths from returning to active guides.
2. Reference frameworks and responsibility boundaries
References come from official project documentation. The repository retains existing tools; this design adds no general-purpose test runner.
| Tool | Adopted capability | Not provided | OpenProgram treatment |
|---|---|---|---|
| pytest | Python discovery, fixtures, markers, warnings and xfail policies | Does not execute JavaScript or guarantee fixture process isolation | Runs Python contracts, unit, component, integration, e2e and live |
| pytest-xdist | Multiprocess distribution | Cannot repair global state, background threads or unsafe monkeypatches | Enable only a fixed worker count after isolation fixes and repeated verification |
| node:test | Node 22 built-in assertions, tests and mocks | No real DOM or browser interactions | Use for pure Web TypeScript/JavaScript logic without new dependencies |
| Vitest | Existing CLI TypeScript test runner | Does not cover the Python worker or real browsers | Retain only in CLI; do not install another copy for Web |
| Playwright | Real browsers, user-visible behavior and cross-page state | Does not replace unit/component tests | Reuse the Python browser extra and Playwright-managed Chromium |
| GitHub Actions | Version matrices, job isolation and required checks | Does not define test semantics | Separate jobs by test level using the same local commands |
3. Target structure
tests/
contracts/{repository,security}/
unit/<product-domain>/
component/<product-domain>/
integration/<product-domain>/
e2e/{agent,context,web}/
live/{providers,channels}/
support/
conftest.py
| Level | Allowed dependencies | Prohibited dependencies | Default execution |
|---|---|---|---|
| contracts | AST, tracked files, manifest, registry, schema | External services; source-text checks used instead of behavioral assertions | Every PR |
| unit | In-memory objects, pure functions, local fakes, isolated temporary files for one module; controlled cleanable threads inside production modules | TestClient, sockets, subprocesses, real background threads/thread pools directly created by tests and fixed sleeps | Python 3.11/3.12/3.13 |
| component | tmp_path, temporary SQLite, TestClient, fake providers and controlled threads | External networks and real credentials | Python 3.12 |
| integration | Loopback HTTP/WS, real subprocesses and multiple production modules | External services | Python 3.12 |
| e2e | Public CLI, real worker, built Web and browser | Developer’s real HOME and pre-existing build outputs | Dedicated CI job |
| live | Real providers, channels and remote services | Ordinary PR required checks | Manual or scheduled |
When a test meets multiple levels, choose the one with the strongest dependencies. Directories have at most level/product-domain depth. Markers describe only execution capabilities: slow, browser, sandbox, live; do not repeat levels already expressed by directories.
4. Execution and state isolation
- Repository contracts read only Git-tracked files. Callers supply roots to generic scanners, excluding nested repositories and build directories.
- Top-level
conftest.pyretains only isolation required to prevent access to real user state; domain fixtures stay local. - Temporary HOME has deterministic cleanup. Tests must not depend on real
~/.openprogram. - Wait for concurrent results with Event, Condition or deadline-based conditional waits; fixed sleeps are prohibited in unit tests.
- Tests must not replace process-global standard-library thread classes or directly create real threads/thread pools. Background resources created inside production modules must be joined or closed during fixture teardown.
- Each production defect gets one regression test through the lowest public boundary.
5. Web, CLI and desktop
| Existing checks | Target | Decision |
|---|---|---|
| Web security/architecture source check | apps/web/scripts/check-*.mjs | Retain only when source structure itself is contractual |
| Web pure helper behavior | apps/web/tests/*.test.mjs + node:test | Import directly and assert inputs/outputs |
| Web user interaction | tests/e2e/web + Playwright | Operate built pages and observe public behavior |
| CLI TypeScript | Existing Vitest | CI runs typecheck, test and build |
| desktop VM/fake Electron | desktop component checks | CI runs the complete npm run check |
| Real Electron | release e2e | Initial restructuring adds no packaging-test infrastructure |
6. CI data flow
contracts
docs
3.11 / 3.12 / 3.13
local resources
subprocess/MCP
CLI
desktop
live manual
Python commands use uv run --locked. Matrix fail-fast is disabled so one version’s failure does not cancel other results. Ordinary PRs do not run live tests. All CI commands also appear in contribution documentation.
7. Adopted, adjusted and rejected
| Status | Decision | Boundary |
|---|---|---|
| Adopt | Level-first directories, product-domain subdirectories, strict markers, strict xfail, fixed workers and Playwright-managed Chromium | Preserve test semantics and counts during migration |
| Adjust | Retain necessary Web source contracts while migrating pure logic to node:test | Do not rewrite all Web checks at once |
| Adjust | Initially generate coverage reports only | Set thresholds from measured data after stabilization |
| Reject | Adding tox/nox, installing Vitest again in Web, -n auto, and arbitrary global coverage thresholds | Existing tools cover requirements, or current isolation is insufficient for stable parallelism |
| Exclude | Windows-specific tests, packaging and compatibility; keyring/Credential Manager | Outside this test-system restructuring |
8. Acceptance criteria
- Clean checkouts and checkouts containing ignored/nested-repository files collect identical tracked tests and produce identical contract results.
- Unit test code does not directly use TestClient, subprocesses, sockets, real background threads/thread pools or fixed sleeps; internal production threads are reclaimed at teardown.
- Required Python suites emit no unhandled-thread warnings; three consecutive runs with fixed xdist workers have no worker crashes.
- Separately verify component behavior without frontend artifacts and e2e behavior with built CSP.
- CI runs all CLI, Web and desktop package scripts.
- Explicitly record test-count, skip and xfail changes across migration.
- Required Python suites have zero failures; known product defects cannot remain in a completed state.
- Establish reproducible coverage first, then prevent regression with a threshold no higher than the measured baseline; raising it requires additional meaningful tests.
- Unit structural contracts detect direct/aliased resource imports, direct sleep imports and replacement of standard-library thread classes. Autouse runtime guards intercept real-thread creation, thread-pool construction and fixed waits directly in test code. Unit tests permit only module-qualified
asyncio.sleep(0), with positional or keyword forms allowed as scheduling yields. - Audit npm dependency risks per workspace; use only upgrades compatible with current builds/tests, without forced breaking upgrades.
Merge-turn tests own their temporary SessionStore. The fixture registers close immediately after construction, so successful tests, assertion failures, and setup failures drain pending index writes and join store timers before the unit resource guard runs. The guard remains strict; cleanup does not depend on machine speed or a longer timeout.
History-page objects use the local name historyWindow, keeping source checks for browser window access unambiguous. Local-refresh test repositories include the real ASAR permission-restoration helper so version-change rejection is exercised after staging, without weakening the no-installation assertions.
9. Implementation status
| Work item | Status | Completion evidence |
|---|---|---|
| Design and baseline | Complete | Design, site build, link checks, clean-checkout baseline and two-stage independent review |
| Input enumeration and shared state | Complete | Git-owned input enumeration, temporary-HOME cleanup, local fixtures, thread/TLS cleanup; focused and unit regressions plus independent specification/quality reviews passed |
| Python directory migration | Complete | Directory/marker migration complete; duplicate HTTP inventory, agentic-context structural-contract false positives and retry isolation fixed. Final required suite: 5356 passed, 10 skipped, 1 xfailed; independent specification/quality reviews passed |
| Web/CLI/desktop | Complete | Web pure helpers use node:test; component and built-Web/browser e2e are separate. Scheduler view-model has 4 Node unit tests; Web check/build, CLI typecheck/Vitest/build, desktop checks and independent review passed |
| CI and contribution documentation | Complete | Ten independent CI results, three-version unit matrix, locked uv, non-browser e2e, complete Web/CLI/desktop/browser commands and contribution-document contracts; independent review passed |
| Waits, concurrency and large files | Complete | Structural contracts cover resource imports, fixed waits and global thread-class replacement. Unit autouse guards cover direct test thread/thread-pool creation, fixed waits, production-resource teardown and global-state restoration. Seven files with 109 tests actually requiring runners, thread pools or Workflow execution moved to component. Current required selection: 5699 passed, 16 skipped, 1 xfailed |
| Coverage and final verification | Complete | In a locked Python 3.12.13 environment, two consecutive serial unit runs each produced 2560 passed, 3 skipped and branch coverage 42.402765%. CI generates/uploads XML before enforcing a 40% floor at six-digit precision. Fixed -n 4 required selection ran three consecutive times with 5699 passed, 16 skipped, 1 xfailed and 0 worker crashes |
10. Improvement plan and implementation records
Complete batches sequentially. Each first reproduces failure through a public/shared boundary, fixes the minimum shared cause, runs focused/affected tests, passes independent specification and quality review, then commits. Do not start the next batch before the prior review passes.
| Batch | Scope | Exclude | Gate | Status |
|---|---|---|---|---|
| Zero required-suite failures | Remove old channel implementations unused by the registry; correct @function / Agent method structural-contract false positives; isolate retry test state | Do not change managed channel implementations or public APIs | All 4 failing-node checks passed; final required suite: 5356 passed, 10 skipped, 1 xfailed; independent specification/quality reviews passed | Complete |
| Structure and waiting contracts | Detect aliased resource imports, thread-class replacement and nonzero asynchronous waits; intercept direct test thread/thread-pool creation; migrate or rewrite actual violations | Do not implement a Python control-flow interpreter or mechanically split tests by line count | Structural/runtime contracts passed; unit: 2434 passed, 3 skipped; five migrated component files: 104 passed; independent specification/quality reviews passed | Complete |
| Coverage gate | Record precise branch baseline, set a regression floor and cover only critical missing branches | Do not pursue arbitrary high coverage or duplicate assertions for coverage | Two isolated locked Python 3.12.13 runs each produced unit 2560 passed, 3 skipped, branch baseline 42.402765%. Six-digit 40% floor passed; XML still uploads before floor enforcement; CI contract passed | Complete |
| JavaScript dependency risks | Audit Web, CLI and desktop separately; upgrade compatible dependencies and verify lockfile | Do not run npm audit fix --force, and do not introduce a new runner | After compatible upgrades, Web decreased from 8 high to 5 high, CLI from 4 high + 1 moderate to 1 moderate, and desktop from 5 high + 2 moderate to 2 high. Remaining items require separate compatible migrations to Next/eslint-config-next 16, esbuild 0.28 and Electron 43. All three workspaces passed npm ci and existing check/test/typecheck/build | Complete |
| Final integration, 2026-08-15 | Integrate into main as it stood then; run Python, Web, CLI, desktop, browser, docs, examples and diff/status gates | Do not overwrite uncommitted primary-workspace changes or push remotely | Historical candidate evidence: serial required suite 5370 passed, 10 skipped, 2 deselected, 1 xfailed; fixed -n 4 ran three consecutive times with 5370 passed, 10 skipped, 1 xfailed and 0 worker crashes. Web, CLI, desktop, browser, docs, examples, Ruff and diff-check gates passed; independent specification/quality reviews passed | Complete |
| Structural maintenance, 2026-08-17 | Clean root development scripts, synchronize paths/directory READMEs, add repository-structure contracts and repair test regressions after main integration | Do not rearrange product modules or overwrite other primary-workspace tasks | Contracts: 442 passed, 1 skipped; fixed -n 4 ran three times with 5699 passed, 16 skipped, 1 xfailed and 0 worker crashes. Python 3.12 unit coverage twice measured 42.402765%; docs: 503 pages, 0 broken links; complete Desktop npm run check passed | Awaiting independent review |