RAKUS Developers Blog | ラクス エンジニアブログ

株式会社ラクスのITエンジニアによる技術ブログです。

複数サーバーでE2Eテストを並列実行してみた

noriharu3 です。

E2Eテストの実行時間短縮を目指して、複数サーバーでテストを並列実行してみましたのでご紹介します。

複数のサーバーでE2Eテストを実行する方法

元々E2Eテストは以下の構成で実装されていました。

Gradleを使用していたので並列実行するだけなら、パラメーターを設定するのみ。

なのですが、今回はE2Eテストを1つのサーバーで並列実行するのではなく、複数サーバーでE2Eテストを並列実行できないか模索しました。

理由としては、E2Eのテストケース毎にDBのロールバックが必要となっていたため、 1つのサーバーで並列実行することがそもそもできなかったからです。

E2Eテストを並列実行させる

Gradleを使っている場合は、パラメーターを設定するだけです。 終わりですw。

docs.gradle.org

// build.gradle

test {
  useJUnitPlatform()
  ++ maxParallelForks = 2
}

E2Eテストを複数のサーバーで並列実行させる

テスト実行前の事前処理で実行するサーバーを決定し、テスト毎に実行するサーバーを切り替えます。

具体的には、テスト未実施のサーバーリスト一覧をテキストファイルに保持しておき、そこからテストを実行するサーバーを決定します。

  • 処理の流れ
    1. サーバーリストから、テストを実行するサーバーを決定する
      • @BeforeAll に処理を追加することで実現
      • サーバーリストからサーバーを取得する際の排他制御flockコマンドでサクッと実装
    2. テスト実行する
    3. DBをロールバックする
    4. サーバーリスト一覧にサーバーを戻す
      • @AfterAll に処理を追加することで実現
// e2e_server_list
e2e_server_1
e2e_server_2
// E2EテストプログラムのAbstract Class

  ... (途中省略)

  @BeforeAll
  protected void リモートホスト割り振り() {
    Map<String, String> result;
    try {
      result = execCommand("sh", "server_pop_push.sh", "pop");
    } catch (IOException e) {
      throw new RuntimeException(e);
    } catch (InterruptedException e) {
      throw new RuntimeException(e);
    }
    setServerName(result.get("stdout"));
  }

  ... (途中省略)

  @AfterAll
  public void リモートホスト返却() {
    try {
      execCommand("sh", "server_pop_push.sh", "push", getServerName());
    } catch (IOException e) {
      throw new RuntimeException(e);
    } catch (InterruptedException e) {
      throw new RuntimeException(e);
    }
  }
}

  ... (途中省略)
// server_pop_push.sh
SERVER_LIST_FILE="e2e_server_list"
LOCK_FILE="/tmp/e2e.lock"

# 0/1/2以外の任意のファイルディスクリプタ(番号)を指定
exec 200>"${LOCK_FILE}"
flock 200

### メイン処理開始
if [ $1 = "pop" ]; then
  cat $SERVER_LIST_FILE | tail -n 1
  sed -ie '$d' $SERVER_LIST_FILE
elif [ $2 != '' ]; then
  echo $2 >> $SERVER_LIST_FILE
else
  echo '引数が不正です。'
fi

結果

結果として、2台のサーバーで並列実行したところ、テスト時間は約半分(40%)となりました。

Before

1台のサーバーで順番にテストを実行していました。

After

指定したサーバ台数で分散して、E2Eテストを実行できるようになりました。。
各サーバに均等に処理が振り分けるわけではなく、テスト未実施のサーバーに振り分けられます。
2台のサーバーで並列実行したところ、テスト時間は約半分(40%)となりました。

最後に

E2Eテストを

  • 分散
  • 並列実行

したブログは多くあるかと思いますが、これらは1つのサーバーに対して複数のブラウザを立てて処理を実行するものがほとんどでした。

DBのロールバックが必要など、何らかの理由で単純にE2Eテストを並列処理できず困っている方に、何らかのヒントを提供することができたら幸いです。

Copyright © RAKUS Co., Ltd. All rights reserved.