実行環境毎に環境変数を切り替えてPlaywrightのテストを実行する

エムスリーキャリアでQAエンジニアを担当している川浪です。

本記事では前回に引き続き環境変数を参照するPlaywrightのE2Eテストについて、実行環境毎に環境変数を切り替えてテスト実行する方法をご紹介します。

※前回の記事は、以下のリンクを参照してください

m3career-eng.hatenablog.com

 

 

前提条件

PlaywrightのテストをVisual Studio CodeVSCode)もしくはコンソールから実行します。

  • 前回の記事と同様、VSCodeの機能拡張「Playwright Test for VS Code」とNode.jsのライブラリ「dotenv」をインストール済み
  • 「TEST_ENV」という環境変数を使って、環境ごとに異なる設定を読み込むことを想定
  • 本番環境、ステージング環境、開発環境用に以下の.envファイルを用意
    • .env.production(本番環境用)
    • .env.staging(ステージング環境用)
    • .env.development(開発環境用)

.envファイルを読み込むコードを追加する

.envファイル名から読み込む環境設定ファイルを特定するソースコードを playwright.config.ts に追加します。

import dotenv from 'dotenv';
import path from 'path';

if (process.env.TEST_ENV) {
    dotenv.config(
        { path: path.resolve(__dirname, `.env.${process.env.TEST_ENV}`) }
    );
}

コマンドラインから実行

Windowsの場合、コマンドプロンプトを起動しPlaywrightのインストール先フォルダに移動後、以下のコマンドを実行します

(例)ステージング環境で実行する場合

set TEST_ENV=staging
npx playwright test

VSCodeからデバッグ実行

ローカル環境でVSCodeからデバッグ実行する場合、settings.jsonファイルに環境変数を追加します。

手順は以下の通りです。

  1. VSCode左下の歯車アイコンをクリックし、設定(Settings)メニューを選択します
  2. 設定画面が開くので、検索ボックスに「playwright」と入力し設定項目の表示を絞り込みます
  3. 表示された項目の中から「Playwright: Env」の「Edit in settings.json」を選択します

 

settings.jsonファイルが開くので、「playwright.env」キーに環境変数名と値を追加し保存します。

"playwright.env": {
    "TEST_ENV": "development"
},

 

以上で設定は完了です。

あとは「Playwright Test for VS Code」のインストールにより追加されたVSCodeのTestingビューを開き、Test Explorerに表示されているPlaywrightのテストをデバッグ実行します。

環境変数「TEST_ENV」で指定したenvファイルが読み込まれ、ファイル内の環境変数を参照してテストが実行されます。

おわりに

今回デバッグ実行の際に設定メニューから環境変数を追加しましたが、VSCodeの公式サイトではデバッグ機能について紹介されていて、launch.json というファイルに環境変数を設定してデバッグできるようです。

今後はこのデバッグ機能に関しても理解しておきたいと思います。

 

環境変数を参照するPlaywrightのE2EテストをVSCodeで実行する

エムスリーキャリアでQAを担当している川浪です。

本記事では、環境変数を参照するPlaywrightのE2EテストをVSCodeで実行する方法をご紹介します。

Visual Studio CodeVSCode)のTestingビュー(機能拡張「Playwright Test for VS Code」のインストールにより追加されるビュー)からPlaywrightのテストを実行したとき、自前で用意した環境変数が読み込まれない現象に遭遇したため、その対処方法について記載します。

本記事の前提条件

本記事の前提条件は以下の通りです。

- Playwrightをインストール済み(使用するスクリプト言語にTypeScriptを選択)

- Visual Studio CodeVSCode)をインストール済み、かつ、VSCodeの機能拡張「Playwright Test for VS Code」をインストール済み

- dotenvをインストール済み*1

 

.envファイルの作成

まずPlaywrightのプロジェクトフォルダ直下に「.env」という名称のファイルを作成します。

作成したファイルを開き環境変数を入力、保存します。

    ※入力例:
    LOGIN_URL='https://staging.example.com/'
    LOGIN_USER='hogehoge'
    LOGIN_PASSWORD='fugafuga'

