Skip to content

Add PHPUnit setup and run tests in CI - #2

Merged
HafizMMoaz merged 1 commit into
masterfrom
feat/48-phpunit-ci
Jul 27, 2026
Merged

Add PHPUnit setup and run tests in CI#2
HafizMMoaz merged 1 commit into
masterfrom
feat/48-phpunit-ci

Conversation

@HafizMMoaz

Copy link
Copy Markdown
Member

Part of zerp-pk/zerp#48, which tracks every published module shipping zero automated tests and no CI to run them.

CI here existed but only ran composer validate and php -l. Nothing executed a test, because there were none.

What's added

The scaffolding package-template already carries and the modules never received:

  • orchestra/testbench in require-dev, autoload-dev for the test namespace, scripts.test
  • an explicit "php": "^8.2" in require, which was previously an empty object
  • phpunit.xml and a testbench TestCase registering the module's service provider
  • a Run tests step in the workflow, and tests added to the lint path
  • .gitignore, so vendor/ and the phpunit cache stay out of the repo

What the tests actually check

PackageIntegrityTest targets the wiring that fails silently rather than loudly. None of it needs a database or the host app, so it runs on a bare checkout in CI:

Test Regression it catches
declared providers exist and boot a renamed or moved provider quietly stops Laravel auto-discovery; the module stays installed but never boots, with nothing logged
module.json parses and has the fields PackageSeeder reads a malformed manifest breaks the scan that writes add_ons rows
module.json package_name matches the composer package the module registers in add_ons under a key nothing can enable
every class in src/ sits at its PSR-4 path the class is unreachable at runtime, on whichever request first touches it
migration filenames unique and well formed loadMigrationsFrom() keys by filename, so a duplicate means one migration never runs
every migration returns a Migration otherwise it throws during someone's deploy, not before

PSR-4 is verified by reading each file's declared namespace rather than by autoloading it. Module classes extend host app classes (App\Http\Controllers\Controller, App\Models\User, App\Models\Concerns\TenantScoped) that do not exist outside an install, so class_exists() would fatal on the missing parent instead of reporting the mapping. Worth noting as its own problem: these packages have hard, undeclared dependencies on host app classes.

Verification

Run locally against all 32 module packages before opening these PRs. All 32 green, ~1,600 assertions total. composer validate --strict is clean on all 32.

The package shipped no automated tests, and CI only ran composer validate
and php -l. These packages are published to Packagist and installed
independently, so a regression here reaches every install with nothing
catching it.

Adopts the scaffolding package-template already carries and the modules
never received: orchestra/testbench in require-dev, autoload-dev for the
test namespace, phpunit.xml, a testbench TestCase registering the module's
service provider, and a `Run tests` step in the workflow. .gitignore keeps
vendor/ and the phpunit cache out of the repo.

PackageIntegrityTest covers the wiring that fails silently rather than
loudly, none of which needs a database or the host app:

- the declared service providers exist and actually boot, so a renamed
  provider cannot quietly stop Laravel auto-discovery
- module.json parses, carries the fields PackageSeeder reads, and its
  package_name matches the composer package, so the module cannot register
  in add_ons under a key nothing can enable
- every class under src/ sits at the path its PSR-4 prefix implies
- migration filenames are unique and well formed, so one cannot silently
  never run, and each file returns a real Migration

PSR-4 is checked by reading the declared namespace rather than by
autoloading: module classes extend host app classes that do not exist
outside an install, so loading them would fatal on the parent instead of
reporting the mapping.
@HafizMMoaz
HafizMMoaz requested a review from a team as a code owner July 27, 2026 20:24
@HafizMMoaz
HafizMMoaz merged commit f274efa into master Jul 27, 2026
2 checks passed
@HafizMMoaz
HafizMMoaz deleted the feat/48-phpunit-ci branch July 27, 2026 20:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant