テスト自動化その前に! 素人が一生懸命考えた「実践アジャイルテスト」

感想おまちしてます!

-shared-img-thumb-SAYA160312500I9A3721_TP_V

この記事は、ソフトウェアテストの専門家でもなんでもない僕が考えたアジャイルテストのお話です。実際に遭遇した課題や問題に対して考えたりアクションしたことをまとめています。結果的にうまくいったこともあれば、うまくいかなかったこともあり、いまだに悩むことは多くありますが、「何が正しいかなんてわかららない」とラルクアンシエルも言っているので、誤解を恐れず、断定的に書いています。なお、上のむちむち写真はなんとなく選んだものです。

スポンサーリンク

なぜ今アジャイルテストなのか?

ことの発端は「テストの自動化」が周囲で話題になってきたからです。これはこれで「ええこっちゃ」なんですが、徐々に過熱化して「なんでもかんでも自動化!」「自動化サイコー!」みたいな相談を受けるようになり、大失敗事例も目の当たりにして、テストについて改めて考えなおす機会が生まれました。

また、自分自身が体験したテスト問題もあります。昔、とあるサービス開発を担当していたときで、そのときはアジャイル開発手法をとりいれながら課題解決を進める立場でした。時間がたつに連れて、だんだん課題は減っていったのですが、そのしわ寄せがどんどんテストに移っていくように見えます。

具体的には、ストーリーの作成やバックログの整理といった前半戦から、開発という中盤戦。これらはとてもアジャイルにできるようになってきたのに、後半戦のシステムテストがボトルネックとして膨らんでいくのです。

しかしながら、テストの専門家は別部署にいて、ある程度まとめてテストするのに忙しく、手に入れたスピードを失うことなく進んでいく相談をしにくい状況です。結果、自分たちで課題を解決するしかなく、そのときもテストと向きあう機会になりました。

640px-Scrum_process.svg

Author: Lakeworks

後者はアジャイルやスクラムといった、新しいプロセスが原因としてあるかもしれません。よく紹介される上記のプロセス図ですが、作業の流れはとてもわかりやすく説明されていても、それ以外の細かいアクティビティがさっぱりわかりません。その影響か、僕の周りでは、新しいプロセスの中でテストはどこでどうすべきなのか? といった疑問を持ち、迷ってしまう人が多くいました。

このつぶやきはそういった経験から生まれました。

課題や問題は何か?

-shared-img-thumb-HIRA86_bikespeedm_TP_V

僕の考える開発に対する大きなテーマは昔から変わっていません。それはずばり「速さ」です。そのためのアジャイル開発であったり、アジャイルなテストです。

一方、速さを阻害する問題は何か?

ひとつは「変化」があります。業界の変化やビジネスの変化。時代の変化や開発の変化。サービス開発はたくさんの変化にさらされており、その変化の波にうまくのり、持続的で継続的な開発が求められます。そして、その変化にうまく乗るためのコストがかかってしまったり、移り変わりに手間どってコストがかかってしまったりします。

部分的に変化を乗りこえ速くなっても、それ以外の部分が遅いままだと、総合的に速くなれません。しかしながら、いきなり全体に対してアプローチするのも難しい話です。僕の場合は、「まずは現場レベルでやってみよう」からはじまることが多いので、そこから生まれるボトルネックの移動をうまくコントロールする必要が多くありました。

-shared-img-thumb-freee151117071495_TP_V

もうひとつ思い浮かぶのが「負債」です。ソフトウェア開発の世界では「技術的負債」と呼ばれたりしますが、レガシーなシステムが抱える課題は、システムの規模によってふくらみ、システムが重要であればあるほど対応が難しく、時間がかかります。

新しくゼロからサービスを作る場合はいいですが、サービス開発は初期リリース後も開発は続いていきます。急な変化の暫定対応が恒久対応になってしまい、暫定が暫定を生むという負のループが発生します。それがどんどん負債になって積み上がっていき、開発スピードやサービス品質に悪影響を与えます。

開発だけでなく、テストに関係する負債も生まれます。テストケースがそろっていなかったり、ケースが膨大に膨れ上がって効率的に運用できていなかったり、その結果、テストに時間がかかってしまったりします。

