Testing and releasing a plugin
Oct 25, 2026
Test it
Put tests in plugins/<slug>/tests/ and run them with:
vendor/bin/phpunit plugins/<slug>/tests
Extend Tests\PluginTestCase for a ready setup: a super admin ($this->staff), a client ($this->client), USD as the default currency, email sending off, and $this->invoice($total, $currency, $paid) to make an invoice for the client. Log in with $this->actingAs($this->staff) for the admin area or $this->actingAs($this->client, 'client') for the client area.
Feature tests need a throwaway MySQL database that may be wiped (the migrations use MySQL syntax):
DB_CONNECTION=mysql DB_DATABASE=hosting_platform_renewal_test vendor/bin/phpunit plugins/<slug>/tests
Fake the outside world. For a service that is called over HTTP use Http::fake() so a test never touches the real service. The Stripe tests (tests/Feature/StripeGatewayTest.php) show this for a gateway: a good and a failing connection test, a Checkout Session, signed and unsigned webhooks, a replayed event and refunds.
Check it
php artisan whbmp:plugin-check <slug>
It checks that the manifest loads, that every class the plugin provides exists and has the interface of its type, that an addon's slug() matches the manifest, that CHANGELOG.md has a section for the version, and that a README exists.
Run php artisan i18n:missing <code> --list to see texts that still need a translation, and php artisan i18n:check to check the language packs.
Use it on a site
Put the plugin folder in plugins/<slug>/ of a WHBMP site, with its plugin.json inside, then open the Plugins page and activate it. That is all: WHBMP finds every valid plugin in that folder. A plugin with a mistake in it is skipped and the Plugins page says why.
Share it
A plugin is a plain folder, so you can give it to anyone yourself:
- Raise
versioninplugin.jsonand add the same version toCHANGELOG.md(New Features, Improvements, Fixes, each line starting with a bold area). - Run
php artisan whbmp:plugin-check <slug>. - Make a zip with one top folder named after the slug (
my-addon/plugin.json,my-addon/MyAddon.php, …). Leave out.git,testsand anything private. - Send the zip to your customers. They extract it into the
plugins/folder of their site and activate it on the Plugins page. To update, they replace the folder with the new version; their data stays, because the plugin's tables are not touched.
Keep your source in your own git repository and tag each release (vX.Y.Z) so you can always rebuild a version.
If a release needs a newer WHBMP, set requires.whbmp in plugin.json to that version. WHBMP then refuses to load it on an older site and says so, instead of failing halfway.