Friday, 02 November, 2018

Debugging PHPUnit Tests On a Vagrant Virtual Machine

How to Debug PHP Unit Tests on a Vagrant Virtual Machine with XDebug and VS Code.

Preamble

A short article this time on debugging PHP Unit tests when using a Vagrant set-up.

I'm not going to go in to detail explaining what unit tests are or how to set them up using PHPUnit; I'm going to assume you already know how to do that. Neither am I going to explain Vagrant boxes or XDebug - that'd just make the post way too long.

What I am going to cover is how to debug your unit tests once you have PHPUnit configured and running on a Linux virtual machine using Vagrant (on VirtualBox) using the Visual Studio Code editor.

Installing XDebug

Installing XDebug on your Vagrant box is relatively straightforward provided you're using PHP7 if you use the official guidance at https://xdebug.org/wizard.php.

If you're installing XDebug for an older version of PHP you can find some guidance at https://stackoverflow.com/questions/49851639/error-while-installing-xdebug-in-php-version-5-6-32/51499173#51499173 but, to be completely honest, if you've never used XDebug before you're in for a tough time.

Configuring XDebug with VSCode

Once XDebug is installed you'll need to install the excellent PHP Debug extension for VS Code by Felix Becker: https://marketplace.visualstudio.com/items?itemName=felixfbecker.php-debug . You can do this from inside the VSCode extension manager - click, search for php and you'll see it.

The plugin comes with some detailed instructions; but in brief to use it you'll need to click the plugin's icon, open launch.json and copy in the standard configuration data below (if it isn't automatically generated), replacing path to your project on vagrant box with your actual path. For our purposes this path will be a path to the test project.

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Listen for XDebug with PHPUnit",
            "type": "php",
            "request": "launch",
            "port": 9000,
             "pathMappings": {
                 "path to your project on vagrant box": "${workspaceFolder}"
            }
        },
        {
            "name": "Launch currently open script",
            "type": "php",
            "request": "launch",
            "program": "${file}",
            "cwd": "${fileDirname}",
            "port": 9000
        }
    ]
}

So far, if you've set-up PHP debugging with VSCode before, this should all be fairly routine.

Configuring PHP

The next step is to configure PHP to use XDebug. The XDebug install instructions will have explained it, but the important part to note for our purposes is the remote_host entry below:

zend_extension="/etc/php/xdebug/255/xdebug.so"
xdebug.remote_enable=1
xdebug.remote_autostart = 1
xdebug.remote_port="9000"
xdebug.profiler_enable=1
xdebug.remote_host=192.168.33.1
xdebug.remote_connect_back=on

To debug unit tests you'll need this xdebug.remote_host entry. You can debug website's without it, but trust me, for PHPUnit debugging you'll need it.

Configuring Vagrant

You're probably wondering where you find the remote IP address of the host for your Vagrant machine?

On Windows you can type ipconfig and see and output like:

  Ethernet adapter VirtualBox Host-Only Network #3:
   Connection-specific DNS Suffix  . :
   Link-local IPv6 Address . . . . . : fe80::188a:8247:b8ab:b29f%4
   IPv4 Address. . . . . . . . . . . : 192.168.33.1
   Subnet Mask . . . . . . . . . . . : 255.255.255.0

On Linux or a Mac ifconfig should produce similar output.

The output here is showing my private network address for the static IP address I set-up for my Vagrant box in my Vagrant file, using:

 config.vm.network "private_network", ip: "192.168.33.2"

You'll need to amend your Vagrant file and vagrant reload (https://www.vagrantup.com/docs/cli/reload.html) if you haven't configured your box this way already.

The thing to "get" here is that I have a host 192.168.33.1 and a guest 192.168.33.22 and XDebug was configured to listen for remote connections from 192.168.33.1in the last step.

PHP Unit Instalaltion and Running the Unit Tests

If you haven't used PHPUnit before pop allong to https://phpunit.de/getting-started/phpunit-7.html and read up on how to install and use it. Once you have a basic test up and running you can read on to find out how to connect it to the XDebug debugger.

NOTE: I tend to install PHPUnit using a phar file as I've had issues with using it with Composer in the past.

For debugging purposes it's often useful to run one test at a time, you can do this with:

phpunit --filter myTestName

Visual Code - Setting a Break Point

Back in Visual Code, find your test, select the line of interest and either press F9 or click the margin to add a break point. A red dot will appear in the margin.

Select the PHPDebug plugin, press F5 or click the green "Go" triangle to start debugging.

Run your unit test again and if everything is configured correctly the code will break and you'll be all set.

Wrap Up

I know this post is niche. It's purpose is merely to help those of you scratching your heads wondering why debugging isn't working and maybe to help give some of you who haven't done this before a head start. If you're struggling feel free to drop me a line on email or on Twitter.

Want to Thank Me?

Did you like this article? Was it helpful? Why not buy me a coffee on Paypal? Buy me a coffee.