Debugging PHPunit tests in Drupal 8 (Vagrant edition)

This blog-post I also published here


In this article we try to document how you can set-up your local development machine, to Xdebug inside tests. Including functional javascript!
The setup is documented here in this article and also in the Drupal docs here.

The quest started on the Dev Days Milano in 2016. With Drupal 8 the community tries to leverage automatic-tests where-ever possible.
A great thing, but when working with automatic tests I felt a bit like a blind man without a guidance-dog nor stick. As a developer it is possible to debug with tools like print_r(), but personally I would never recommend that.
My preference is Xdebug + PHPStorm. That's where this article is about.

The setup is a bit different than a typical Xdebug session that starts with a browser-request. Phpunit spins up multiple php-sessions via the CLI-interface. Everyone of those PHP-session should include Xdebug information that PHPstorm can leverage.
This setup uses the Drupal Vagrant Box from Jeff Geerlings. Although a bit more complex, it won't interfere with your local PHP-settings and that is a good thing.
Also we found it quite fragile to get it working well, therefore we chose to deepdive in the topic with a goal to get a fully replicable setup.

In this article

  1. Install Drupal Vagrant Box
  2. Change Drupal Vagrant Box configuration
    1.   What are we doing here?
  3. Validate that PHPStorm + Xdebug works for browser-based requests
  4. Run a test command-line and notice Xdebug is triggered
    1.   Debugging some runtime values from xdebug + vagrant and add them to Phpstorm
  5. Next level: functional javascript!

Install Drupal Vagrant Box

Jeff Geerlings is maintainer of Drupal-VM. An excellent toolset for local-development.

Please follow their installation-docs until you can open the Drupal-site installed on the Vagrant-box on your host-machine.

NB the host-machine is your laptop. And the client is the VM running on/in your host-machine.

Change Drupal Vagrant Box configuration

Drupal-VM has great default settings, but we need some extra.

Create the file "config.yml" in the root of your VM.
Add these values and save the file.

# Comment out any extra utilities you don't want to install. If you don't want
# to install *any* extras, set this value to an empty set, e.g. `[]`.
  - adminer
  # - blackfire
  - drupalconsole
  - drush
  # - elasticsearch
  # - java
  - mailhog
  # - memcached
  # - newrelic
  # - nodejs
  - pimpmylog
  # - redis
  # - ruby
  # - selenium
  # - solr
  - varnish
  - xdebug
  # - xhprof
# XDebug configuration. XDebug is disabled by default for better performance.
## Use PHPSTORM for PHPStorm, sublime.xdebug for Sublime Text.
php_xdebug_idekey: PHPSTORM
php_xdebug_cli_enable: 1
php_xdebug_remote_enable: 1
php_xdebug_remote_connect_back: 1
php_xdebug_max_nesting_level: 256
php_xdebug_remote_autostart: 1
php_xdebug_remote_port: 9000

Spin your box up again with the command "vagrant --provision"

# Do "vagrant --provision" and validate again.
# on host machine
cd ~/drupal-vm
vagrant --provision
# open drupal.vm in your browser


What are we doing here?

First we added "xdebug" as "installed_extras" to the VM. We only uncommented "xdebug" from the default settings. The other extras are default. You can find this in "default.config.yml".

Then there is the list of variables starting with "php_xdebug_". Those are PHP runtime settings. Some are default, but this is the complete list and we put it here for reference.

They are all important, but a couple are extra important.

> php_xdebug_cli_enable  # should xdebug run on the command-line? For sure!

> php_xdebug_remote_host  # this is the IP-address of your host machine as seen by the VM. Supercritical!

Validate that PHPStorm + Xdebug works for browser-based requests

In this article on PHPStorm website is documented how you should install and validate Xdebug inside PHPstorm.

The running Drupal-VM has support for Xdebug and it should work out-of-the-box for browser-requests when you follow their docs.

When you put a breakpoint in either "index.php" or "autoload.php" every browser-request should trigger your xdebug session.


Run a test command-line and notice Xdebug is triggered

# open the test-file and add a breakpoint in PHPStorm.
# our file:core/modules/text/tests/src/Kernel/TextFormatterTest.php
vagrant ssh
cd /var/www/drupalvm/drupal/web/core/scripts
php --sqlite /tmp/test.sqlite --file core/modules/text/tests/src/Kernel/TextFormatterTest.php

Read the paragraph if it is not working yet!!

Debugging some runtime values from xdebug + vagrant and add them to Phpstorm

So it is not working yet... Let find out "php_xdebug_remote_host".

Run a browser + xdebug request with a breakpoint. Lookup and write down PHP variable "SERVER_HOST" -> ... my case it was ""

Now edit your VM configuration file and change php_xdebug_remote_host to the right IP-address.

# Do "vagrant --provision" and validate again.
# on host machine
cd ~/drupal-vm
vagrant --provision

In my case I tested this on this setup:

  • Macbook with Sierra

  • PHPStorm 2016

  • Vagrant version ...

  • DrupalVM version ...

And with only one VirtualBox installed and running

Next level: functional javascript!

# open the test-file and add a breakpoint in PHPStorm.
# our file: core/modules/views/tests/src/FunctionalJavascript/ClickSortingAJAXTest.php
# ssh into your VM
vagrant ssh
# install phantomjs
sudo apt install phantomjs
# run phantomjs
# Open a second terminal
# on your host
cd ~/drupal-vm
vagrant ssh
## note: I got an error related to the display-driver. The 'export' line below 'fixes' this.
## @see
export QT_QPA_PLATFORM=offscreen
## note: I got an error related to write-permissions
## @see
## this happens in the host-machine, not in the vagrant box!
sudo touch /tmp/xdebug-remote.log
sudo chmod 666 /tmp/xdebug-remote.log
# time to start phantomjs
cd /var/www/drupalvm/drupal
phantomjs --ssl-protocol=any --ignore-ssl-errors=true vendor/jcalderonzumba/gastonjs/src/Client/main.js 8510 1024 768
# run the tests
# Go to the first terminal
cd /var/www/drupalvm/drupal/web/core/scripts
php --sqlite /tmp/test.sqlite --file core/modules/views/tests/src/FunctionalJavascript/ClickSortingAJAXTest.php



Disable "xdebug listening" in phpstorm when doing 'vagrant provision', 'vagrant up', 'drush' and 'composer'. Xdebug gives a big performance hit.