進行中の開発プロジェクトで増えていくテストを自動で回し続けるために行ったいくつかのこと

 進行中の開発プロジェクトで増えていくテストを自動で回し続けるために行ったいくつかのこと

2013/6/18 第6回テックヒルズにて発表

C94b14a077358ef2706819c62063bbc2?s=128

KUROKI Shinsuke

June 18, 2013
Tweet

Transcript

  1. 進行中の開発プロジェクトで 増えていくテストを自動で回し続けるために 行ったいくつかのこと 株式会社Aiming エンジニア 黒木 慎介

  2. 自己紹介 • 黒木 慎介 • Aimingのエンジニア(よくお昼寝している) • 主にRuby on Railsでお仕事

    • Jenkins歴は3年くらい
  3. 今日話すこと • あるプロジェクトでのJenkins – 使い方 – 増えすぎたテスト件数≒実行時間との戦い – 増えすぎた実行頻度との戦い –

    心構え • AimingでのJenkinsの使い方紹介
  4. あるプロジェクト • PC向けブラウザゲーム • Ruby on Rails + CoffeeScript +

    Backbone.js + α • 2011-12年にかけての約8ヶ月で開発 • 最初2人→最後10人で開発
  5. Jenkinsの使い方 • テストの実行 – Rspec(Ruby on Railsのテスト) • ci_reporterを使用 –

    Jasmine(JavaScriptのテスト)
  6. ci_reporter • Rubyのgem • RSpecの実行結果をXML出力する • Jenkinsは、このXMLを読んで – テストの成功件数・失敗件数を表示できる –

    ジョブのページで、失敗したテストの情報を表示 できる
  7. 増えすぎたテスト件数≒実行時間との戦い

  8. 増えるテスト件数 ※再現イメージです

  9. 増えるテスト件数 ※再現イメージです

  10. 増えるテスト件数 ※再現イメージです

  11. 増えるテスト件数 ※再現イメージです

  12. 増えるテスト件数 ※再現イメージです

  13. 地獄 • テスト7000件越え • 実行時間1時間越え • 手元でのテスト全件実行が困難→自動テスト の重要性は増す

  14. 地獄 • テスト7000件越え • 実行時間1時間越え • 手元でのテスト全件実行が困難→自動テスト の重要性は増す – 引き下がるわけには行かない!!

  15. 対策 • 分割して並行に実行 – スレーブ(VM上)を2台から6台に増設 – テストをカテゴリ別に分割して実行

  16. 分割に便利なもの(1):ラベル付け テスト全件 60分

  17. 分割に便利なもの(1):ラベル付け カテゴリA 20分 カテゴリB カテゴリC D 20分 15分 5分

  18. 分割に便利なもの(1):ラベル付け カテゴリA 20分 カテゴリB カテゴリC D 20分 15分 5分

  19. 分割に便利なもの(1):ラベル付け ノードの設定画面で:

  20. 分割に便利なもの(1):ラベル付け ノードの設定画面で:

  21. 分割に便利なもの(1):ラベル付け ジョブの設定画面で:

  22. 分割に便利なもの(1):ラベル付け ジョブの設定画面で:

  23. 分割に便利なもの(1):ラベル付け

  24. 分割に便利なもの(2):Join Plugin • Aが成功したら、BとCを実行して、両方成功し たらDを実行する • 最後にメトリクス計測とか

  25. 分割に便利なもの(2):Join Plugin

  26. 分割に便利なもの(2):Join Plugin

  27. 分割に便利なもの(3):Build Pipeline Plugin

  28. 増えすぎた実行頻度との戦い

  29. Gerrit • レビューシステム • ある変更がレビューを経てどう変化したかを 差分として見ることができる

  30. Gerrit Trigger Plugin • Gerritのレビュー依頼が提出されたら、 Jenkinsのジョブを実行 • 提出された全ての変更が対象

  31. Gerritレビューの流れ

  32. Gerritレビューの流れ

  33. Gerritレビューの流れ

  34. Gerritレビューの流れ

  35. Gerritレビューの流れ

  36. Gerrit Trigger Plugin • Gerritのレビュー依頼が提出されたら、 Jenkinsのジョブを実行 • 提出された全ての変更が対象

  37. そのとき、Gerrit Triggerは

  38. そのとき、Gerrit Triggerは

  39. そのとき、Gerrit Triggerは

  40. そのとき、Gerrit Triggerは

  41. そのとき、Gerrit Triggerは

  42. 地獄 • Jenkinsの実行が開発のペースに追いつかな い – 1回のレビュー提出で変更10個以上とか普通 – 増える開発人数 – 提出された差分のテストが終わらないうちに修正

    再提出された差分のテストが積まれたり – 朝来てもビルドキューが空になってない
  43. 地獄 • Jenkinsの実行が開発のペースに追いつかな い – 1回のレビュー提出で変更10個以上とか普通 – 増える開発人数 – 提出された差分のテストが終わらないうちに修正

    再提出された差分のテストが積まれたり – 朝来てもビルドキューが空になってない • Jenkinsの完了を待たずにマージ
  44. 地獄、しかし • 開発人員が増え、ペースが上がっていた • その分、テストが壊れる頻度もあがっていた

  45. 地獄、しかし • 開発人員が増え、ペースが上がっていた • その分、テストが壊れる頻度もあがっていた – 引き下がるわけには行かない!!

  46. 無駄なテスト実行を減らしたい • 既にマージされてる変更のテスト • 既に修正再提出されている変更の元のテスト • テストは成功終了でも失敗終了でもなく中断 させたい – テストしてないのに青や赤をつけたくないので

  47. Jenkinsのジョブを中断 % exit 0 % exit 1 ? → →

  48. 普段我々はどうやって Jenkinsのジョブを中断しているだろうか?

  49. 普段我々はどうやって Jenkinsのジョブを中断しているだろうか?

  50. Webから止めればいいじゃない!! • JenkinsのWebから中断ボタンを押した時には、 所定のURLにgetしているだけだった • 同じurlをcurlで叩く • そのあとsleepすることで次の処理の開始を抑 止する %

    curl http://jenkins/job/my_project_a/$BUILD_NUMBER/stop && sleep 60
  51. 心構え

  52. 心構え(1) • Jenkinsがやってくれるのは自動化だけ – 自動化する処理は自前 – だからこそ頑張り次第でいろいろできる

  53. 心構え(2) • Pluginのドキュメントをちゃんと読む – Jenkins Wiki – 必要な情報はだいたい変数に入れてある – それでも挙動がよくわからんときはある、が…

  54. 心構え(3) • なんだったらコードも読む – だいたいGithubにある ここからレポジトリへ

  55. 今日話すこと • あるプロジェクトでのJenkins – 使い方 – 増えすぎたテスト件数≒実行時間との戦い – 増えすぎた実行頻度との戦い –

    心構え • AimingでのJenkinsの使い方紹介
  56. 今日話すこと • あるプロジェクトでのJenkins – 使い方 – 増えすぎたテスト件数≒実行時間との戦い – 増えすぎた実行頻度との戦い –

    心構え • AimingでのJenkinsの使い方紹介
  57. AimingでのJenkinsの使い方 • ビルド – Android, iOS – ゲームサーバー(C++) • テスト実行

    • デプロイ • サーバー再起動 • データチェック
  58. 結果の通知

  59. データチェックをJenkinsで • 企画の人が作ったマスターデータ(Excelとcsv で、svnで管理)を、取り込んでデプロイ • データにミスがあるとデプロイが止まって困る • 取り込み部分だけをジョブ化 →ミスがあっても事前にわかる!

  60. 提供 ご清聴ありがとうございました!

  61. 時間が余った時用

  62. 分割に便利なもの(4):rakeのオプション • Ruby on Rails固有 • modelsだけで1時間かかるようになり、さらな る分割を行う方法として導入 • コマンドラインオプションで、実行するテストの

    ファイル名をパターン指定できる % rake spec SPEC='spec/models/**/[a-l]*_spec.rb‘
  63. 分割に便利なもの(4):rakeのオプション • コマンドラインオプションで、rspecに渡すオプ ションを指定できる • テスト項目にタグをつけておいて、tオプション でそれだけ流す/除外して流す % rake spec

    SPEC_OPTS=‘-t debt‘ % rake spec SPEC_OPTS=‘-t ~debt‘
  64. 既にマージされているか • Gerritのqueryコマンドを使う • status: mergedの結果の中に同じchange numberのものがあれば、マージされていると 判断できる % ssh

    -p 29418 -l s-kuroki gerrit_host ‘gerrit query project:my_project status:merged’ |grep "number: $GERRIT_CHANGE_NUMBER"
  65. 次のパッチセットが提出されているか • git ls-remoteで確認 f4a80a6171d8287 refs/changes/96/2996/3 →change number2996のPatch set 3

    % git ls-remote |grep $GERRIT_CHANGE_NUMBER/$((GERRIT_PATCHSET_NUMBER + 1))