Adding Unit tests to a WordPress plugin via VVV and PHPUnit

While the official documentation can be found at https://make.wordpress.org/core/handbook/testing/automated-testing/phpunit/ , this is very far from being approachable to folks who are just starting (like me). It honestly took half a dozen of tries during the last year to make it work as expected.

While steps 1 ( Install PHPUnit ), and 2 ( Install WP-CLI ) are somewhat clear, step 3 ( Use WP-CLI to setup our plugin’s unit tests ) becomes extremely muddy very fast.

This has been haunting me for a while, as every time I have tried to make it work in the past it failed sooner or later through the process. Finally using VVV (as well as being more acquainted with solving the errors I was finding along the way) I was able to make it work, not without a full day of hiccups though.

Here’s a list of problems and its solutions I faced when making VVV and PHPUnit work for testing WordPress plugins. At the moment is pretty dry but I’ll try to keep updating it as I encounter new ones 🙂

This is based on this tutorial , which is the best I found so far.

Problem: Need to install PHPUnit via composer, but .phar instructions are given.

Solution:

Run:

> composer require --dev phpunit/phpunit ^7
> ./vendor/bin/phpunit --version

See:

> PHPUnit 7.5.16 by Sebastian Bergmann and contributors.

Problem: WP-CLI and wp scaffold plugin-tests your-plugin-name does not work

Solution: Needs to be run inside the virtual machine, not in the host machine (outside).

Run:

> vagrant ssh

The anchor will change to something like:

> vagrant@vvv:/srv/www/wordpress-one/public_html$

Run:

> wp scaffold plugin-tests your-plugin-name

See:

> Success: Created test files. 

Now if you ls -l in the plugin folder you'll see something like:

vagrant@vvv:/srv/www/wordpress-one/public_html/wp-content/plugins/woocommerce-pre-orders$ ls -l
total 148
drwxrwxr-x 1 vagrant www-data   128 Oct 12 00:32 assets
drwxrwxr-x 1 vagrant www-data    96 Oct 12  2019 bin
-rwxrwxr-- 1 vagrant www-data  7958 Oct 12 00:32 changelog.txt
-rwxrwxr-- 1 vagrant www-data   404 Oct 12 15:09 composer.json
-rwxrwxr-- 1 vagrant www-data 52397 Oct 12 15:04 composer.lock
drwxrwxr-x 1 vagrant www-data   480 Oct 12 00:32 includes
-rwxrwxr-- 1 vagrant www-data  2162 Oct 12 00:32 package.json
-rwxrwxr-- 1 vagrant www-data 54973 Oct 12 00:32 package-lock.json
-rwxrwxr-- 1 vagrant www-data   112 Oct 12 00:32 phpcs.xml
-rwxrwxr-- 1 vagrant www-data   389 Oct 12  2019 phpunit.xml.dist
-rwxrwxr-- 1 vagrant www-data   331 Oct 12 00:32 README.md
drwxrwxr-x 1 vagrant www-data   128 Oct 12 00:32 templates
drwxrwxr-x 1 vagrant www-data   128 Oct 12  2019 tests
drwxrwxr-x 1 vagrant www-data   480 Oct 12 15:30 vendor
-rwxrwxr-- 1 vagrant www-data 10581 Oct 12 00:32 woocommerce-pre-orders.php
drwxrwxr-x 1 vagrant www-data   128 Oct 12 00:32 woo-includes

Problem: Error establishing a database connection

Solution: When running the PHPUnit tests, WordPress will load the config from wp-tests-config.php instead of wp-config.php. You need to add your database connection details in wp-tests-config.php

Open wp-tests-config.php
See connection details
Run mysqladmin create DB_NAME --user=DB_USER --password=DB_PASSWORD --host=DB_HOST , in this case:

> mysqladmin create wordpress_test --user=wp --password=wp --host=localhost

Problem: mysqli_real_connect(): (HY000/2002): No such file or directory in …

