Testing Setup
Nothing about testing is mandatory — a Syntaxis project has no test gate
until AGENTS.md actually declares a real test command.
/tests is how you turn that on deliberately.
Setting up the harness and actually writing tests are two separate jobs:
/tests installs and wires things up, while
/automate is what writes the tests themselves.
Three modes, pick one
Section titled “Three modes, pick one”/tests stack-native unit testing/tests unit the same thing/tests browser a browser and end-to-end harness/tests mobile a device or simulator harnessEach invocation picks exactly one. Naming a runner by itself never selects
browser or mobile — /tests Playwright still reads as a unit-testing
request with a preference attached, not a green light to set up browser
automation.
An existing runner gets reused when there is one. Otherwise, the default depends on the stack:
| Stack | Default |
|---|---|
| TypeScript / JavaScript | Vitest, unless the project already clearly uses Jest |
| Python | pytest |
| Go | go test |
| Rust | cargo test |
| Ruby | Minitest, unless something else is implied |
| PHP | PHPUnit for Composer-based projects |
It writes one small example test against genuine project logic, records the
command in AGENTS.md, and slots that command into an existing Verify
step between typecheck and build.
What it deliberately skips: coverage tooling, snapshots, mock-service layers, CI wiring, or any broader test architecture.
Browser
Section titled “Browser”Playwright Test is the default for a compatible web app or extension; an existing runner takes priority when the project already has one.
It adds a single representative smoke path through a real surface of the
project — just enough to prove the harness can actually launch the app and
watch it behave, not merely that some static fixture exists. The resulting
command gets documented as Browser tests: <command>.
Mobile
Section titled “Mobile”| Stack | Default |
|---|---|
| Flutter | integration_test |
| React Native / Expo | Maestro |
| React Native with Detox already in place | Detox |
| Ionic + Capacitor | Playwright against the web build; Appium for the native shell |
| Native, shared code | Appium |
| Native with existing suites | XCUITest / Espresso |
Before touching anything, mobile setup checks what the environment can actually do — installed SDKs, available simulators, connected devices, and whether it’s headless. A harness that genuinely can’t run gets reported as incomplete, never dressed up as configured and working.
Its command gets documented as Mobile tests: <command>.
Where Verify and CI come in
Section titled “Where Verify and CI come in”Unit tests join an existing Verify command automatically. Browser and
mobile suites don’t — they’re slow and tied to a specific environment, and
most CI runners have no simulator to begin with. Adding either to Verify
takes a separate, explicit request; that gate is
/ci’s territory, not this skill’s.
None of the three modes creates CI on its own just by running.
Once a harness is in place
Section titled “Once a harness is in place”AGENTS.md records the command, and everything downstream reads it from
there:
/featurecan fold in a focused test expectation./implementadds a test proportionate to whatever step it’s on./checkruns it as repeatable evidence, then observes directly whatever the suite doesn’t already prove./automatewrites case-backed specs straight into it./test-runruns them as part of a full cycle.
What a green run actually proves
Section titled “What a green run actually proves”A passing run proves exactly what it ran and nothing past that. It says nothing about visual fidelity, real authenticated behavior, browser chrome, store builds, hardware-specific paths, or any device it never touched. When those boundaries matter, Syntaxis names them rather than letting a passing run imply more than it showed.