playwright.config.ts ファイルの修正

Playwrightのプロジェクトフォルダ直下にあるplaywright.config.tsファイルを開き、.envファイルを読み込む以下のコードを追加します

    import dotenv from 'dotenv';
    import path from 'path';
    
    dotenv.config({ path: path.resolve(__dirname, '.env') });

Playwrightのテスト実行

VSCodeのTestingビューを開き、Test Explorerに表示されているテストを実行もしくはデバッグ実行します。

環境変数は、コード上で

process.env.環境変数

と記述することで値が参照できます。

 

おわりに

環境変数ですが、例えば本番、ステージング、開発環境毎に異なる値を参照させたい場合、playwright.config.ts で読み込む.envファイルを切り替えるコードを追加することで対応可能です。詳細は次回以降のブログでご紹介したいと思います。

参考URL

https://playwright.dev/docs/test-parameterize#env-files

 

*1:dotenvは環境変数を.envファイルから読み込むためのNode.jsのライブラリです。インストール方法は https://github.com/motdotla/dotenv を参照してください

BigQueryで緯度経度情報をH3情報に変換する

エムスリーキャリアでSalesforceの開発を担当している西村です。

ライドシェアリング事業を展開しているUber社が開発したH3というグリッドシステムとBigQuery上で緯度経度情報をH3で扱える情報に変換するための手法を紹介します。

H3を利用することで地理情報を国/都道府県/市区町村などの枠組みとは別の枠組みで集計・分析できるようになるため、様々な事業で今まではと異なるアプローチができるようになります。

 

H3とは

H3は、世界を六角形のセルに分割する地理空間インデックスシステムです。

https://blog.uber-cdn.com/cdn-cgi/image/width=2160,quality=80,onerror=redirect,format=auto/wp-content/uploads/2018/06/Twitter-H3.png

H3: Uber’s Hexagonal Hierarchical Spatial Index | Uber Blog より引用

 

各六角形のセルにはそれぞれ異なるセルIDがふられていて、H3には緯度経度をセルIDに変換する機能があります。

六角形のセルの大きさをどの程度にするかは0~15までの16段階で指定ができ、H3ではこの16段階を解像度という概念で扱っています。

h3geo.org

 

例として、東京駅の緯度「35.68130153」と経度「139.76708188」をH3を使って六角形のセルIDに変換してみます。変換する六角形の大きさとしては、1辺が平均26kmの解像度4と平均1.4kmの解像度7を指定します。

解像度が4の六角形に変換した時のセルIDは「842f5a3ffffffff」、解像度が7の六角形に変換した時のセルIDは「872f5a32dffffff」になります。
解像度が異なると同じ緯度経度でも異なるIDに変換されることがわかります。

この変換機能を含んだライブラリはC言語で書かれていて、PythonやJavaScritpなどの他の言語でも機能扱うことができます。

 

BigQueryで緯度経度情報をH3情報に変換

変換には以下を活用します。

GCSにh3-jsをアップロード

https://unpkg.com/h3-js からスクリプトをダウンロードします。

GCSに適当なバケットを作成して、ダウンロードしたファイルを作成したバケットにアップロードします。

JavaScript UDFを定義

h3-jsに緯度経度を六角形のセルIDに変換するlatLngToCell という関数があるのでこれをSQLから呼び出せるようにJavaScript UDFを定義します。

以下のようなUDFを定義して保存します。

CREATE OR REPLACE FUNCTION `project.dataset.h3_latLngToCell`(lat FLOAT64, lng FLOAT64, res INT64) 
RETURNS STRING LANGUAGE js
OPTIONS (library=["gs://hoge/h3-js.umd.3.6.3.js"]) AS R"""
return h3.latLngToCell(lat, lng, res);
""";  

UDF内の各々は以下のように扱います。

  • project : Google Cloudのプロジェクト名
  • dataset : UDFの定義先となるデータセット
  • h3_latLngToCell : このUDFの関数名。わかりやすい名前を付ける
  • library : 先程GCSにアップしたファイルのgsutil URI
  • h3.latLngToCell(lat, lng, res) : h3-jsの呼び出したい関数