本質的な課題は「変化への対応」ですが、変化と負債の間に因果関係があるため、両者をうまくコントロールする必要があります。

余談: 作るものを探す時代になってきた影響か、昔はプロジェクトベースの開発で問題なかったのですが、最近はプロダクト中心の開発が多くなってきた気がします。計画 < プロダクト。さらに、作るものを探す必要があるので、小さく作るようになりました。 小さく作るとテストも小さくなります。ひとつひとつの量は減るかもしれませんがテスト回数は増えます。小さいのが増えると管理や関連付けが複雑になります。小さくなると使い捨てがでてきます。 こういった時代の変化も、速さへの対応の難しさのひとつになっているのかもしれません。

どういったテストが必要で基準は何か?

スクリーンショット_052416_021147_PM

少し前にブームになったのが「アジャイルテストの4象限」です。『実践アジャイルテスト』という書籍に登場してその内容がとてもわかりやすく、いろいろなところで引用されるようになりました。

ただ、僕はこの図をどう使うかがあんまりよくわからなかったので、この視点で自分たちのテストを整理してみました。

単体テスト(UT)

  • 名前: UTと呼ぶことにします。
  • 担当: ENGが責任を持ちます。
  • 範囲: プログラムの最低限の機能保証をします。
  • 品質基準 / 完了の定義:
    • 単体テストを行っていること
    • セルフチェックリストを完了していること。
    • レビューが終わっていること。
    • SonarQubeのQuality Gateをクリアしていること。
  • 成果物: 簡単なチェックリストや単体レベルのテストケース、もしくは、xUnit等を使ったテストプログラムです。

昔、ある友人から教えてもらいましたが、PHPUnitの開発者であるSebastian Bergmannさんは、

単体は単体なのだから、API接続やDB接続を含めるべきではない

と言っていたそう(かっこいい!)。だから、単体の範囲をそろえておく必要があります。各自に認識の違いがあると、テストの狙いまでずれてしまい、結果的に、網羅性ががたがたになってしまい、バグがすりぬけてしまう可能性が高まります。

僕のときは、「メソッド = 単体」として、メソッドがDBやAPI呼ぶなら単体にしてしまいました。単体の処理が複数繋がると単体じゃないじゃん! という意見もありましたが、そういうときは、「これはプログラムレベルでやったほうがいいか? それとも画面レベルでやったほうがいいか?」を基準にシンプルに考えました。

扱うシステムがWebサービスなので、画面とそれ以外の区切りをつけたかったのが理由ですが、これだとバッチどうするねん! とかAPIどうするねん! とかいう意見もでてきます。僕の場合は「画面がないから単体」でなんとかできましたが、別の考え方でもいいかもしれません。重要なのはポリシーとその共通認識です。

ユーザ受け入れテスト(UAT)

  • 名前: UATと呼ぶことにしますが、エンドツーエンドテスト(E2E?)もいいですね。
  • 担当: 仕様の責任者(僕の場合、プロデューサーやプロダクトオーナー)が担当しますが、仕様を書く人とプログラムをデザインする人が協力してやったほうがよかったです。
  • 範囲: 作った画面が仕様通りかを保証します。
  • 品質基準 / 完了の定義:
    • テスト計画書が作成され、テスト範囲(スコープ)が明確になっており、関係者がその内容に合意していること。
  • 成果物: 仕様(機能)レベルのテストケース、WebDriverなどを使ったテストプログラム、これらを積み上げてできるレグレッションテストです。

UTがプログラムレベルなので、こちらは画面レベルです。ここでの考え方としては、UTとUATで大きな品質を確保&維持していこうとしています。

テストはさらに以下の種類に分類できます。

  1. アクションごとのテスト(数が多くテスト時間が短い。画面のあるボタンを押すなど)
  2. シナリオテスト(数は減らせるがテスト時間が長い。一連の流れ)
  3. 環境ごとのテスト(クロスブラウザ、クロスデバイス)

3は、1と2をブラウザやデバイスごとにやるので、対応する環境で指数関数的にテスト数が増えてしまいます。よって、3は間違いなく自動化しないと戦えないでしょう。

