スローテストを解消する12の方法

2012/01/10

システム開発において一番コストが高いものは人的リソースであることがほとんどだ。従って開発者の時間効率をあげるためにできることは色々と取り組む必要がある。例えば個人の開発マシンが遅くてビルドやテストに時間がかかるとかもっての他だ。一日10回ビルドして一回のビルドに5分かかるとする。これを高性能なマシンに変えたら2分になったとすると、(5-2)1020=10時間。時間単価5000円として一ヶ月あたり合計50000円の節約になる。同じことがCIやテスト自動化にも言える。

CIサーバのハードウェアを高性能なものに変更する

会社のあまったPCを使ったりして遅いテストを待つのはバカバカしいの一言だ。

CIサーバを複数台で構成する

上の話と同じような話。Jenkinsは複数台構成を取ることができるし、多分他のCIも同様だ。

CIサーバのディスクをSSDに変更する

ディスクのIOがボトルネックになるケースもある。サーバのスペックが良くてもハードディスクのIOはやはり遅いので、SSDに変えることによって高速化できる。場合によってはテストの所要時間が1/5から1/10になるケースもある。

テストで利用するデータベースをインメモリDBにする

上の話と似ているが、テストケースのsetUpで大量のデータをデータベースに登録するような場合どうしてもテストの実行に時間がかかるようになる。これをインメモリDBに変えることで高速化が可能だ。

テストスイートを分割する

コミット時に実行するテストと結合テストや受け入れテストを分離する。テストをグループ化しておき、必要なグループ単位で実行できるようにする。たとえばSCMへのコミットの際にユニットテスト群を毎回実行し、ユーザー受入試験などのテスト群はユニットテスト群が正常に通った場合のみに動かす、定時で動かすなどの工夫も出来る。

データベースを利用する箇所をモックに変える

データベースを利用するテストには時間がかかる。ユニットテストレベルでは一般的に外部のリソースと結合していないことを前提とした方が良いので、モック等に差し替えることを検討する。

外部システムとの連携テストの箇所をモックに変える

同上。外部のWebサービスやAPIとの連携のテストについても、モックを用意してそのテスト単体で動作するように依存性を排除していく。これによって外部システムの状態によってテストが落ちる/落ちないが変わるといった状況からは解決もする。

テストで利用するデータベースを最小データに保つ

自動テストを行う際にデータに本番データベースのコピーを使うのは最悪のアプローチだ。そうではなく、最低限のデータセットを用意し(fixture)、それを各テストで共通して使うようにする。共通部分以外のデータについては別で管理してテストケース毎に個別に呼び出すか、またはデータベースを然るべき状態に変更するためのAPI等を用意して、操作をエミュレートする。

SeleniumやWatir等のブラウザを通したテストだらけにしない

Seleniumなどのテストは、ブラウザをテストケース毎に起動して操作するので大変時間がかかる。ブラウザの起動に2秒くらい掛かったりするし。受け入れテストレベルの自動化は必要で、その際には全レイヤー横断型で画面のエビデンス等が取得できるSeleniumの試験は悪くはないが、全てのテストをレイヤー横断的に実装する必要性はない。経験的にはこのタイプのテストが多いとSlow Testになりやすい。入力チェック等のバリデーションはモデル単体でテストできるだろうし、本当にブラウザを通したテストが必要なテスト項目なのかをよく考えること。

テストの独立性を高める。他のテストに依存させない

テストの実行もユーザーストーリーと一緒でIndependentが望ましい。依存性の高いテストは複数のテストをシーケンシャルに実行することになりテストに時間がかかりやすい。また依存性が高いと仕様変更等があった際に多くのテストが動作しなくなる問題も発生しうる。テストのスコープを明確にすること。

テストを同一マシン上でも並列で動作するようにする

上記に関連してテストを同一マシン上で並列に実行できるようにする。このようにしようとすると必然的にテストにおいてデータベースの依存性を排除したりテストを小さい粒度に保つようになる。I/Oにボトルネックがない場合はテストの並列実行は効果が望める。

