Dockerを使って、Drupalのモジュールを開発する際に、Docker内のPHPUnitをPhpStormから実行する方法を紹介したいと思います。

ソースの取得

Drupal 8のソース

composer create-project drupal-composer/drupal-project:8.x-dev my_site_name_dir --stability dev --no-interaction

docker-compose.yml

↓の内容をファイル名 docker-compose.yml で保存し、Drupalプロジェクトのルートディレクトリに置いてください。

version: '3'
services:
  php:
    image: php:7.1-apache
    volumes:
      - ./:/var/www/html
    ports:
      - '80:80'

保存したらDrupalプロジェクトのルートディレクトリでdocker-compose up --buildを実行します。

PhpStormの設定

Dockerのphp設定を読み込む

Preferences > Languages & Frameworks > PHP を開きCLI Interpreter の右側にある ... をクリック

設定画面が開き左上の +をクリック。
Select Cli Interpreterから From Docker, Vagrant, VM, Remote... をクリック

Docker Compose をクリックすると、docker-compose.yml の内容が読み込まれるので、Servicephp に選択し、OK をクリック

↓の画面が開くので、再度 OK をクリック
General > PHP version: からDocker内で指定されたversionのphpが読み込まれていることが分かります。

↓の画像のようになっていれば設定完了です。

DockerのPHPUnit設定を読み込む

Preferences > Languages & Frameworks > PHP > Test Frameworks をクリックし、 左上にある+ボタンから PHPUnit by Remote Interpreter をクリック

先程設定したDocker上のphpをセレクタから選択

↓の設定画面が開くので、PHPUnit library 項目で Use Composer Autoloader にチェックが入っていることを確認し、その下の Path to script を Dockerコンテナ内の/var/www/html/vendor/autoload.php に設定します。
そして Test Runner 設定内の Default Configuration File/var/www/html/web/core/phpunit.xml と設定し、OKをクリック。 ※ phpunit.xml の元ファイルが、同じ階層に phpunit.xml.dist の名前であるのでコピーしておきましょう。

設定済みのPHPUnitが実行される設定

Run > Edit Configration... を開き、左上の+アイコンから PHPUnit を選択します。

nameという項目にこの設定の名前(任意)を入力し、Test RunnerDefined in the configration file にチェックが入っていることを確認して、OKをクリックします。

実際にPHPUnitを動かしてみる

サンプルのモジュールを作成し、そのモジュールに対してPHPUnitを動かしてみます。 ディレクトリ構造は、下の通りです。

modules
└── custom
    └── sample_module
        ├── src
        │   └── Controller
        │       └── SampleModuleController.php
        └── tests
            └── src
                └── Unit
                    └── SampleModuleControllerTest.php

SampleModuleController.php

<?php

namespace Drupal\sample_module\Controller;

use Drupal\Core\Controller\ControllerBase;

/**
 * Class SampleModuleController.
 */
class SampleModuleController extends ControllerBase {
  public static function foo() {
    return 'foo';
  }

}

SampleModuleControllerTest.php

<?php

namespace Drupal\Tests\sample_module\Unit;

use Drupal\Tests\UnitTestCase;
use Drupal\sample_module\Controller\SampleModuleController;

class SampleModuleControllerTest extends UnitTestCase {

  public function testSample() {
    $this->assertEquals('foo', SampleModuleController::foo());
  }
}

composer.json
開発環境でのみSampleModuleControllerTestからSampleModuleControllerを使用できるようにするため、autoload-devプロパティを追加しましょう。

    "autoload": {
        "classmap": [
            "scripts/composer/ScriptHandler.php"
        ],
        "files": ["load.environment.php"]
    },
+    "autoload-dev": {
+      "classmap": [
+        "web/modules/custom"
+      ]
+    },

phpunit.xml
今回はモジュールのみをテストしたいので、phpunit.xml の<testsuites>内を以下の用に修正します。

  <testsuites>
    <testsuite name="modules">
      <directory>../modules/custom/</directory>
    </testsuite>
  </testsuites>

<listeners>, <filter> 要素は今回は削除しました。

いざ実行!

赤矢印先のセレクタを先程作成したPHPUnitの設定に指定し、右側にある虫のアイコンをクリックし、PHPUnitを走らせます。

コンソール画面が表示され、無事Docker内のPHPUnitがPHPStormから実行でき、モジュールがテストできたことが確認できました!


共に働く新しい仲間を
募集しています

スタジオ・ウミは「Drupal」に特化したサービスを提供する Drupal のエキスパートチーム。
フルリモート&フレックス制だから、働く場所を選ばず時間の使い方も自由です。
そんなワークライフバランスの整った環境で、当ブログに書かれているような
様々な技術を共に学びながら、Drupalサイト開発に携わってみたい方を募集しています。
まずはお話だけでも大歓迎!ぜひお気軽にご連絡ください。