SQLからの呼出

先程の東京駅の緯度「35.68130153」と経度「139.76708188」と解像度7を使ってUDFをSQLから呼び出してみます。

SELECT `project.dataset.h3_latLngToCell`(35.68130153, 139.76708188, 7)

実行結果として「872f5a32dffffff」を出力します。

 

最後に

今回はlatLngToCellを呼び出すUDFを作成しましたが、h3-jsの他の関数もUDFに定義すればSQLで利用できます。

h3-jsは他にも隣接するセルを返す関数やセルとセルがいくつ離れているかを返す関数があるので活用の可能性は大きいです。

活用例の一つとしては、飲食業界で1つのセルの中に競合を含む店舗数がどの程度あるかを集計することで市区町村といった切り口とは別の観点で今後の出店戦略を練るのに活かすことができると思います。

 

また、Kepler.glというブラウザ上で地理情報を可視化できるツールがあります。こちらのツールで算出したセルIDを含むデータをインポートすると、地図上でH3の六角形形式で可視化ができるのでぜひ試してみてください。

kepler.gl

エムスリーキャリアは東京Ruby会議12に協賛します!

こんにちは、@akitoshigaです。

表題の通り、エムスリーキャリアは2025年1月18日(土)に横浜市鶴見区民文化センター サルビアホールにて開催される「東京Ruby会議12」にSilverスポンサーとして協賛いたします!

 

regional.rubykaigi.org

 

東京Ruby会議12 は、プログラミング言語Rubyを使ったソフトウェア開発について議論する地域Ruby会議です。

エムスリーキャリアのプロダクトの多くはRubyを採用しています。

Rubyコミュニティのさらなる発展に貢献するため、今回の協賛を決定いたしました。

 

当日はノベルティの配布を企画しております。

また、エムスリーキャリアのメンバーも何名か参加予定です。

 

それでは皆さん当日は現地でお会いしましょう!

 

Kaigi on Rails 2024に参加してきました!

こんにちは。@akitoshigaです。

10/25に有明にて行われたKaigi on Rails 2024のDay1に有志のみんなで行ってきました!

当日の様子

 

エムスリーキャリアは今年スポンサーとして初の参加になりました。

会場ではエムスリーキャリアのロゴを掲載していただきました!

 

スポンサーブースもすごい盛り上がりを見せていました。



エムスリーキャリアはスポンサーノベルティとしてステッカーを用意しました。

こちらもたくさんの来場者の方に、お手に取っていただきました!

 

会場のホールはとても大きかったのですが、それにもかかわらず基調講演は満員になるほどの盛り上がりでした。

Vladimir Dementyevさんの基調講演『RAILS WAY, OR THE HIGHWAY』

セッションレポート

以下に自身が参加したセッションのレポートを一部掲載いたします。

Railsの仕組みを理解してモデルを上手に育てる - モデルを見つける、モデルを分割する良いタイミング 

オブジェクトを作成する際は以下を活用した方がよい。

  •  イベント型モデル
    • 『〇〇する』で表せるモデル
      • 適切なイベント型モデルを探し出せると、責務が適切なモデル設計が行える
      • モデルなのでRailsWayに沿っている
  • PORO(Play Old Ruby Object)
    • ActiveRecordを継承せずテーブルとも結びつかないクラス
    • Railswayから外れそうなな境界にあるのでチームでルールを策定するのがオススメ
    • クラス名には返却するオブジェクトの名前を名詞でつける
    • このルールに基づいていればモデルにしたくなったときに移行が容易になる
  • Serviceは作らない方が良い
    • Railsはレイヤー分割を減らして密結合にしている
    • 密結合することにより以下所に書いたコードが複数の役割を担当して認知負荷を減らしている
    • 新たなレイヤーを増やすことはRailsの利点をスポイルしている
    • Serviceをつくらないことで設計判断に迷いがなくなる
      • Serviceの定義が人によってバラバラになりがちなので、ならばいっそないほうが良いという考え
  • モデルを分割するタイミングはコードの量で判断しないほうがいい
    • そのまま書くのがつらくなったとき、かつそのときに良い分割方法があるときに分割する
    • 時間と共に良いモデルは変わるので、最初から最適化しようとしないのがオススメ

 