Warning: mysqli_real_connect(): (HY000/2002): No such file or directory in /Users/iamgabrielma/vagrant-local/www/wordpress-one/public_html/wp-includes/wp-db.php on line 1612
Error: `No such file or directory`
Error establishing a database connection
This either means that the username and password information in your `wp-config.php` file is incorrect or we can’t contact the database server at `localhost`. This could mean your host’s database server is down.
Are you sure you have the correct username and password?
Are you sure that you have typed the correct hostname?
Are you sure that the database server is running?
If you’re unsure what these terms mean you should probably contact your host. If you still need help you can always visit the WordPress Support Forums. `No such file or directory`

Solution: Same as “Error establishing a database connection”

Problem: MYSQL . CREATE DATABASE failed; error: ‘Access denied for user … ‘

+ mysqladmin create wordpress_test --user=wp --password=wp --host=127.0.0.1 --protocol=tcp
mysqladmin: CREATE DATABASE failed; error: 'Access denied for user 'wp'@'localhost' to database 'wordpress_test’'

mysqladmin: CREATE DATABASE failed; error: 'Access denied for user 'wp'@'localhost' to database 'wordpress_test’'

Solution: Your user needs proper privileges:

Run:

> vagrant ssh
> mysql
> GRANT ALL PRIVILEGES ON * . * TO 'wp'@'localhost’;

Source: https://github.com/Varying-Vagrant-Vagrants/VVV/issues/913

Problem: PHPUnit returns “No tests executed”

vagrant@vvv:/srv/www/wordpress-one/public_html/wp-content/plugins/woocommerce-pre-orders$ phpunit
Installing...
Running as single site... To run multisite, use -c tests/phpunit/multisite.xml
Not running ajax tests. To execute these, use --group ajax.
Not running ms-files tests. To execute these, use --group ms-files.
Not running external-http tests. To execute these, use --group external-http.
PHPUnit 6.5.14 by Sebastian Bergmann and contributors.
Time: 2.99 seconds, Memory: 26.00MB
No tests executed!
vagrant@vvv:/srv/www/wordpress-one/public_html/wp-content/plugins/woocommerce-pre-orders$

Solution: By default phpunit.xml.dist will exclude the sample test.

Open phpunit.xml.dist
Comment <exclude>./tests/test-sample.php</exclude>

Run:

> phpunit

See: OK (1 Test, 1 Assertion)

Problem: Could not find /tmp/wordpress-tests-lib/includes/functions.php

vagrant@vvv:/srv/www/wordpress-one/public_html/wp-content/plugins/woocommerce-pre-orders$ phpunit Could not find /tmp/wordpress-tests-lib/includes/functions.php, have you run bin/install-wp-tests.sh ?

Solution:

If is the first time:

Run:

> bash bin/install-wp-tests.sh DB_NAME DB_USER DB_PASSWORD DB_HOST latest

In this case:

> bash bin/install-wp-tests.sh wordpress_test wp wp 127.0.0.1 latest

If is not the first time:

Exit from SSH:

> exit; 

Run:

> vagrant reload --provision
> vagrant ssh
> bash bin/install-wp-tests.sh DB_NAME DB_USER DB_PASSWORD DB_HOST latest

In this case:

> bash bin/install-wp-tests.sh wordpress_test wp wp 127.0.0.1 latest

Source: https://github.com/wp-cli/wp-cli/issues/2259
Source: https://github.com/Varying-Vagrant-Vagrants/VVV/issues/1931

Error: Massive file changes in GIT but only showing old mode vs new mode:

Solution:

Run:

> git config core.filemode false

Why? 

Most probably, the contents of this file haven't changed, only the executable bit has been cleared. Try actually changing the file by, say, appending an empty line to it, and see what git diff outputs.Apart from file contents, Git also records the state of the executable bit for each file. It makes sense on Linux systems if you want scripts to be executable right after checkout.

Source: https://stackoverflow.com/questions/16748160/what-does-it-mean-when-git-diff-shows-mode-changes/16748188
Source: https://stackoverflow.com/questions/1257592/how-do-i-remove-files-saying-old-mode-100755-new-mode-100644-from-unstaged-cha

And works! Just needed to jump through 16 loops on fire 😀

Leave a Reply