テストケースのsetUpメソッドを効率化する

各テストケースでは毎回ケース毎にsetUpメソッドが走ることが一般的だ。すなわちsetUpメソッドが遅いとテストの件数に比例してテストにかかる時間が長くなる。ムダなことをしていないかをチェックすべきだ。また前述の通りバカでかいテストデータを読むこむようなことは必然的な理由がない限り避けるべきだ。



2012/01/10

著作

CakePHPで学ぶ継続的インテグレーション

著者/訳者:渡辺 一宏 吉羽 龍太郎 岸田 健一郎 穴澤 康裕

出版社:インプレス( 2014-09-19 )

定価:¥ 4,320


Chef実践入門 ~コードによるインフラ構築の自動化 (WEB+DB PRESS plus)

著者/訳者:吉羽 龍太郎 安藤 祐介 伊藤 直也 菅井 祐太朗 並河 祐貴

出版社:技術評論社( 2014-05-22 )

定価:¥ 2,992


SCRUM BOOT CAMP THE BOOK

著者/訳者:西村直人 永瀬美穂 吉羽龍太郎

出版社:翔泳社( 2013-02-13 )

定価:¥ 2,520


Software in 30 Days スクラムによるアジャイルな組織変革“成功"ガイド

著者/訳者:Ken Schwaber、Jeff Sutherland著、角征典、吉羽龍太郎、原田騎郎、川口恭伸訳

出版社:アスキー・メディアワークス( 2013-03-08 )

定価:¥ 1,680


How to Change the World 〜チェンジ・マネジメント3.0〜

著者/訳者:Jurgen Appelo, 前川哲次(翻訳), 川口恭伸(翻訳), 吉羽龍太郎(翻訳)

出版社:達人出版会

定価:500円

どうすれば自分たちの組織を変えられるだろう?それには、組織に変革を起こすチェンジ・マネジメントを学習することだ。アジャイルな組織でのマネージャーの役割を説いた『Management 3.0』の著者がコンパクトにまとめた変化のためのガイドブック


寄稿

実践 Vagrant

著者/訳者:Mitchell Hashimoto

出版社:オライリージャパン( 2014-02-21 )

定価:¥ 2,808


Ryuzeeについて
Certified Scrum Professional (CSP) / CSM / CSPO in Japan. Twitterアカウントは@ryuzee →サイトが役立ったのでお布施する!

タグ
diary delphi books 書評 trac agile php apache インストールマニアックス maniax iis mysql postgresql perl sqlserver ruby オープンソース wordpress agilo scrum cakephp ユニットテスト yyyayeyaey publication tram 組織 linux プロダクトバックログ リーン ストーリーポイント ベロシティ ストーリー テスト 事例 契約 オフショア 管理職 スクラムマスター プロダクトオーナー デイリースクラム ふりかえり 受託開発 見積もり コーチ リーダー yyyoyy zen xp アンチパターン 可視化 doneの定義 recommended レビュー kaltrua vmware 自動化 fixture hudson 継続的インテグレーション kanban スプリント スクラム道 リリースプランニング カバレージ subversion scrum-of-scrum netbeans 朝会 バーンダウンチャート 調査結果 コミット devlove チーム bdd selenium アジリティ スプリント0 フィードバック ユーザーストーリー tdd sprint task スプリントレビュー スプリント計画会議 scrum-boot-camp scrumbc alm 継続的デリバリー ci user-story migration vagrant product-owner 継続的デプロイ continuous-delivery continuous-deploy continuous-integration jenkins デプロイ どうでもよいこと 日記 centos vim test commitment movie コードレビュー devops リリース 登壇 スコープ 評価 プランニングポーカー 見積り done ready agile-buffet agile-japan 講演 azure team-foundation-server team-foundation-service tfs 導入 eclipse visual-studio microsoft 技術的負債 defects lean daily-scrum grooming scrum-boot-camp-premium git ubuntu homeserver 監視 chef aws sahara packer lxc serverspec sensu dashing capistrano graphite 寿司 grafana docker slack deploy AWS Packer Jenkins AMI