Files
summercms/docs/plugins/testing.md
Jakub Zych a95a014b52 fix(build): scaffold plugins under plugins/<vendor>/<name> (quick-261028-pq8)
- make:plugin writes plugins/<vendor>/<name> with module
  <app>/plugins/<vendor>/<name>; the package name stays <name>
- make:* and the models-leaf check look in summer.yaml, then
  plugins/<vendor>/<name>, then the older plugins/<name>
- summer new puts its starter plugin at plugins/golem15/<name>
- refuse a vendor directory that is a legacy plugin module and a second
  copy of a plugin that already sits in plugins/<name>
- help text and docs, with an upgrading note: moving is optional
2026-10-28 18:55:46 +01:00

48 lines
2.5 KiB
Markdown

---
title: Testing plugins
description: Test plugins with go test, run database tests against real PostgreSQL containers, replay API parity fixtures and keep documentation examples running.
section: plugins
order: 40
---
# Testing plugins
SummerCMS uses the standard Go test tooling. There is no separate test runner and no PHPUnit bootstrap: a plugin's tests are `_test.go` files next to its code, and `go test` runs them.
## Running tests
Run every test in the module from its root:
```sh
go vet ./...
go test ./...
```
Tests that need Docker, such as database tests, skip themselves in short mode. Use it for a fast loop:
```sh
go test -short ./...
```
In an application with local plugins in a `go.work` workspace, run the tests of one plugin by its directory, for example `go test ./plugins/acme/blog/...`.
## Unit tests without a database
Most plugin code runs without a database. Build a container with `backpack.New`, call your plugin's Register and Boot, and assert on what it published. Drive HTTP handlers with `net/http/httptest`: `surf.Assemble` builds the same handler `serve` uses, so a test can send requests to your routes without listening on a port. Call console commands in-process with `bonfire.Call`.
## Database tests
SummerCMS supports PostgreSQL only, so database tests run against real PostgreSQL rather than an SQLite stand-in. The framework's own tests start a `postgres:16-alpine` container through testcontainers-go and create a fresh database per test. Follow the same pattern in plugin tests:
- skip the test when `testing.Short` reports true;
- migrate a fresh database per test with `lagoon.Migrate`, so tests do not depend on each other.
Docker must be running for these tests.
## API parity tests
When you port an existing backend, its real responses are the acceptance test. [tide](../../modules/tide/README.md) records request and response fixtures from the reference backend and replays them against your port, reporting differences after masking IDs and timestamps. The `summer parity:record`, `summer parity:replay`, `summer parity:proxy` and `summer parity:broadcasts` commands wrap it.
## Examples in the documentation
Every Go code block in these docs is a copy of an `Example` function or a marked region of a test that `go test ./...` runs. If you change a framework API and forget an example, `go test` fails. Write your plugin's examples the same way: an `Example` function with an `// Output:` comment is compiled, run and compared by `go test`, so it cannot go stale.