Skip to content

Instantly share code, notes, and snippets.

@quentint
Last active April 27, 2023 21:18
Show Gist options
  • Save quentint/6331aa9a75313ed955b2ea20d33557af to your computer and use it in GitHub Desktop.
Save quentint/6331aa9a75313ed955b2ea20d33557af to your computer and use it in GitHub Desktop.
Lando + PHPStorm/IntelliJ IDEA + PHPUnit

Lando + PHPStorm/IntelliJ IDEA + PHPUnit

Context

This gist is a follow-up to this Lando issue, updated for Docker Composer and Windows (but might also help macOS and Linux users).

Steps

Setup Docker

  1. Open File | Settings | Build, Execution, Deployment | Docker
  2. Click on the top-left "+"
  3. Case a: If you have (and want to use) Docker for Windows: choose "Docker for Windows"
  4. Case b (theorical, because unfortunately I could not get it to work): If your Lando instance is in WSL:
    1. Choose "WSL" and your Linux distribution
    2. Add one or more path mappings (in my case mapping /home/quentint to \\wsl$\Ubuntu\home\quentint was enough because my projects are stored in WSL's home directory)

PHP CLI Interpreter

  1. Open File | Settings | Languages & Frameworks | PHP

  1. Click on the three dots on the "CLI Interpreter" line
  2. Click on the top-left "+" and create CLI Interpreter "From Docker, Vagrant, VM, WSL, Remote..."

  1. Choose "Docker Compose"

  1. Click on the "Configuration files" folder icon
  2. Click on the top-right "+"

  1. Select all YAML files in C:\Users\[user]\.lando\compose\[project]
  2. Select "appserver" in the Service dropdown
  3. Click OK to close the "Configure Remote PHP Interpreter" window
  4. Choose "Connect to an existing container" in the "Lifecycle" section

  1. Click OK to close the "CLI Interpreters" window
  2. Click on the directory icon of the "Path mappings" section
  3. Add a local path mapping your project root to /app and click OK to confirm

PHPUnit

  1. Open File | Settings | Languages & Frameworks | PHP | Test Frameworks
  2. Click the top-left "+" to add a test framework
  3. Choose "PHPUnit by Remote Interpreter"
  4. Choose your newly created interpreter and click OK to close the window

When using Composer (you should)

  1. Choose "Use Composer autoloader"
  2. Set "Path to script" to /app/vendor/autoload.php

When using Symfony

  1. If not already there, create phpunit.xml.dist at the root of your project
<?xml version="1.0" encoding="UTF-8"?>
<!-- https://phpunit.readthedocs.io/en/latest/configuration.html -->
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd" backupGlobals="false" colors="true"
         bootstrap="tests/bootstrap.php">
    <coverage processUncoveredFiles="true">
        <include>
            <directory suffix=".php">src</directory>
        </include>
    </coverage>
    <php>
        <ini name="error_reporting" value="-1"/>
        <server name="APP_ENV" value="test" force="true"/>
        <server name="SHELL_VERBOSITY" value="-1"/>
    </php>
    <testsuites>
        <testsuite name="Project Test Suite">
            <directory>tests</directory>
        </testsuite>
    </testsuites>
    <!-- Run `composer require symfony/phpunit-bridge` before enabling this extension -->
    <!--
      <listeners>
          <listener class="Symfony\Bridge\PhpUnit\SymfonyTestsListener" />
      </listeners>
      -->
    <!-- Run `composer require symfony/panther` before enabling this extension -->
    <!--
      <extensions>
          <extension class="Symfony\Component\Panther\ServerExtension" />
      </extensions>
      -->
</phpunit>
  1. If not present, add KERNEL_CLASS='App\Kernel' to your .env.test file
  2. Open previous settings (File | Settings | Languages & Frameworks | PHP | Test Frameworks)
  3. Check "Default configuration file"
  4. Set path to /app/phpunit.xml.dist

Add Xdebug support

See this comment for detailed steps.

Run tests 😊

@GuyPaddock
Copy link

Unrelated to your issue @SlimDeluxe, but something I wanted to repost here: I got this to work in IntelliJ but my teammates running PhpStorm couldn't get it to work. Eventually, it turned out that it worked by chance for me because I had the Python plugin for IntelliJ installed, and a side effect of the Python plugin is that it remaps Windows paths into WSL paths when launching commands. PhpStorm doesn't have a Python plugin so this isn't an acceptable workaround there.

More here:
https://youtrack.jetbrains.com/issue/WI-71929

@quentint
Copy link
Author

Hmm, I am now running PhpStorm (without Python plugin) and it works pretty well 😉

@mortona42
Copy link

I'm able to run Unit and Kernel tests, but Functional tests are having issues with accessing urls and file permissions. I'm not sure how to configure PHPStorm to connect to the existing lando instance. When I select exec to run the existing container, it says the input device is not a TTY.

@quentint
Copy link
Author

@mortona42: I just published this gist with details that might be helpful to you: https://gist.github.com/quentint/265404e9fd9a6ada2893639006c0865b

@mortona42
Copy link

In PHPStorm, I had to enable the Docker Compose V2 option in the Docker tool settings, that fixed the TTY message.
Setting the test runner compose command to exec -u www-data fixed the file permission issue.

@SlimDeluxe
Copy link

Great success! 😄
It works for me now. I wish I could tell you what the problem was, but I don't know. In the meantime, my Linux kernel, Docker, PhpStorm etc. were updated. Maybe one of those was the problem. Anyway, the above approach works now and I am able to select appserver in the Service dropdown.

Also thanks to @mortona42 , the file permission problem is gone. To my surprise, it was not enough that the test ran through docker compose. The file created was still owned by root.
To recap: if you set up your test runner like this...

image

... any file created during testing will be owned by your (host) user and not root. The same way it works if you run lando phpunit.

The last problem is that PhpStorm tries to create the Clover XML in a dir that does not exist.

Generating code coverage report in Clover XML format ... failed [00:00.008]
Directory "/opt/phpstorm-coverage" could not be created

As you can see in the above screenshot, I tried setting a path for the XML report, but it's just ignored and PhpStorm appends another one with the problematic path.

image

I can't find any option how to properly set this path. 😏

@mortona42
Copy link

Path mappings are in the docker server settings:
Screenshot from 2023-04-27 10-50-24

@SlimDeluxe
Copy link

Isn't that path already mapped by Lando?
Trying this more portable solution from PhpStorm forums, I added it in service volumes like this and it works.

services:
  appserver:
    type: php:8.1
    via: cli
    webroot: .
    xdebug: "debug,coverage,develop"
    volumes:
      # Add directory for PhpStorm coverage XML report
      - ./build/coverage/xml/:/opt/phpstorm-coverage/

However it's strange that I see it as empty on the host, while files are present in the container.

image

It goes to show that I am still a Docker newb 😅

@mortona42
Copy link

I haven't tried to use coverage so I'm not sure if that's a hardcoded path or something. I was seeing /opt paths in the command phpstorm was running if I didn't set the path mapping.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment