CIのテスト環境にDockerを導入して自動テストを高速化してみた。
はじめに
こんにちは。プラットフォーム開発部のいしがきです。普段はDMMサービス全体を支える会員基盤の開発をしています。
目次
- 概要
- 既存の自動テスト環境
- 既存の自動テスト環境の問題点
- 改善案 : Dockerの導入
- 実現方法
- まとめ
概要
今回はCI(継続的インテグレーション)の開発工程において、自動テスト環境にDockerを導入してテストの実行時間を高速化した事例を紹介します。
既存の自動テスト環境
まず、既存の自動テスト環境を紹介します。構成はごくごく一般的なCIの構成で、下記の図のような構成になっています。
1.リポジトリ管理はStashを使用しています。
開発者は日々、ソースコードを自身のトピックブランチにcommit,push→pull request(レビュー・承認)→統合ブランチ(master)にmergeの流れです。テストコードはPHPのテストフレームワークである、Codeceptionを使用しています。
2.テストの作業の自動化のツールにはJenkinsを使用しています。
このJenkinsがテストを実行するタイミングは、下記の2つとなっています。
(1) 1.の統合ブランチ(master)にmergeをフックに全テスト実行。
(2) 朝と夕方の定期実行で全テスト実行。
また、Jenkinsのジョブの構成はテストコードを分割し、その分割した単位ごとにJenkinsのジョブを作成。ビルドパイプラインを利用して全テストを実行しています。
※ビルドパイプラインについては次の節を参照ください。
3.テストの実行結果の成功、失敗の通知をHipChatに随時通知するようにしています。
既存の自動テスト環境の問題点
この自動テスト環境を運用していくにあたって、いくつかの問題点があがりました。
1.テストの量が100~200....と日々多くなってくると、単純にテストの実行時間が長くなってくる。 実際、テストケースが200~300程度で、15~30分ほど時間がかかっていました。 2.テスト時間短縮のために、ある程度ジョブ同士を並列で実行していましたが、さらに粒度をあげようとすると ジョブ同士が干渉して、テストが失敗することがあります。 (下記図) などなど..
ビルドパイプラインのイメージです。(緑のブロックがひとつのジョブです)
改善案 : Dockerの導入
上記の問題点のところを解決するために、CI環境にDockerを導入してみました。Dockerについての説明は、様々なところでされているので省きます。
改善案として、Dockerを導入することの特徴・メリットは以下です。
1.JenkinsのジョブをDockerのコンテナの中で実行することで、テストの実行環境が常にクリーンに保たれる。
2.Dockerのコンテナ内で動いているのはマシンではなく単なるプロセスなので、ジョブ同士の並列実行にも耐えられる。
上記の特徴から、構成図とビルドパイプラインのイメージは以下のようにすることができます。
自動テスト環境の構成図
ビルドパイプラインのイメージ
実際の業務で試してみたものを参考にすると、1121.8秒(約19分)→346秒(約6分)ほどに短縮することができました。
仕組み上は、もう少し短縮できると思いますが(※) 運用していくにあたって、この時間短縮で十分なためここまでにしています。
(※)テストをさらに分割し、ジョブを作成→並列の粒度をあげる
実現方法
ここでは、Dockerのイメージ作成の設定ファイルであるDockerfileの中身とJenkinsの実行方法に関して、簡単に説明したいと思います。
1.Dockerのコンテナの中で、テストを実行できるようにするためのDockerのイメージ作成。
Dockerイメージの作成はDockerfileの中で構成管理ツールのAnsibleを利用し、テスト実行環境を作成しています。
Dockerfile
2.JenkinsではそのDockerのイメージをもとに、コンテナを立ち上げテストを流すためのJenkinsの設定。
1. で作成したDockerのイメージをもとにテストを実行していきます。
Jenkins
まとめ
以上、「CIのテスト環境にDockerを導入して自動テストを高速化してみた。」の紹介でした。
皆さんもテストの実行時間が長いと感じた時は、試してみてはいかがでしょうか。