Skip to main content
MDCMS uses Bun’s built-in test runner for both unit and integration tests. This page covers how to run tests, write new ones, and manage database migrations.

Unit Tests

Unit tests live alongside source files with the *.test.ts suffix. Unit tests cover config parsing, validation logic, contracts, SDK methods, and utility functions. They do not require any external services.

Integration Tests

Integration tests exercise the full stack — API endpoints, authentication flows, database operations, and the content lifecycle.
Integration tests require Docker services to be running. Start them before running:

CI Gates

The CI pipeline runs three sequential stages. All must pass before a PR can be merged.
1

Quality

Format check + TypeScript typecheck across all packages.
2

Unit tests

All unit tests across every package.
3

Integration tests

Full integration test suite. Requires Docker services.
The combined command that runs all three stages:
The pre-push git hook runs ci:required automatically before every push.

Writing Tests

Follow these principles when adding tests:
  1. Write the failing test first. Verify it actually fails before writing any implementation.
  2. Implement until the test passes. Do not modify the test to make it pass — fix the implementation.
  3. Test behavior, not implementation details. Assert on observable outcomes (return values, side effects, API responses), not internal state.
  4. Keep tests focused. Each test should verify one behavior. Use descriptive test names that explain the expected behavior.
Run bun run unit during development for fast feedback. Save bun run integration for before pushing.

Database Migrations

MDCMS uses Drizzle ORM for database schema management. Migrations are generated from the schema definition and applied via Drizzle Kit.
1

Modify the schema

Edit the Drizzle schema file:
2

Generate migration

This creates a new SQL migration file in the drizzle/ directory.
3

Review the generated SQL

Open the generated file in drizzle/ and verify the SQL matches your intent. Pay attention to destructive operations like column drops or type changes.
4

Apply locally

5

Test with existing data

Verify the migration works correctly against a database that already has data. Check that existing records are preserved and new constraints do not cause failures.
6

Commit together

Commit the schema change and the generated migration file in the same commit:
Always test migrations against a database with realistic data before deploying to production. A migration that works on an empty database may fail or corrupt data on a populated one.