PHPUnit, PhpStorm and docker-compose

I wanted to run tests with PHPUnit on a docker environment, which was set up with docker-compose, and use the PhpStorm integration. Since PhpStorm 2013.2 there is a docker intergration which works well for single containers, but unfortunately it does not seem to use the running network of containers. So for example my PHP container does not get access to the MySQL container for integration tests.

If that’s not a problem for you, you will not need what I am going to explain here, read this instead: https://blog.jetbrains.com/phpstorm/2016/11/docker-remote-interpreters/

Local CLI Interpreter

So instead of configuring the Remote PHP Interpreter for Docker, I created a local interpreter like this and selected it as the CLI interpreter for the project:

The interpreter is actually a shell script that runs PHP in my container using docker-compose run. PhpStorm will not know that it runs in a container. I got the idea from this article and adapted it for docker-compose.

This is the test.sh script:

#!/bin/bash
docker-compose run integration php "$@"

Where “integration” is the name of the container.

docker-compose Configuration

For me the “integration” container is defined like this in docker-compose.yml:

  integration:
    build: ./config/php-integration-tests
    image: my-project/integration-tests
    volumes:
      - ./config/php/php.ini:/usr/local/etc/php/php.ini
      - ./config/php/php-fpm.conf:/usr/local/etc/php-fpm.conf
      - ./config/php/ext-xdebug.ini:/usr/local/etc/php/conf.d/ext-xdebug.ini
      - /tmp:/tmp
      - /path/to/project:/path/to/project
    env_file: .env
    user: www-data
    networks:
      - back
    depends_on:
      - mysql

Yours will look different, whatever the needs of your PHP container are. But the two highlighted lines that are important for the PhpStorm integration:

  • PhpStorm writes a temporary test runner to /tmp, so we mount the host /tmp directory to the container
  • The project directory must be mounted to the exact same path as on the host because there are no path mappings for a local interpreter and host paths will be passed to PHPUnit

Integrate the Test Runner

Now when you run a test file, or a phpunit.xml configuration in PhpStorm, the path is passed to our fake interpreter (test.sh) and …

Cannot find PHPUnit in include path

This error caused me some headache. I finally found out that the test runner that is generated by PhpStorm looks for “../../vendor/autoload.php” or “../../../vendor/autoload.php” within the include path. I’m not sure why it works like this, it seems to assume that it is run with the directory of the “phpunit” executable as working directory. Since “.” is usually in the include path, it finds the correct composer autoloader from there.

On the docker container this is not the case (the working directory on the host does not matter here). I tried to change the working directory there but in the end it was easier to change the include path in the “Run/Debug Configuration”:

Interpreter options:

-dinclude_path=/path/to/project/vendor/phpunit/phpunit

Now it works!

PhpStorm runs the command like this:

/path/to/project/test.sh -dinclude_path=/path/to/project/vendor/phpunit/phpunit /tmp/ide-phpunit.php --configuration /path/to/project/phpunit.xml

which results in this command being executed on the container:

php -dinclude_path=/path/to/project/vendor/phpunit/phpunit /tmp/ide-phpunit.php --configuration /path/to/project/phpunit.xml

If you mounted the paths correctly and the container is running, the tests will run on the container and PhpStorm “thinks” they run locally.

2 Replies to “PHPUnit, PhpStorm and docker-compose”

  1. Thanks for this. It helped me to know that others have the same problems. Sadly our tool stack means I’m on windows so the trick with having the exact same path on both sides doesn’t work for me.

    The good news is that it looks like we don’t have long to wait for first class docker-compose.yml support in PHPStorm. https://youtrack.jetbrains.com/issue/WI-33800 says it is due in version 2017.2 which is hopefully coming soon.

    For now I’ve given up with PHPUnit integration in PHPStorm and am running it from the command line.

Leave a Reply

Your email address will not be published. Required fields are marked *