Skip to content

Add PHP and JS testing infrastructure#11

Merged
acockrell merged 12 commits intomainfrom
feature/testing
Mar 22, 2026
Merged

Add PHP and JS testing infrastructure#11
acockrell merged 12 commits intomainfrom
feature/testing

Conversation

@acockrell
Copy link
Copy Markdown
Collaborator

@acockrell acockrell commented Mar 22, 2026

Summary

  • Adds PHPUnit 9.6 test suite for all PHP classes (helpers, frontend, admin, uninstall)
  • Adds Jest test for the `gpse/search-results` block metadata
  • Adds GitHub Actions CI: PHP matrix (8.2 + 8.3), Jest, and lint jobs run on every PR to main
  • Adds Docker Compose test environment (`docker-compose.test.yml`) for local parity with CI
  • Adds `make lint`, `make test-js`, `make test-php`, and `make test` targets

New files

File Purpose
`composer.json` / `composer.lock` PHPUnit ^9.6 + yoast/phpunit-polyfills ^3.0
`phpunit.xml.dist` PHPUnit test suite config
`tests/bootstrap.php` Loads WP test lib and plugin
`tests/php/Test_GPSE_Helpers.php` 5 assertions on `get_search_results_html()`
`tests/php/Test_GPSE_Frontend.php` Shortcode output, form/block value population, escaping, redirect guard
`tests/php/Test_GPSE_Admin.php` Settings registration, types, defaults, link injection
`tests/php/Test_GPSE_Uninstall.php` Verifies all three options removed on uninstall
`gpse/src/search-results/index.test.js` Block name, category, title, API version, text domain
`bin/install-wp-tests.sh` Installs WP core + test library via SVN; handles MariaDB vs MySQL 8.0 SSL quirks
`docker/Dockerfile.test` PHP 8.2 CLI image with Composer, SVN, and MariaDB client
`docker-compose.test.yml` MySQL 8.0 + phpunit services for local test runs
`.github/workflows/ci.yml` CI: lint, Jest, PHPUnit (PHP 8.2 + 8.3)
`.eslintrc.js` ESLint config extending `@wordpress/eslint-plugin/recommended`
`.stylelintignore` Excludes `dist/` and `gpse/build/` from style linting

Running the tests locally

make test-js    # Jest
make test-php   # PHPUnit via Docker Compose
make lint       # ESLint + Stylelint
make test       # all of the above

Test plan

  • `make lint` — JS and CSS lint pass
  • `make test-js` — Jest passes
  • `make test-php` — all 26 PHP tests pass locally via Docker
  • CI: all jobs green (PHP 8.2, PHP 8.3, JS Tests, Lint)

PHP (PHPUnit via wp-env):
- composer.json with phpunit/phpunit ^9.6
- phpunit.xml.dist pointing at tests/php/
- tests/bootstrap.php loads WP test lib and plugin
- tests/php/class-test-helpers.php — WP_GPSE_Helpers output assertions
- tests/php/class-test-frontend.php — shortcode, form/block value population, redirect guard
- tests/php/class-test-admin.php — settings registration, link injection
- tests/php/class-test-uninstall.php — verifies all three options removed on uninstall

JS (Jest via wp-scripts):
- gpse/src/search-results/index.test.js — block registration, category, title, save()

Infrastructure:
- .wp-env.json — wp-env Docker config (PHP 8.2, plugin mounted)
- Add @wordpress/env devDependency
- Add test:php, env:start, env:stop, env:clean npm scripts
- Scope test:unit to gpse/src to avoid scanning PHP test dirs
- @wordpress/env ^10.0.0 → ^11.2.0 (latest)
- phpunit/phpunit ^9.6 → ^11.1 (current supported line for PHP 8.2 + WP 6.9)
- phpunit.xml.dist: update schema to 11.5, remove attributes dropped in PHPUnit 10+
  (convertErrorsToExceptions, convertNoticesToExceptions, convertWarningsToExceptions)
@acockrell acockrell marked this pull request as draft March 22, 2026 20:13
Three jobs run on every PR to main:
- test-php: PHPUnit against PHP 8.2 and 8.3, WordPress latest, MySQL 8.0
- test-js: Jest (npm run test:unit)
- lint: wp-scripts lint-js + lint-style

Also adds bin/install-wp-tests.sh — standard WP plugin script that installs
WordPress core and the phpunit test library into /tmp for the PHP job.
- actions/checkout v4 → v6.0.2
- actions/setup-node v4 → v6.3.0
- shivammathur/setup-php v2 → 2.37.0
- ramsey/composer-install v3 → 4.0.0
- Add subversion install step to PHP jobs (Ubuntu 24.04 no longer ships with svn)
- Update package-lock.json to include @wordpress/env (was missing, broke npm ci)
PHP: Remove MYSQL_DATABASE from service env — install_db creates it, so
  the pre-created DB caused mysqladmin to error with 'database exists'

Lint JS: Scope lint:js to gpse/src (exclude pre-existing gpse/assets/js/
  violations). Add .eslintrc.js to mark @wordpress/* imports as externally
  resolved — they are webpack externals, not npm packages

Jest: Rewrite index.test.js to test block.json metadata directly instead
  of importing index.js, which requires @wordpress/blocks at runtime
Makefile:
- make lint     — runs lint:js (gpse/src) + lint:css, mirrors CI lint job
- make test-js  — runs Jest via wp-scripts, mirrors CI test-js job
- make test-php — starts wp-env and runs PHPUnit, mirrors CI test-php job
- make test     — runs test-js + test-php
- Updated help and .PHONY

.eslintrc.js:
- Add jest env override for *.test.js files so describe/it/expect
  are recognised as globals (fixes CI lint failure)
gpse/assets/css/gpse.css:
- Break long comment (line 20, 85 chars) to satisfy max-line-length
- Reorder selectors: td.gsc-orderby-container (lower specificity) now
  precedes .gsc-resultsHeader td.gsc-orderby-container (higher)

.stylelintignore:
- Exclude dist/, gpse/build/, node_modules/ — all build artifacts
- Downgrade PHPUnit to ^9.6 (WP 6.9.4 test framework uses parseTestMethodAnnotations which was removed in PHPUnit 10)
- Switch yoast/phpunit-polyfills to ^3.0 (compatible with PHPUnit 9-11)
- Add docker-compose.test.yml and docker/Dockerfile.test for local parity with CI
- Fix install-wp-tests.sh: add --skip-ssl to mysqladmin to bypass MariaDB SSL default, check includes/ dir instead of parent dir so cached Docker volume doesn't skip SVN checkout, tolerate pre-existing test database
- Rename test files to match class names (PHPUnit 11 derives class name from filename; fix for any future upgrade too)
- Remove directory prefix/suffix from phpunit.xml.dist to discover by class name
- Add Makefile targets: lint, test-js, test-php, test
MySQL 8.0 client uses --ssl-mode=DISABLED; MariaDB uses --skip-ssl.
Detect the client at runtime and select the correct option so the DB
creation step works in both the Docker environment (MariaDB client)
and GitHub Actions (MySQL 8.0 client).
caching_sha2_password (MySQL 8.0 default) requires a secure connection.
--ssl-mode=DISABLED broke auth. The MySQL 8.0 client default (PREFERRED)
uses SSL without verifying the self-signed cert, which is what we want.
Only MariaDB client needs --skip-ssl to avoid self-signed cert errors.
@acockrell acockrell marked this pull request as ready for review March 22, 2026 21:39
@acockrell acockrell merged commit f13bc7f into main Mar 22, 2026
4 checks passed
@acockrell acockrell deleted the feature/testing branch March 22, 2026 21:42
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