End-to-end testing
An Apso end-to-end test proves that the schema, generated framework, database, HTTP surface, extensions, and client integration agree. Run these journeys after a CLI or template release and before deploying a product schema change.
Prerequisites
node --version
npm install -g @apso/cli
apso --version
apso doctorThe following local TypeScript path uses PGlite. It does not require Docker or a cloud account.
Journey 1: schema to working API
Initialize the project
apso init --name project-api --language typescript --skip-platform
cd project-apiConfigure the local service:
DATABASE_TYPE=pglite
DATABASE_SYNC=true
APP_PORT=3100Define the product model
Use the projects and tasks schema from the Quickstart, then validate it:
apso schema validate
apso generateConfirm that generation created entity folders for both resources:
test -f src/autogen/Project/Project.entity.ts
test -f src/autogen/Task/Task.entity.tsRun and exercise CRUD
apso devIn another terminal:
curl -s -X POST http://localhost:3100/Projects \
-H "Content-Type: application/json" \
-d '{"name":"Launch","status":"Active"}'
curl -s -X POST http://localhost:3100/Tasks \
-H "Content-Type: application/json" \
-d '{"title":"Verify API","status":"Todo","priority":1,"projectId":1}'
curl -s "http://localhost:3100/Projects/1?join=tasks"
curl -s -X PATCH http://localhost:3100/Tasks/1 \
-H "Content-Type: application/json" \
-d '{"status":"Done"}'Open http://localhost:3100/_docs and confirm the same routes and request shapes appear in OpenAPI.
Pass criteria: generation completes, the service starts, project and task writes succeed, the relationship can be joined, validation rejects an invalid enum, and OpenAPI matches the live surface.
Journey 2: start from a product model
Use this journey to verify the service builder and the richer starter experience exposed to product teams.
- Open Apso Cloud and create a service in a test workspace.
- Select Multi-Tenant Workspaces, Customer CRM, or another starter relevant to the release.
- Remove one entity that is outside the first workflow.
- Rename one field to match the product language.
- Review relationship direction and tenant scope.
- Generate the service.
- Open the service Docs view and create one root record and one related record.
- Pull or clone the generated source and inspect
.apsorc,autogen/, andextensions/.
Pass criteria: the selected starter produces an editable schema, removed concepts do not appear in generated output, renamed fields reach the API contract, relationships are valid, and the repository contains standard framework code.
A starter test must validate product vocabulary and relationship quality. Counting generated files alone does not prove that the model helps someone build the intended application.
Journey 3: agent-assisted schema evolution
Configure an MCP-capable coding agent to run apso mcp serve, then give it a bounded product change:
Add milestones to the project service. A milestone belongs to one project, has a title, due date, and status, and can contain many tasks. Preserve existing project and task data.
Require the agent to:
- Read the existing
.apsorcbefore editing. - Add a
Milestoneentity with supported version 2 field types. - Add each relationship once in the top-level
relationshipsarray. - Run
apso schema validateandapso generate. - Run
apso migrateand report the SQL impact. - Add custom completion rules under
extensions/when requested. - Run the framework tests and build.
Review the diff yourself:
git diff -- .apsorc src/autogen src/extensions src/migrations
npm test
npm run buildPass criteria: the agent changes the schema contract, leaves existing entities intact, generates a valid migration, keeps custom behavior outside autogen/, and passes the same checks a developer would run.
Frontend smoke test
After one backend journey passes, connect a Next.js BFF using a server-only SDK client:
import 'server-only';
import { ApsoClientFactory } from '@apso/sdk';
const apso = ApsoClientFactory.getClient({
baseURL: process.env.APSO_API_URL!,
apiKey: process.env.APSO_API_KEY!,
});
const projects = await apso.entity('Projects').get();Verify loading, empty, success, validation, and authentication error states. Keep the service key outside the browser bundle.
Release evidence
Record the CLI version, generated framework, schema fixture, test output, migration result, and screenshot of the OpenAPI route surface. This makes a failed release reproducible without relying on a developer’s local state.