booklista tech blog

booklista のエンジニアリングに関する情報を公開しています。

Docker + Capybara + appium_capybara + RSpec + クロスブラウザー(Stable + Beta版) を使用したリグレッションテストの自動化

アイキャッチ

はじめまして。プロダクト開発部QAエンジニアの岡です。
普段は弊社が総合的な運営をサポートしている電子書籍ストアのQA業務を行っています。
今回はQA業務として行っているリリース前のリグレッションテストを自動化したことについてお伝えします。

リグレッションテスト自動化に至る背景

弊社が開発を外部委託から内製へ切り替えるにあたり、品質と開発リードタイム短縮のためテストの自動化を進めるという目標がありました。
しかし、単体テスト自動化には課題があり直ぐに実現できないことから、開発工程で不具合が混入してしまう状況でした。

一例)

  • HTMLテンプレートにJavaScriptが直書きされているなどLinterによる機械的なチェックができずブラウザーの互換性担保が難しい
  • jQueryで実装しているためセレクターの書き方によって、予期せぬところで予期せぬ動作をしてしまうことがある

このように、E2Eによるリグレッションテストが効果を発揮しやすいプロジェクト背景もあり、まず、既存のコードから独立して進めることのできるリグレッションテストの自動化をQA主体で進めることになりました。

自動化で実施したこと

  • テストシナリオの選定
  • クライアント環境の選定
  • 環境構築

テストシナリオの選定

サイトのリグレッションテストを作成するにあたり、どの部分のシナリオを作成するか考える必要があります。
サイト内をすべて網羅できていれば安心ですが、シナリオ作成やメンテナンスのコストを考えると、主要部分にケースを絞ることが必要です。
対象は電子書籍サイトのため、以下の観点でテストケースを絞りました。

  1. ユーザーがサインイン、本を購入する、本を読むなどの読書体験に関わる箇所は最重要
  2. ボタンやリンクをタップしたときにアクションが起きる箇所は重要
  3. レイアウトの崩れはSeleniumのみで検知することは難しいため、1と2が問題無ければ自動化ではOKとする

クライアント環境の選定

次に、クライアント環境の選定です。ブラウザー依存の不具合を検出するため、対応デバイスを網羅するようにしました。

[対応デバイス]

  • デバイス
    • Windows
    • Mac
    • iPhone
    • iPad
    • Android
  • ブラウザー
    • Chrome
    • Safari
    • Firefox
    • Edge

さらにブラウザーのバージョンアップでの不具合も検出するため、ブラウザーのBeta版にも対応することにしました。

環境構築

以下が作成した環境のご紹介です。

使用技術

  • Docker
    • selenium/hub
      • Grid Hubイメージ(ブラウザー構成を一元管理するものです)
    • selenium/node-base
      • Nodeのベースイメージ(ここに各ブラウザーとドライバーをインストールしています。Chromeがすでにインストールされているイメージのselenium/node-chromeもありますが、Beta版に対応させたいためこちらを使用しています)
  • Capybara
    • ブラウザーの操作を自動化するためのgem
    • Seleniumのラッパー
    • RSpecを内包している
  • appium_capybara
    • CapybaraでAppium(Seleniumの一種、モバイル用)が使えるようになる
  • RSpec
    • Rubyのテスティングフレームワーク。Webアプリの総合テスト(FeatureSpec)を記述する際に使用
  • AWS CodeBuild
    • クラウドでの定期実行に使用している

構成

構成図

こちらは、Windows側のdocker-compose.ymlの一部抜粋です。
RSpecコンテナに設置したテストスクリプト(RSpec)でテストを実行しており、全クライアント環境を共通のテストスクリプトで実施しています。

version: '3.8'
services:
  rspec:
    volumes:
      - ./rspec/test_code:/test_code
    build: ./rspec
    tty: true
    shm_size: 2gb
    env_file: .env
    ports:
      - 2222:2222
    depends_on:
      - selenium-hub
      - chrome-beta
      (略)
    environment:
      - TZ=Asia/Tokyo
  selenium-hub:
    image: selenium/hub:latest
    ports:
      - 4442:4442
      - 4443:4443
      - 4444:4444
  chrome-beta:
    build: ./chrome-beta
    environment:
      - TZ=Asia/Tokyo
      - HUB_HOST=selenium-hub
      - SE_EVENT_BUS_HOST=selenium-hub
      - SE_EVENT_BUS_PUBLISH_PORT=4442
      - SE_EVENT_BUS_SUBSCRIBE_PORT=4443
    depends_on:
      - selenium-hub
    shm_size: 1gb
    ports:
      - 5900:5900
  (略)

