【Drupal8】phpunitテストでデータベースやモジュールを使いたい


Drupalで作っているシステム、自作モジュールのユニットテストを書いておこうと思ってやりだしたら思いの外手こずったのでコツをメモ書き。

継承する元クラスによってできることと速さとが違う

参考 : https://www.drupal.org/docs/8/testing/types-of-tests-in-drupal-8

Drupal8が用意しているテストには大きく分けて三種類あるらしい。
* ユニットテスト
* カーネルテスト
* ブラウザテスト

これらはphpunitモジュールを使う。
phpunitモジュールの他にもシンプルテストというのが検索すると出てくるが、これはどうも古いやり方らしく「もう使わないでね!phpunit使ってね!」というドキュメントに行き着くので調べてない。

今回はユニットテストとカーネルテストを書いたのでこのふたつについてわかったことを。

ユニットテスト

  • Drupal\Tests\UnitTestCase を継承して作る。
  • そのモジュール内で完全に完結する処理のテストに使う。
  • Drupal処理で普通に使えるサービスやモジュール(データベースやコンフィグ)が使えない。
  • 動作がすごく早い。

カーネルテスト

<?php

namespace Drupal\Tests\my_custom_module\Kernel;

use Drupal\KernelTests\Core\Entity\EntityKernelTestBase;
use Drupal\node\Entity\Node;

class MyXxxxTest extends EntityKernelTestBase {

  /**
   * Modules to install.
   *
   * @var array
   */
  public static $modules = ['my_custom_module', 'node', ];

  /**
   * {@inheritdoc}
   */
  protected function setUp() {
    parent::setUp();
    $this->installConfig(['my_custom_module', 'node', ]);
  }

  …

SQLを書く際の注意点

  • カーネルテストでは、テストごとにトークン文字列がサフィックスとして付いたテーブルが生成されてそこでテストが実行されるらしい。
  • 自作処理内でデータベースを扱う箇所で、SQLクエリを直接書いてる箇所があったら書き方によってはテストとうまく連動しないので注意する。
    • SQLクエリにテーブル名を記述する際、「 {table_name} 」というふうに{}で囲む。こうするとテスト時に動的にそのテスト用のテーブル名に置き換えてくれるようだ。