RedmineプラグインのシステムテストをPlaywrightで動かす


My Redmine

今週のブログ担当は石川です。
ファーエンドテクノロジーではRedmine本体の改善を行うとともに、RedMica UI ExtensionプラグインRedmine issues panelプラグインRedmine message customizeプラグインなどさまざまなプラグイン(やテーマ)を開発し、そのうちいくつかをオープンソースソフトウェアとして公開しています。
Redmineは継続的にRailsやRubyのバージョンアップが行われており、プラグインはRedmineのバージョンアップに追従する必要があります。追従するためには十分な自動テストを書くことが大切です。

今回のブログでは、Playwrightを使ってRedmineプラグインのシステムテストを行う方法について紹介します。


サンプルコードを公開しています

Playwrightとは

Playwrightは、Microsoftが開発したエンドツーエンドのテストツールで、Chromium、Firefoxなどのブラウザを操作してWebアプリケーションのテストを行うことができます。
Playwrightにはさまざまな機能がありますが、Redmineプラグインのテストをする上では特に環境構築の簡単さが魅力的です。

Playwrightを使ったRedmineプラグインのシステムテスト

https://github.com/ishikawa999/redmine_playwright_sample にサンプルコードを置いています。

Redmineプラグインとはいえ、Playwrightの導入方法は一般的な流れです。
Playwright Ruby Clientのドキュメント: https://playwright-ruby-client.vercel.app/docs/article/getting_started

1. Gemfileにテストに必要なgemを追加

# Gemfile
source 'https://rubygems.org/'

group :test do
  gem 'capybara-playwright-driver'
  gem 'playwright-ruby-client'
end
$ bundle install

2. Playwrightの準備

$ npm install playwright
$ npx playwright install
$ npx playwright install-deps

3. driven_byでシステムテストの実行時にPlaywrightを使用するように設定

# test/test_helper.rb
require_relative '../../../test/test_helper'

# systemテスト用
class PlaywrightSystemTestCase < ActionDispatch::SystemTestCase
  driven_by(:playwright, options: { headless: ENV['TEST_HEADLESS'] == 'false' ? false : true, browser_type: :chromium })

  Capybara.default_max_wait_time = 10
  Capybara.default_driver = :playwright
  Capybara.javascript_driver = :playwright

  def log_user(login, password)
    visit '/my/page'
    assert_equal '/login', current_path
    within('#login-form form') do
      fill_in 'username', :with => login
      fill_in 'password', :with => password
      find('input[name=login]').click
    end
    assert_equal '/my/page', current_path
  end
end

require_relative '../../../test/test_helper' では、Redmine本体側のtest_helperを読み込んでいます。こうすることで、Redmine本体側でテスト用に用意されている便利なメソッドや設定を利用できます。

その下ではActionDispatch::SystemTestCaseクラスを継承したPlaywrightSystemTestCaseを作って、その中でdriven_byでシステムテストの実行時にPlaywrightを使用するように設定しています。headlessがtrueの場合はシステムテストの実行時にヘッドレスモードで実行され、falseの場合はブラウザが表示されてどのように画面が操作されているかを確認できます。基本的にはheadless: trueモードで実行することが多いですが、デバッグのためにfalseにすることもあるため環境変数で切り替えできるようにしています。他のオプションはこちら: https://playwright-ruby-client.vercel.app/docs/article/guides/rails_integration#reference-available-driver-options
driven_by(:playwright)の記法はRails7.1から導入されたものなので、それより前のRailsを使っている場合はcapybara-playwright-driverのREADMEに書かれている記法を使ってください。

Capybara.default_max_wait_timeは、長いページの読み込みやアクションに時間がかかってテストが失敗してしまわないように少し長めにしています。

Capybara.default_driver、Capybara.javascript_driverは、JavaScriptで画面の書き換えが行われるときに正確にテストできるよう設定しています。

log_userメソッドはRedmine本体のシステムテストでもよく使われているメソッドで、頻繁に使うログイン処理をまとめています。

4. システムテストの作成

# test/system/sample_test.rb
require_relative '../test_helper'

class SampleTest < PlaywrightSystemTestCase
  fixtures :all

  test 'home' do
    log_user('admin', 'admin')

    visit '/'
    assert_text 'Home'
  end

  test 'Create issue' do
    log_user('admin', 'admin')
    visit '/projects/ecookbook/issues/new'

    assert_text 'New issue'
    fill_in 'Subject', with: 'issue subject'
    click_on 'Create'

    assert_text 'issue subject'
    assert_text "Issue ##{Issue.last.id} created."
  end
end

PlaywrightSystemTestCaseを継承してテストクラスを作ることで、Playwrightを使用したシステムテストを書くことができます。capybara-playwright-driverを使っていることで慣れ親しんだCapybaraのDSLをそのまま使うことができています。
ここでは利用していませんが、Playwrightが提供している機能も利用可能です。
https://playwright-ruby-client.vercel.app/docs/article/guides/rails_integration#playwright-native-scripting

5. 実行

$ cd /path/to/redmine
$ bundle exec rails test test/system

Run options: --seed 21714

# Running:

Capybara starting Puma...
* Version 6.4.2, codename: The Eagle of Durango
* Min threads: 0, max threads: 4
* Listening on http://127.0.0.1:33695
..

Finished in 3.765242s, 0.5312 runs/s, 2.1247 assertions/s.
2 runs, 8 assertions, 0 failures, 0 errors, 0 skips

