I've been testing my gallery plugin using local and remote URLs.
This seemed reasonable until I realised that it breaks the release process.
This is because the release needs to test an updated environment, but the environment is only updated by the release. So my tests would pass on local dev, but fail when run through the CI, which could only see the remote URL.
Note: I just remembered that there's actually a way to expose a local URL to other internet users, I didn't try this.
wpdtrt-plugin-boilerplate/composer.json:
"require-dev": {
"phpunit/phpunit": "^7.5.14",
"psy/psysh" : "~0.6",
"wp-coding-standards/wpcs": "^0.14.1",
"dealerdirect/phpcodesniffer-composer-installer": "^0.4.4",
"wp-cli/wp-cli": "^2.3"
},A fresh site prevents wiping the existing database from being wiped out by test data during setup.
- Download latest WP from wordpress.org
- Unzip to
new_folderin websites directory - Edit
wp-config.phpto add DB user/pass anddefine( 'DB_HOST', '127.0.0.1' ); - Create empty
wp_dbnamedatabase using SequelPro - Create a virtual host in MAMP Pro
- Visit http://virtualhost to run the WordPress 5 minute set up
- cd
new_folder mkdir wp-content/plugins/my-plugin-name
wp scaffold plugin-tests my-plugin-name(usingwp-cli/scaffold-command, which can also be used for theme tests). See also https://developer.wordpress.org/cli/commands/scaffold/plugin-tests/.
Success: Created test files.The following files are created in my-plugin-name/:
./phpunit.xml.distis the configuration file for PHPUnit../travis.ymlis the configuration file for Travis CI. Use--ci=<provider>to select a different service../bin/install-wp-tests.shconfigures the WordPress test suite and a test database../tests/bootstrap.phpis the file that makes the current plugin active when running the test suite../tests/test-sample.phpis a sample file containing the actual tests../phpcs.xml.distis a collection of PHP_CodeSniffer rules.From:
wp scaffold plugin-tests
./phpunit.xml.distis merged into my file of the same name./travis.ymlis merged into my CI script./bin/install-wp-tests.shis called bygulp-modules/dependencies.js, customised to pass environmental variables in from mybash_profile./tests/bootstrap.phpis loaded viaphpunit.dist.xml, customised for my use case../tests/test-sample.phpis merged into my test script../phpcs.xml.distis merged into my file of the same name
See also https://github.com/wp-cli/sample-plugin/blob/master/bin/install-wp-tests.sh
e.g. wpdtrt-plugin-boilerplate/bin
yarn run dependenciesThis calls:
gulp-modules/dependencies.js:
async function wpUnit() {
// ...
// bootstrap.php checks for bin/install-wp-tests.sh
// and throws an error if it is not found.
// ./bin/install-wp-tests.sh is stored in wpdtrt-plugin-boilerplate
const dbName = `${pluginNameSafe}_wpunit_${Date.now()}`;
const wpVersion = 'latest';
let installerPath = 'bin/';
if ( boilerplatePath().length ) {
installerPath = `${boilerplatePath()}bin/`;
}
const { stdout, stderr } = await exec( `bash ${installerPath}install-wp-tests.sh ${dbName} ${wpVersion}` );
// ...
}- downloads the latest version of WordPress from
https://wordpress.org/nightly-builds/wordpress-latest.zip - downloads
wp-mysqlifrom the Github repo - clones the testing suite (
wordpress-tests-lib) fromdevelop.svn.wordpress.orgto the user's temporary folder (see below) - sets
WP_TESTS_DIRandWP_CORE_DIR - customises
wp-tests-config-sample.phpand outputs it towordpress-tests-lib/wp-tests-config.php - creates a separate database for running unit tests
This dynamic instance of WordPress allow plugins to be tested in isolation of a standard WordPress folder.
install-wp-tests.sh uses sed (a special editor for modifying files automatically) to replace the following placeholders in wp-tests-config-sample.php:
define( 'DB_NAME', 'youremptytestdbnamehere' );
define( 'DB_USER', 'yourusernamehere' );
define( 'DB_PASSWORD', 'yourpasswordhere' );However it appears to hardcode the values which control which domain is used to host the temporary WordPress site which exists while tests are running.
This is problematic, as the generated code assigns the domain of example.org to the dummy site.
define( 'WP_TESTS_DOMAIN', 'example.org' );
define( 'WP_TESTS_EMAIL', '[email protected]' );example.org is not a real domain, so Cypress cannot visit it to start the end-to-end tests.
- override the constant with some kind of hack
- redirect
example.orgto ? usinghostsfile - use my own
wp-tests-config.phpsomehow - buy
example.org(joke)
Note that I've already modified install-wp-tests.sh, to use the following environmental variables:
WPUNIT_DB_USERWPUNIT_DB_PASSWPUNIT_DB_HOST
This change was made, to allow local dev and Travis to use different values here (via bash_profile and Travis settings), without exposing these in .yo-rc.json or on the command line (Travis build logs are public for open source projects).
It's therefore feasible that I could edit this file again. I could potentially follow the developer's lead and use sed calls to change out example.org for something more practical.
Make WordPress Core ticket #34000 suggests that WP_TEST_DOMAIN should be configurable.
And there's this:
wp-cli/wp-cli/features/bootstrap.feature:
# Use try to cater for wp-db errors in old WPs.
When I try `wp core install --url=example.com --title=example --admin_user=example [email protected]`
Then STDOUT should contain:
"""
Success:
"""
And the return code should be 0I also tried using the optional wp scaffold --url flag to set a different domain, but the generated wp-tests-config.php file did not reflect this change.
TMPDIR=${TMPDIR-/tmp}
TMPDIR=$(echo $TMPDIR | sed -e "s/\/$//")
WP_TESTS_DIR=${WP_TESTS_DIR-$TMPDIR/wordpress-tests-lib}
WP_CORE_DIR=${WP_CORE_DIR-$TMPDIR/wordpress/}
I couldn't track down where the value of WP_TESTS_DIR was set (and didn't look for WP_CORE_DIR).
However, it seems that there were ignored anyway, with the resultant paths only featuring $TMPDIR:
$WP_TESTS_DIR:/var/folders/0y/xxxxxxxx/T/wordpress-tests-lib$TMPDIR:/var/folders/0y/xxxxxxxx/T$WP_CORE_DIR:/var/folders/0y/xxxxxxxx/T/wordpress/
TMPDIR was easier to track down. It is an environmental variable, which is available on MacOS, and used by many apps to store temporary files:
OS X generates a programmatic directory stored in
/private/varand defines the $TMPDIR environment variable for locating the system temporary folder.Using Terminal.app, type
echo $TMPDIRoropen $TMPDIR(to open Finder on that folder).
echo $TMPDIR; # /var/folders/0y/xxxxxxxxxxxxxx/TIn PHP this is exposed with:
sys_get_temp_dir()In WP CLI this is in wp-cli/wp-cli/php/utils.php:
Utils\get_temp_dir()Although there is little in the way of documentation online, it’s clear that the var folder was designed to improve operating security. It was designed to improve permissions (rwxr-xr-x) over previous temp and cache locations, such as the /Library/Caches and /tmp folders. According to Apple developer information, the var folder is a reference to “per-user temporary files and caches.”
From: What is a var folder?
yarn run testThis runs gulp-modules/test.js:
const { stdout, stderr } = await exec( './vendor/bin/phpunit --configuration phpunit.dist.xml' );
console.log( stdout );
console.error( stderr );