補足: テスト計画書の書き方

ここでいうテスト計画書は、テストスコープの定義に利用するとても重要なドキュメントです。その決定のためには、全体としてどこにどういったテストを配置しているか一目でわかり、今回狙う範囲を簡単に見つけられると便利です。

スクリーンショット_052416_022719_PM

例えば、僕はメンバーとこういったテストマップを考えました(サンプルとしてTwitter をベースに作ってみました)。横軸はよく使われる度合いで、縦軸は重要度になります。重要度はサービスの質によって異なる場合があるので、各サービスで決めればいいと思います。

これがテスト計画書の設計材料としてあり、スコープを決めていくのです。グラフに自分たちの機能をざっくり置いていき、関連性があれば線でつなぐなどの工夫もできます。

昔担当したプロジェクトでは、わざわざドキュメントを作るのが面倒だったので、ホワイトボードに書いていました。完成したら写真をとって保存するだけの簡単な運用です。

個人的には、この方法が一番効果的で、ケース漏れや影響範囲漏れが徐々に減っていきました。そこまでくると、次に時間がかかっているところはどこか? どうやって効率を上げるか(自動化するか)? の議論ができます。

プロダクトテスト(PT)

  • 名前: プロダクトテストと呼ぶことにしますが、総合テストとかもいいかも。
  • 担当: 関係者全員。テストの種類によってオーナーが変わる。
  • 範囲: 作ったシステムが期待通りかを保証します。期待値チェックや認識合わせが含まれるので、デモなどでまめに全体共有すると手戻りを防げます。
  • 品質基準 / 完了の定義:
    • 定性的な内容が多くなるので、それぞれのFBや課題に対する優先順位付けとアクションプランを決める。

テストごとの成果物を以下にまとめます。

  • 探索テスト、モンキーテスト、ユーザビリティテスト、サービス品質テスト:
    • 使い勝手、音声品質や通信品質といったテストがしにくい性質のテストです。関係者全員でテストを行い、成果物は「使ったときのフィードバック(感想、改善案や新しいアイデア)」です。
  • アルファ&ベータ版テスト:
    • リリース候補を限定した範囲に公開するため、リリース前の模擬リリースにもなります。使い勝手だけではなく、ある程度の規模の人数で動かしてみたり、実際のデータで使ってもらったりできます。ユーザからのフィードバックにはビジネス判断も技術判断も入るため、ビジネス側と開発側の両者でテストを依頼し、成果物は、「模擬リリース時のシステム情報(負荷など)」や「使ったときのフィードバック(感想、改善案や新しいアイデア)」です。
  • ABテスト:
    • アルファ&ベータ版テストに似ていますが、実際にリリースした環境でのテストを指します。リリース後なので開発プロセスの外側にあるテストですが、ここでのフィードバックがプロダクトや開発に影響をあたえるのは間違いないので、ここに含めておきます。評価したい機能のビジネス側の責任者と、技術側はビジネスとプロダクトを担当するプロデューサーやプロダクトオーナーがテストします。成果物は、「ユーザを使った効果測定結果」です。結果は部分的な向上があったとしても、全体的な低下があると関係性の判断が必要になるので、木を見て森を見る姿勢が重要です。

常にシステム全体をチェックするのは難しいので、新規追加や修正をした箇所、それに影響する範囲を中心にチェックします。また、これらの結果を踏まえて、ビジネスと開発といった責任をまたいだ範囲で合意形成を作ります。

経験的に、サービス開発だとこれ以外のテストの効率を上げて、このテストに注力するほうが、サービスが育つ気がしています。

システムテスト(ST)

  • システムテストと呼ぶことにします。
  • 担当: 技術側全員。実施は個人でもいいですが、その評価は全体でする必要があります。
  • 範囲: 非機能要件など、特別な観点ごとのシステム全体の評価を行います。
  • 品質基準 / 完了の定義:
    • パフォーマンスなど目標数値に達したか? その確認手順は間違っていないか? という合意形成を作ります。

テストごとの成果物をまとめます。

  • パフォーマンステスト: 成果物は、テスト内容とその結果の情報です。
  • セキュリティテスト: 成果物は、テスト内容とその結果の情報です。