ChromeBeta版コンテナのDockerfileでは、selenium/node-base:latestをベースに、 Beta版のChromeブラウザーとドライバーをインストールしています。
参考URL: docker-selenium/NodeChrome/Dockerfile

ここまで設定したら、 docker-compose -f docker-compose.yml up --build -d でdockerを起動します。
次に、テストを実行します。
こちらはテスト実行時設定(Chrome)の一部抜粋です。

require 'selenium-webdriver'
require 'capybara/rspec'

Capybara.register_driver :chrome do |app|
  capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
    'goog:chromeOptions': {
      args: ['headless', 'window-size=1200,970', 'no-sandbox', 'disable-gpu', 'disable-dev-shm-usage']
    }
  )

  Capybara::Selenium::Driver.new(
    app,
    browser: :chrome,
    url: 'http://selenium-hub:4444/wd/hub',
    capabilities: capabilities
  )
end


こちらは、テスト実行時設定(モバイルブラウザー)の一部抜粋です。
共通のテストスプリプトで実行させるため、appium_capybaraを使用しています。
※実施時にはホストマシンでAppiumが起動中である必要があります。

# Android Chrome
require 'appium_capybara'

desired_caps_android = {
  deviceName: 'emulator-5554',
  platformName: 'Android',
  browserName: 'Chrome',
  automationName: 'UiAutomator1'
}

url = 'http://host.docker.internal:4723/wd/hub'

Capybara.register_driver(:appium) do |app|
  appium_lib_options = {
    server_url: url
  }
  all_options = {
    appium_lib: appium_lib_options,
    caps: desired_caps_android
  }
  Appium::Capybara::Driver.new app, all_options
end
Capybara.default_driver = :appium


# iPhone Safari
require 'appium_capybara'

desired_caps_ios = {
  platformName: 'iOS',
  deviceName: 'iPhone Simulator',
  browserName: 'Safari',
  platformVersion: '15.5',
  automationName: 'XCUITest',
  locate: 'ja_JP',
  languge: 'Japanese'
}

url = 'http://host.docker.internal:4723/wd/hub'

Capybara.register_driver(:appium) do |app|
  appium_lib_options = {
    server_url: url,
    wait: 30
  }
  all_options = {
    appium_lib: appium_lib_options,
    caps: desired_caps_ios
  }
  Appium::Capybara::Driver.new app, all_options
end

Capybara.default_driver = :appium


特定のクライアント環境は、AWS CodeBuildを利用して定期実行をしています。結果はSlackで通知するようになっています。

環境構築で苦労した点

  • Chromeのバージョンアップでテストコードメンテナンスの発生する場合がある
    例えば、Chrome103ではテスト実行ができない問題が発生していました。 こちらはドライバーが対応されるまでの暫定対応として、headlessモードにすることで動作しています。ブラウザーバージョンアップに対応し、常にテストを実行可能にすることが課題となっています。

  • Safariブラウザーでの要素の操作に難航した
    通常のclick()ではタップがシミュレートできないため、JavaScriptを使用して要素をタップすることで回避しています。

リグレッションテスト自動化運用後の改善点

  • リグレッションテストの実行時間が、3日 → 1日になった
  • リグレッションテスト実行時間短縮により、開発のリードタイムの短縮に貢献した
  • AWS CodeBuildを使用した定期実行(Stable + Beta版)により、ブラウザーのバージョンアップによる不具合も検知しているため、サイトが安定して稼働している

さいごに

リグレッションテストを自動化することにより、開発~運用が改善されました。
弊社では、リグレッションテストだけではなく、単体テストの自動化の促進、ノーコードでテストを自動化するツールの開発などが進められています。
お客様が快適にサイトをご利用いただけるよう、テストを通して品質の向上を目指します。