Serviceを作るなとよく耳にしていましたが、その理由を解説してもらえて良かったです。

再三にわたってServiceを作るなとおっしゃっていたのが印象的でした。

speakerdeck.com

 

Sidekiqで実現する長時間非同期処理の中断と再開

  • ジョブの停止にはデータや処理の不整合など懸念点が多い
  • 以前はタイミングをはかってSidkickを手動停止していたがつらい
  • Sidekiqのプロセス停止を検知して任意のタイミングで非同期処理を停止、それを安全に再開出来る仕組みを構築する

中断処理

  • Sidekiq設定ファイルにイベントハンドリングを設定する
  • Sidekiqの停止を検知したら例外を送出して処理を中断するメソッドを定義する
  • 中断処理はperformメソッド内の区切のよいタイミングにいれることでデータの整合性を保つことができる

再開処理

  •  Redisでジョブの進捗を管理するようにする
  • 再開時に中断したジョブを検索して再実行する
  •  CSVファイルなど行のデータを処理する場合は行番号を保持するようにする
  •  再開時に処理済みの行はスキップする処理を実装
  •  中断時に一時ファイルを退避させるにはGCSが最適

2024/7/3に公式からSidekiq Iterationが導入された

  • コールバックをつかえるので中断・再開時の柔軟な個別処理が実装しやすくなる
  • 現状はβ版だけど、今後導入する可能性がありそう

 

そもそも非同期処理を中断したり再開したりするのはなるべく避けるべきだと思っていたので実装方法がとても参考になりました。

例外を利用するのはなるほどと思いました。

speakerdeck.com

 

Capybara+生成AIでどこまで本当に自然言語のテストを書けるか?

  • 自然言語システムテストを書くことを目指す
  • 人間のテストのステップをそのまま生成AIに渡すとコンテキストもあるべき状態も情報が欠落してしまう
  • 人間から見たときは同じでも実装が異なるとテストは壊れる
  • 生成AIへ視覚や操作によるフィードバックを持たせることでこのギャップを埋める
  • 自然言語Rubyコードを出力してもらい、それによりフィードバックを得る
  • デモではUIが同じだけどCSSセレクタが違うものに対して自然言語で書かれたテストを実行
  • InputToolを使用すれば能動的なテストが可能になり 途中でミスをしても自動で軌道修正が可能

 

E2Eテストは壊れやすいのでこれが実用段階に進めば革新をもたらしそうだと思いました。生成AIが独自でフィードバックサイクルを回せるのが本当にすごいと思いました。

speakerdeck.com

 

さいごに

どれも実践に裏付けられた大変学びの深いセッションでした。

ここで培った知見を活かして、エムスリーキャリアのより良いプロダクト開発につなげていきたいと思います!

テスト駆動開発の勉強会を実施しました

こんにちは、@akitoshigaです。

エムスリーキャリアでは、社内の有志で不定期に勉強会を行っています。

先日、自身が主催となってテスト駆動開発(TDD)の勉強会を実施しました!

背景

ある日に自身が所属しているチームの開発方針について話し合う機会がありました。

その中でテスト駆動開発を取り入れるのはどうだろうという意見が上がりました。

チーム内にはTDDについて知らない・知ってるけどやったことないメンバーも多かったため、自身の方でレクチャーをする事になりました。

ただチーム内でのみ共有するにはもったいなかったので、勉強会という形で社内のエンジニアにも共有することにしました。

実施した内容

今回の勉強会のゴールを"TDDをやってみたいと思った時に気軽に出来るようにすること"と定めました。

自身のTDDを実践した内容を紹介したかったので、書籍などは使わず自身で資料を作成することにしました。

勉強会の内容は、作成した資料の発表とライブコーディングを行う形をとりました。

実施してみて

社内にTDDの共有ができた上、実際にTDDを実施してくれたメンバーがそのフィードバックを共有してくれました。