リリースする機能や修正箇所にもよるのですが、スプリントで毎回やるテストでもなく、JMeterなどのツールでがんばる部分もあるので、どちらかというと3ヶ月毎とか定期的にやるテストでした。

スクリーンショット_052416_022004_PM

ここまで整理した「オレ流テスト」をまとめると上記のようになります。UAT部分は、WebDriverなどの登場でで劇的に楽になったので、これまでも中心的役割となったテストです。後述しますが、一方でUTの存在意義がだんだん薄くなってきた印象もあります。そのかわりに、プロダクトに向いたテストの重要性が増してきた気がします。

どう進めるか?

-shared-img-thumb-YUKA150701558664_TP_V

進める上での注意点を先にまとめます。

  • 一気にたくさん作るとコストも同時に増えていく問題。作ると分割や統合、修正といった、テストの運用管理(メンテナンス)コストが必要になります。どこから作って積み上げていくかの作戦が重要です。
  • UI変更で自動化した画面テストが全滅する問題。フロントエンドの変更スピードは速いので、Page Object Patternを使った自動テストコード作成など、影響を最小限に抑えるための工夫が必要です。

ある程度、UTやUATがあれば作戦も変わってきますが、まったく何もない場合を想定して、どこから攻めていくかを考えてみます。

UTから積み上げていく作戦

  • メリット: なんだろう?
  • デメリット: もっとも小さな単位からやるので、石垣を積み上げていく心の強さが必要。大抵の場合、城を立てる前に石垣が崩れる。

やるなら、重要なロジック(金額計算とか)に絞ってやるとよさそうですね。新規開発であれば、UTから積み上げやすそうです。

UATから積み上げていく作戦

  • メリット: 細かいパターンは網羅できないが、重要なシナリオを何本か自動化するだけで、クリティカルなフローをカバーできる。
  • デメリット: 画面テストは不安定だったり、データ準備が大変だったり。

今動いているサービスに対して外側から守っていく作戦なので、はじめやすいと思います。自動化していく場合の優先順位も、以下のように立てやすいでしょう。

  • 問題が起きたところから先にやる作戦: トラブルが起きた場所や、複雑でさわりにくい危険箇所を優先して守っていく。
  • よく使われる場所から先にやる作戦: もっとも多いユーザの行動パターンを優先して守っていく。ユーザの90%がとあるシナリオで動くなら、そのシナリオを自動化すればカバレッジ90%と考えられる。
  • 数値化で優先順位をつける作戦: リスクと自動化コストとマニュアルコストを数値化して優先順位を決める。『リーン開発の現場』でも紹介されている皆が合意しやすい作戦。

これまで、テストが揃ってない開発が多かったので、外側のテストから積み上げていくことが多いですが、その積み上げの結果、「よーし、やっとUTガリガリかけるぜー」となったことはありませんでした。

つまり、外側のテストだけである程度、開発が回るようになってしまったのです。そうすると、UTの恩恵をあまり感じなくなり、「UTいらない説」も出てきました。

UTがいるかいらないかはよくわかりませんが、その現場でそのテストが過剰なテストであれば、作らないと決めて作るべきテスト(探索テストとかABテストとか)に投資したほうが、コストに見あった効果を期待できそうです。

まとめ

-shared-img-thumb-JK92_kaerimichi20150208082355_TP_V

こうやって自分の経験や考えをまとめてみると、テストに対する知識の無さに愕然とします。ただ、実現したいのは、

  • うまくテストして
  • バグを減らして
  • アウトプットの品質を高める

なので、品質を作りこむために、テスト方法やチェック内容を定義し、どこでどうやるか議論し、そのために必要なドキュメントやツールを考える形になったのだと思います。

そのせいか、自動化は手段のひとつとして最後の方にちらっと出てくる感じ。それよりも前に、話したり考えたりすることがたくさんありました。

そして、残念ながら「こうやればバッチリ!」なものはほとんどなくて、状況によって異なるケースが多いので、アジャイルテストをどう実践するかも、メンバーと話しながら作り上げていくしかないのでしょう。

写真: 写真素材ぱくたそ