Selenium テストを並列化し、さらに 60% の作業効率化した話



前回のおさらい

  • Selenium を活用し、サービスの本番リリース時の動作確認作業を自動化した
  • 自動化により確認にかかる時間を 2時間→20分 に短縮できた

新たな課題


  • その後も増えつづける本番サーバ(オンプレ)
  • 半年で約2倍に
  • 自動化し楽になったが、また時間がかかり始めている

リリース作業の概要


動作確認テストを並列実行したい


How

  • JUnitで頑張る?
    • @Rule とか?
    • テストフレームワークに並列実行の責務をもたせるのはやりすぎ
  • Gradleで頑張る?
    • maxParallelForks を指定する?
    • テストクラス単位での並列化ではなく、サーバ単位で並列化したいので却下
  • Any other ideas?

それ xargs でできるよ


  • -Pオプションで最大並列実行数(プロセス数)を指定できる

実行コマンド

  • Before(直列)
# server_list.all.csv にテスト対象の全サーバを記述
$ ./gradlew clean releaseCheck -Plist=./server_list.all.csv
  • After(並列)
# テスト対象のサーバ一覧ファイルを分割して用意する
$ ls servers/
server_list.1.csv server_list.2.csv server_list.3.csv

# 3並列で実行する
$ find servers/ -type f | xargs -P 3 -Ifile ./gradlew clean releaseCheck -Plist=file

並列化した結果


  • 直列の場合と比べて、実行時間を 3分の1 程度まで短縮できた
  • 並列数を増やすとクライアントPC(ブラウザが起動するPC)のCPU負荷がボトルネックになり、実行時間の減少はゆるやかに
並列数 1プロセスあたりのテスト対象サーバ数 実行時間
1 (=直列) 30台 31分
2 15台 16分
3 10台 12分
4 7台, 8台 11分
5 6台 10分

まとめ


  • Selenium / JUnit / Gradle/ シェル それぞれの責務をうまく果たす/組み合わせることで、シンプルに課題を解決できた(UNIX哲学
    • 今回は Selenium はあまり関係なかったですね...スミマセン
  • 次は Docker と Headless Chrome あたりを使ってポータブルかつ、さらに高速化できないかと目論んでいる