このような実践に基づくナレッジが社内に蓄積されることはとても重要だと考えています。

そのため、共有してくれたメンバーに感謝すると共にやってみて良かったなと強く感じています。

 

資料について

自身が今回の勉強会で作成した資料を共有します。

TDDについて、自身の実践を交えた概要とケーススタディについて記載しています。

みなさんのお役に立てば幸いです!

speakerdeck.com

 

 

 

 

 

 

Docker環境でPlaywrightを導入する方法

既存のDocker環境にPlaywrightを導入する手順をご紹介します。ここでは、テスト対象のサーバーがRailsで動作しているケースを前提に進めていきます。

なぜDockerでPlaywrightを動かすのか?

1コンテナ1サービスの原則に従う場合、Playwrightサービスは別コンテナで動かすことが推奨されます。これにより、既存のDocker環境を汚さずに済み、Playwrightに必要な環境が既に整っている状態で導入が可能です。また、依存関係を分離することで、環境構築やメンテナンスがより簡単になります。

Playwright導入のためのコード

PlaywrightをDockerで実行するためには、公式で提供されているDockerイメージを利用します。以下はその具体的な手順です。

1. docker-compose.yml
 playwright:
  image: mcr.microsoft.com/playwright:v1.43.1-jammy
  command: sleep infinity
  volumes:
    - ../:/usr/src/app
  extra_hosts:
    - "host.docker.internal:host-gateway"   
詳細な解説
  • image: mcr.microsoft.com/playwright:v1.43.1-jammy
    Playwrightの特定のバージョン(v1.43.1)と、Ubuntu 22.04 JammyベースのDockerイメージを指定します。このイメージには、Playwrightの依存関係がすべて含まれています。
  • command: sleep infinity
    コンテナを無限に実行し続けるコマンドです。これにより、Playwrightのテスト実行時までコンテナを保持しておくことができます。
  • volumes:
    ../:/usr/src/app は、ホストマシンの親ディレクトリをコンテナ内の /usr/src/app にマウントします。これにより、ホスト上のテストコードをコンテナ内で参照できるようになります
  • extra_hosts:
    "host.docker.internal:host-gateway" は、コンテナ内からホストマシンにアクセスするための設定です。通常、コンテナ内の localhost はコンテナ自身を指すため、ホストマシン上で稼働しているサービス(例:Railsサーバー)に直接アクセスできません。
    この設定により、host.docker.internal というホスト名を host-gateway に解決し、コンテナからホストマシン上のサービスにアクセス可能にします。

host.docker.internalとは?

host.docker.internal は、Dockerが提供する特別なホスト名で、コンテナからホストマシンのIPアドレスに解決されます。主に開発環境で使用され、コンテナ内のアプリケーションがホストマシン上のサービス(例えば、ローカルのデータベースやAPIサーバー)にアクセスする際に役立ちます。

host-gatewayとは?

host-gateway は、Docker 20.10.0以降で導入された機能で、コンテナ内からホストマシンのネットワークゲートウェイにアクセスするための設定です。これにより、コンテナとホストの通信が可能になります。

2. Railsの設定変更

Railsアプリケーションがdevelopment環境で動作している場合、デフォルトでは接続可能なホスト名が制限されています。コンテナ内からホストマシンにアクセスするためには、host.docker.internal を許可する必要があります。

config/environments/development.rb

Rails.application.configure do
  # 他の設定...

  # Dockerコンテナ内からホストマシンにアクセスするためのホスト名を許可
  config.hosts << 'host.docker.internal'
end

Railsdevelopment環境では、default で Rails.application.config.hosts に下記の Host が登録されています。

これ以外のHost 名として接続しようとすると、ブロックされるため追加で host.docker.internal を含めることで、コンテナ内からホストマシンに接続できます。

まとめ

この手順に従うことで、RailsアプリケーションをDockerコンテナ内でPlaywrightと連携してテストする環境を簡単に構築できます。Dockerを活用することで、依存関係の分離や環境の再利用が容易になり、より柔軟で効率的な開発フローを実現できます。