ここまでの手順でPlaywrightを使ったRedmineプラグインのシステムテストを実行できるようになりました。

6. GitHub Actionsでの自動テスト

Playwrightの環境構築は簡単なので、GitHub Actionsでの自動テストも簡単に設定できます。

# .github/workflows/test.yml
name: Test

on:
  push:

env:
  RAILS_ENV: test

jobs:
  test:
    runs-on: ubuntu-latest

    strategy:
      matrix:
        include:
          - redmine-repository: 'redmica/redmica'
            redmine-version: 'stable-3.0'
            ruby-version: '3.2'
            artifact-id: redmica-stable-3.0
          - redmine-repository: 'redmica/redmica'
            redmine-version: 'master'
            ruby-version: '3.2'
            artifact-id: redmica-master
          - redmine-repository: 'redmine/redmine'
            redmine-version: 'master'
            ruby-version: '3.2'
            artifact-id: redmine-master

    steps:
    - uses: hidakatsuya/action-setup-redmine@v1
      with:
        repository: ${{ matrix.redmine-repository }}
        version: ${{ matrix.redmine-version }}
        ruby-version: ${{ matrix.ruby-version }}
        database: 'postgres:14'

    - uses: actions/checkout@v4
      with:
        path: plugins/redmine_playwright_sample

    - name: Set up plugin
      run: |
        bundle install

    - uses: actions/setup-node@v4

    - name: Install playwright browsers
      run: |
        npm install
        npx playwright install chromium
        npx playwright install-deps

    - name: Run tests
      run: RAILS_ENV=test bundle exec rake test TEST=plugins/redmine_playwright_sample

    - name: Store screenshots Artifacts
      uses: actions/upload-artifact@v4
      if: failure()
      with:
        name: screenshots-${{ matrix.artifact-id }}
        path: /home/runner/work/redmine_playwright_sample/redmine_playwright_sample/tmp/screenshots
        retention-days: 1

ベースとなるRedmineの環境構築は https://www.farend.co.jp/blog/2024/07/redmine-development-tools/で紹介されているhidakatsuya/action-setup-redmineアクションを使っています。
Playwrightの環境構築はInstall playwright browsers Stepで npm installnpx playwright install chromiumnpx playwright install-deps で行っています。開発環境と同じように簡単に使えて良いですね。

systemテストが失敗した場合に原因が特定しやすいよう、Store screenshots Artifacts Stepでテストが失敗した段階のスクリーンショットをアーティファクトとして保存して確認できるようにしています。

まとめ

RedmineプラグインのシステムテストをPlaywrightで動かす方法を紹介しました。テストを書くモチベーションを保つためにも、安定したテスト環境を整えることは大切です。よいテストライフを!

おまけ: Redmine本体のシステムテスト

Redmine本体のシステムテストは現在Seleniumで動いています。今回のブログを書くなかでRedmine本体のテストもPlaywrightで動かせるといいなと思い、https://www.redmine.org/issues/41094 でチケットを作ってパッチを投稿してみました。今後これがコミットされるかはわかりませんが、Redmineのテスト環境の改善に繋がったらうれしいです。

【スタッフ募集中】
弊社ではAWSを活用したソリューションの企画・設計・構築・運用や、Ruby on Rails・JavaScriptフレームワークなどを使用したアプリケーション開発を行うスタッフを募集しています。採用情報の詳細
弊社での勤務に関心をお持ちの方は、知り合いの弊社社員・関係者を通じてご連絡ください。

My Redmine

こちらの記事もオススメです!
Dockerを使うとRedmineのテストが少しだけ楽になりました
RedmineのテストにDockerを使うことで、仮想マシンの構築作業が不要になり楽になりました。
グアムで使ったeSIM Airalo と配車サービス Stroll
スマートフォンでの操作のみでインターネットに接続できるeSIMと配車サービス Strollをグアムで利用しました。
Intel MacからM3 Macへデータを移行しました
パソコンをIntel MacからM3 Macへ新しくしました。移行アシスタントとTime Machineのバックアップを使って、楽にデータ移行ができます。
Redmineとプラグインの開発を支える自作のツール
Redmineやプラグインの開発を行う中で、開発をしやすくするために自作したツールを二つご紹介します。
Redmine 18周年を祝う会 & 入門Redmine 第6版 出版記念パーティin 松江を開催しました
オープンソースのプロジェクト管理ツールRedmineのリリース18周年をお祝いしました。
ファーエンドテクノロジーからのお知らせ(2024/10/02更新)
2024年10月19日 オライリー本の全冊公開日のお知らせ(もくもく勉強会も同時開催)
ファーエンドテクノロジーが所蔵するオライリー本(全冊)公開日のご案内です。公開日には「もくもく勉強会」も同時開催します。
RubyWorld Conference 2024 (12/5・6開催) にPlatinumスポンサーとして協賛
ファーエンドテクノロジー株式会社は、2024年12月5日(木)〜6日(金)に島根県松江市で開催される「RubyWorld Conference 2024」にPlatinumスポンサーとして協賛しています。
プロジェクト管理ツールRedmineのクラウドサービス「My Redmine」の海外向けサービス「My Redmine Global Edition」の提供を開始
「My Redmine」の海外向けサービスとして、新たに「My Redmine Global Edition」の提供を開始しました。
Redmineの最新情報をメールでお知らせする「Redmine News」配信中
新バージョンやセキュリティ修正のリリース情報、そのほか最新情報を迅速にお届け