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
#!/bin/bash docker-compose run integration php "$@"
Where “integration” is the name of the container.
For me the “integration” container is defined like this in
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”:
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.