Core Concepts
Package-Based Architecture
Test Packages represent a fundamental shift in how tests are organized and executed. Instead of loose collections of test files, everything is a package with explicit dependencies, phases, and results.
Package Types
Test Packages
A Test Package is one that executes tests. It's identified by having a run phase in its manifest.
Characteristics:
- Contains Playwright E2E test code
- Produces test results in CTRF format
- Generates artifacts (screenshots, logs, videos)
- Must declare where results will be found
Use for:
- E2E test suites
- Integration tests
- Smoke tests
- Regression tests
Utility Packages
A Utility Package provides supporting functionality without running tests. It has no run phase.
Characteristics:
- Sets up test environments
- Seeds test data
- Configures WordPress/WooCommerce
- Cleans up after test runs
Use for:
- Disabling onboarding wizards
- Creating test users
- Installing helper plugins
- Database seeding
The Manifest
Every package has a qit-test.json that serves as its contract with the system. The manifest declares:
- Identity: Package name and namespace
- Requirements: What the package needs to run
- Phases: What commands to execute when
- Results: Where to find test output (test packages only)
Lifecycle Phases
Phases define when commands execute in the test lifecycle:
globalSetup
Runs once before all packages. Changes made here affect the entire test run.
setup
Runs before this package's tests. Package-specific preparation.
run
The actual test execution. Only test packages have this phase.
teardown
Cleanup after this package. Package-specific cleanup.
globalTeardown
Runs once after all packages. Final cleanup for the entire test run.
Database Isolation
QIT ensures complete isolation between packages through database snapshots:
- After
globalSetup, a baseline snapshot is taken - Before each package (except the first), the database is restored
- Each package starts from the exact same state
- Changes made by one package never affect another
This means you can:
- Write tests without worrying about cleanup
- Run packages in any order (though order still matters for other reasons)
- Debug with confidence knowing the starting state
Result Collection
Test packages must produce results in CTRF (Common Test Results Format):
{
"results": {
"summary": {
"tests": 10,
"passed": 8,
"failed": 2
},
"tests": [
{
"name": "Checkout flow",
"status": "passed",
"duration": 1234
}
]
}
}
Additionally, packages can produce:
- Blob artifacts: Screenshots, videos, logs
- Allure results: Advanced test reporting
Secret Management
Secrets provide a secure way to handle sensitive data:
- Declaration: Packages declare required secrets in their manifest
- Validation: All secrets are validated before any execution
- Injection: Secrets are passed as environment variables
- Redaction: Secret values are automatically redacted from all output
Orchestration
The orchestrator manages the entire execution flow:
- Visual feedback: Shows progress through a CLI UI
- Lifecycle CTRF: Generates test results for setup/teardown phases
- Output management: Handles output suppression in CI
- Error handling: Captures and reports failures at any phase
Command Execution
Commands in phases are auto-detected for execution venue:
npm/npxcommands run on the host (where Node.js is installed)- Everything else runs in the Docker container (where WordPress lives)
- Override with
host:ordocker:prefix, or useruns_onin object command format
Commands execute in the package directory and have access to environment variables, declared secrets, and QIT-provided variables like $QIT_SITE_URL.
In Playwright tests, use @woocommerce/qit-runtime for typed access to environment info (qit.env.siteUrl), WP-CLI execution (qit.wp()), and cross-package capabilities (qit.actions()).
Running Test Packages
Test packages are run via CLI flags or qit.json configuration:
qit run:e2e my-plugin \
--test-package=./packages/tests/checkout \
--test-package=./packages/tests/payment \
--php=8.2
Exit Codes
QIT uses consistent exit codes:
- 0: Success - all tests passed
- 1: Failure - test failures or configuration errors
- 3: Infrastructure - Docker or network issues
CI Mode
When CI environment variable is set:
- Command output is suppressed (unless verbose)
- Only essential information is shown
- Errors are always visible
- Cleaner logs for CI systems
Key Principles
- Fail Fast: Validation happens early
- Isolation by Default: Packages can't interfere
- Explicit Over Implicit: Everything is declared
- Deterministic: Same input = same execution
- Observable: See what's happening at each step