BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ アーティクル 効果的なテストの文化を創る

効果的なテストの文化を創る

原文(投稿日:2014/08/06)へのリンク

自分が開発から運用まで責任を持った初めてのシステムのことをよく覚えています。幸運にも設計からサポートまでのすべてを任されました。数年後、そのシステムのひとつのサブシステムがよく使われるようになりました。継続的に機能追加の要望がくるので、複雑性は増していました。変更をするたびに、私は注意深く既存の機能を検証しました。手動の検証は時間がかかり、機能追加は爆発的に複雑になります。

多くの人と同様に、私は自動テストについて聞いたことはありましたが、その手法を学ぶ時間がありませんでした。そして、時間的余裕ができたので、私はいくつかの本を読んで、その手法を学びました。その手法を現実の仕事に適用した結果、成長するにつれて変更が難しくなるサブシステムの問題に対処するのに、自動テストは完全な方法であると感じました。ある日の午後、私はドライブに出かけていました。時間に余裕があったのです。インターネットにはつながりませんでしたが、テストを書くために必要なすべてのツールを持っていました。何日か後、手動で実施していた検証の細かい部分の大多数を自動化しました。時間の節約効果は多大なものでした。何時間も必要だったテストが数秒になりました。

しかし、時間の節約は2番目の効果でした。私の頭の中のすべてのシナリオが、大きく変化したのです。作ったものに対する信頼の感覚がよみがえったのです。まだ複雑性が増していない新しいシステムに対する信頼に似たものです。新しいリリースを行うときはとても心配でした。何度もチェックしました。しかし、何度チェックしようと、不安はなくなりませんでした。アプリケーションのリリースとサポートに責任を持っていたので、本能的にリリースを避けようとしていました。自動テストを一式作り、使うことで、恐れはなくなりました。

テストに漏れがあったら、単純にテストを追加し、二度と漏れないようにしました。自信が生まれたので、リスクを取って、新しい機能を追加することができるようになりました。また、不具合に怯えることなく、価値を提供することに注力することができました。

手動のテストの場合、テストシナリオは手動で注意深くセットアップし、手動で実行し、手動で検証しなければなりません。シナリオが誰かの頭の中に残るということはまれです。簡単に忘れられてしまいます。

自動テストの場合、シナリオ、実行、検証はすべてプログラムによってドキュメント化され自動化されます。唯一の手動のセットアップはシナリオ実行のボタンをクリックするだけです。記憶に頼る必要もありませんし、賞味期限の切れたドキュメントを頼って、シナリオを追いかけ、手動で実行する必要はないのです。

ほとんどの開発者が自動テストの価値を認めながら、その利点を享受するのに失敗しています。私は幸いなことに、利点を享受するための正しい方法を見つけることができました。

責任

テストに責任を持つことがなかったら、テストを自動化する時間はなかったでしょう。これはとても単純なことです。自分が開発を支援したシステムのサポートを担うことで、私はソフトウエアがきちんと動作することを保証するということに大きな関心を抱きました。午前5時に電話で起こされて問題を解決するのはごめんです。私は問題がその日のうちに解決するようにこつこつ働きました。

開発者は作ったものをどのように検証すればいいか一番よく知っています。どの部分に自信がないか、どこに複雑性があるか、どこに問題が含まれていそうか、知っています。開発者以外に包括的な視点を持っている人はいません。開発者は作業自動化の専門家であり、検証作業の自動化の適任者なのです。

多くの開発者は自分の開発したシステムをサポートすることができ、その責任を他に渡したがりません。何かを作った人はその作ったものが成功することを強く望むのです。私たちができることは各人が何に貢献したいと思っているのか尋ねることです。責任を共有し、開発者がシステムのサポートで貢献できるようにするのが、効率的なテストの利点を享受する方法です。

バラバラのチームを融合する

もし、組織がソフトウエア開発の責任を複数のチームに分散させていたら、テストをするのは大変です。残念なことに、顧客の手にわたってしまった欠点に対処する場合は、そのような大変さが常態化しています。

テストが他のチームにゆだねられた場合、ほとんどの場合手動のテストです。自動化されている場合も、メンテナンスするのが難しい、エンドツーエンドのテストです。エンドツーエンドのテストは本番環境と同等の環境をセットアップする必要があります。また、個別の部分を切り出すことができません。また、何かうまくいかなかった場合、多くのテストに影響を与え、意味のあるフィードバックを失敗から入手することも難しくなります。アプリケーションの更新で無効になってしまうような脆いエンドツーエンドのテストコードを定期的に更新するなら、手動テストに回帰するのは自然なことです。

分離されたテスターがアプリケーションの低いレベルをテストするための能力や知見を持っているのはまれです。特に効果的な検証が行われる必要があるユニットレベルのことは知りません。ユニットテストはシステムを小さなユニットに分離し、これらの部分をすべて検証します。このレベルでは、コードとアプリケーションに対する深い理解が必要です。開発者だけがこの知見を持っています。もし、分離されたテスターがこれらの知見を持っているなら、開発チームに参加しない理由は見当たりません。

加えて、テストの責任を手渡すとき、開発者にソフトウエアが正常に動くことに対する責任はないと伝える場合があります。しかし、そうすると、開発者に対して信頼していない、というメッセージを送ってしまうことになります。これは最悪のマイクロマネジメントです。私たちは検証待ちになるほどのたくさんの新しい機能を開発しています。実際にテストをしてフィードバックをするまでには数日、数週間かかってしまうでしょう。小さな問題が隠れていただけでも、新しい機能の実装の障害になり得ます。そして、機能実装が遅延すると急激に進捗が悪化してしまうのです。

このように分離するのは、自然かもしれませんが、結果的にはテスターのレイヤが厚くなり、何度も検証をするようになってしまいます。私は3つ以上の分離されたテストフェーズを持っている組織を知っています。この場合は、プロセス全体が止まってしまいます。ひとつの競合相手が責任を直接開発者と共有するやり方の利点に気づいたら、その他の企業は不利になり、最終的には競争に負けるかもしれません。

受け渡しをやめるのは効率的なテストをする上でとても重要です。ひとつのチームがテスト、サポートに責任を持つようにします。責任が複数のチームに分散されているなら、ひとつのチームに統合する必要があります。テスターは開発者の隣で仕事をするのです。または、各人がテスターと開発者の両方の役割を担い、相互にチェックを行ってバイアスを排除します。開発者がいくつかのユニットテストを書いて、別のテストチームに渡すのではなく、ユニットテストとエンドツーエンドの自動テストをするのか、それとも、手動のテストをするのかを状況に応じて皆で決めるようにします。

新しいチームの焦点を次の単一の機能、もしくは関連するいくつかの機能に絞るのがベストです。こうすることで、全員で一緒に働いてひとつの機能を開発しテストできます。関連のない変更のまとめたり、大きな変更のまとまりを開発チーム、テストチーム、サポートチームの間で数ヶ月かけて動かすのではなく、単一のチームで小さなリリースに必要なことをすべて行い、1週間から2週間の時間枠で作業します。この限定的な焦点の当て方は実際に生産性を向上させています。

小さな変更を行うことで、顧客からのフィードバックも素早く受け取れるようになります。変更が小さいので、テスト環境やステージ環境も簡単に準備でき、外部顧客のレビューもより焦点を絞ったものになります。顧客が確認したものについてもあいまいさがなくなります。フィードバックが来るのも素早くなり、フィードバックへの対応も遅れないようになります。大きなかたまりよりも小さな変更のほうがテストしやすいからです。素早くフィードバックを受け取り、素早く変更を行い、リリースして、次の小さな機能セットに移るのです。

自動テストの価値をデモする

チームの個々人が開発、テスト、システムサポートの責任を負うようになった場合、ふたつの選択肢があります。ひとつはチームが手動でのテストが効率的でないことに気づくまで待つこと。もうひとつはギャンブルを避け、チームを教育するという方法。ガイダンスなしで自動テストを実施するには数年かかります。個々人が日常の責務をこなすのに精一杯の状態では、特にそうです。自動テストに賛同しても、自動テストを習熟には数年かかります。しかし、専門家の力を借りて自動テストの価値を知らしめることで、この期間を短縮できる可能性があります。

自動テストの虜になって、十分な成果をあげた後、私は他の人も巻き込みたくなってきました。まず、デモを実施して、自動テストツールの活用方法を説明しました。しかし、私はこのやり方は失敗だったと考えています。直接実際のプロジェクトで自動テストを実施するのを支援するのではなく、テストの仕方を教えてしまったのです。教えるのは不十分なのです。テストの価値を証明する唯一の方法は、チームが実際に責任を持っている仕事に対して、テストを使って自信をはぐくむことを支援するという方法だけです。

もっとも効率的なのは、自動テストのテクニックを実践できる機会を作り、複雑でミスしがちなアプリケーションで使ってみることです。開発者は皆、頭を悩ますシステムを最低でもひとつは持っています。経験を自信に変えるには、現実にやってみるのが唯一の方法です。

個々の開発者が次のようなことを経験すれば、導入はより進むでしょう。

  • 複雑性を自動でテストすることに対する信頼。
  • テスト駆動開発の場合、コードを書く前にテストを書くことによって、ソフトウエア開発がはかどるということ。
  • テストが無駄になっているときは、テストを自動化するのは逆効果。このトレードオフがわからないと数年を無駄する。多くが自動テストを放棄する大きな原因。
  • ツールが自動テストの負荷を劇的に下げるということ。
  • テストによって、ソフトウエアの変更や機能追加が簡単になり、既存の機能もシンプルになるということ。
  • 既存の問題の根本原因分析、修正にテストが役立つということ。
  • 外部のリアルタイムシステムとの統合など、手動テストが不可能な領域で自動テストが効果を発揮するということ。

開発者のツールキットの中で自動テストに大きな価値があることを証明するのは簡単です。開発者が自動テストが仕事を改善してくれることを一度体験すれば、後は一気に価値が認められます。

命令を避ける

デモを実施してテストを広めることに失敗した後、私は少なくともチームが私についてこれる状態にしたいと思いました。そして次の失敗をしたのです。それは、アプリケーションの一部に対するテストを書くことを要求したことです。これが失敗なのは次のふたつの理由からです。

  • 私は責任を負いすぎました。私は何かよくないことが起きたとき、遅くまで残る役目でした。したがって、多くのテストは私の負担になりました。私はうまく動作しなさそうなシステムの一部に対するテストを選択しました。しかし、テストケースを受け渡す中でこの意味は薄れてしまいました。
  • 意味が薄れてしまったので、価値も感じられなくなりました。そして、性急にテストケースを作りました。その結果、テストケースの質が犠牲になりました。理解しにくく、いい加減で、ときには不正確なケースになってしまいました。命令をすることで多くのテストが生まれますが、それらのテストが使い物になるとは限らないと悟りました。目的のないテストは罰ゲームみたいなものです。役に立たないテストは有害で、メンテナンスしなければならないコードを増やします。さらに、使えないテストは長期的には混乱の種になります。というのは、システムのあるべき姿を記述したものとみなされる場合があるからです。

責任を共有し、特定のテストケースに利点がある理由を説明することは、大きな価値のあるテストを生みます。教訓はとてもシンプルです。つまり、命令を回避せよ。

他にもいくつか回避したほうがいい命令があります。

  • コードカバレッジの水準を命令する。
    • テストのコードカバレッジはテストケースをカバーしたコードの量を測定します。カバレッジが80%であれば、20%のコードはテストを実行しても、呼び出されません。
    • コードカバレッジはテストしていない領域を見つけるには素晴らしい効果を発揮します。しかし、テストの品質を保証するものではありません。テストケースの効果は測定できないのです。また、アプリケーションには、テストするのに値しない領域もあります。したがって100%のカバレッジを実現するよう指示をするのは賢くありません。
    • コードカバレッジの水準を指示するのは無駄なテストを多く生んでしまうのです。
  • コードが書かれる前にテストを書くように指示する。つまりテスト駆動開発(TDD)。
    • TDDは非常に重要な手法です。しかし、指示をして実行するような手法ではありません。アプリケーションには不確かな部分や事前のテストが有効でない部分があります。TDDの価値を示すのはよいことです。しかし、個々人が自分の判断において実践するべきです。
  • テスト数を命令する。
    • これはコードの行数を指示するのと同じです。意味がありません。
    • システムに無駄なテストがあるのなら、取り除くことも改善です。テストコードはメンテナンスする必要があるコードの量を増やします。

これらの命令によって個人は参ってしまい、無駄なテストが生まれ、システムのメンテナンスしやすさを劣化させます。

障害を取り除く

開発者が一度自動テストの価値を実感したら、障害を取り除くことが重要です。障害を取り除くことで手動テストのトレードオフを除去できます。テストを自動化することを難しくしている原因はどんなものであれ、自動テスト構築を実施しない理由のひとつに過ぎません。

障壁を取り除くためのツールはたくさんあります。

  • テストランナー
    • テストランナーを使うと素早くテストを実施できます。開発者が利用している開発環境と統合するといいでしょう。開発者がTDDを実践しているのなら、コードを書くのと同じくらいテストを簡単にできるようにしておきたいと思うでしょう。
  • コードカバレッジの計測
    • コードカバレッジは開発者にアプリケーションをどのくらいテストしているか教えます。更なるテストを推進するのにうってつけのツールです。
  • 継続的統合(CI)サーバ
    • 個々人がテストケースを実行するのに加えて、CIサーバを使って変更が発生するたびに、自動的にテストを実施します。
    • テストスイート全体を実施するのは忘れられがちです。セーフティーネットを構築しておくことはテストの価値を高めるでしょう。セーフティーネットがなくて、テストが無視されていた環境を何度も見たことがあります。テストが機能しなくなっていることにすら気付いていません。
    • テストが失敗したら、通知されますので、問題をすぐに直すことができます。
    • 開発者がCIサーバを信頼すると、作成したテストに対してより大きな価値を認めるようになり、その価値を享受するために、テストをすぐに作りたくなる。

これらのツールのコストについて議論になる企業を多く見てきました。皮肉なことに、多くのツールの開発者一人当たりのコストは、数時間の時給よりも低いのです。そのような効率的なテストを実現するという重要な役割を担うツールのメリットについて論じるのは時間の無駄です。

今すぐ、実践を通じて、ツールを使って障害を取り除きましょう。動き出すのが遅ければ遅いほど、手に入る価値も小さくなってしまいます。

余裕

技法を学び実践するのに必要な余裕もテストに対する障害のひとつです。開発者が空いた時間にテストをテーマにして学んでくれるのに期待するべきでしょうか。それとも、仕事中に、時間を確保し、そのような学習をサポートしたほうがいいのでしょうか。

私は長い間、さまざまなテスト技法の学習と適用に携わり、"自動テストツール"がどんなときに役に立ち、どんなときに無益かが本能的にわかるようになりました。

個人に対して余裕を与え、自動テストのスキルを磨くのを支援しましょう。

  • 高負荷なスケジュールを避けます。忙しさを排除したところに学習は生まれるのです。
  • 不必要な作業はやめます。例えば、手動で実施するテストケースを文書化することです。こうすることで自動化するインセンティブも生まれます。
  • 自動テストを無駄だと感じる顧客や利害関係者もいるかもしれません。神話は追い払いましょう。このような話で意欲を殺いではいけません。
  • 何が成功して何が失敗したかを頻繁に振り返りましょう。皆が学んだことを共有し、成果を擁護できるようにしましょう。

成果に着目する

私が携わった中でもっとも効果的なテストが行われたのは、全員がソフトウエアの成果に着目していたプロジェクトでした。どのようなレポートを作成するべきか指示を受けるのではなく、私は望ましいビジネス成果を理解し、どのような必要なレポートを決めるのを支援することができました。

システムのどの部分がもっともビジネス上の正常に貢献するのか理解していたので、その部分に注力しました。ビジネス上の望ましい成果を踏まえて、テストの優先順位を付けていたのです。加えて、成果の観点でテストを設計していたので、テストの期待値について顧客やユーザに直接説明できるようになっていました。

これは、テストから最大限の価値を引き出せた例です。ここを目指すべきです。ビジネスに価値を追加しないコードとテストを注意深く作成することほど気が滅入ることはありません。

信頼

腹痛を起こしたとしましょう。病院に到着したとき、あなたはマネジメントに症状を説明します。マネジメントは盲腸の上部の腹部を切開するための医師に診察を頼みます。そして、盲腸を切除するのを専門とする医師も呼びます。さらに、切開した腹部を縫い合わせる医師も呼びます。あなたは回復室に運ばれ、以後医師からの連絡はありません。まだ、腹痛がします。さらに診察してもらうと、痛みは胆嚢が原因でした。盲腸は問題なかったのです。

幸いなことに私たちはこのような世界とは無縁です。医師の仕事は内臓を除去することではありません。もっともそうするための専門能力は持っていますが。彼らは診察を頼まれ、注意深く分析した後、解決策を処方します。手術のときは、切開をして学んだことを基に診断を検証します。どのような場合も、正しい道筋を確保します。手術後も、施術が完璧であることがわかるまで患者を手放しません。感はは安全に回復室へ送られます。回復時も状況を確認し、回復を支援するためのアドバイスを準備します。医師以外の人も患者の容態を確認しますが、究極的には医師が患者の回復に責任を持ちます。

もし、医師に自分の命を預けることができるのなら、同じように自分が使うソフトウエアの開発者を信頼することだってできるでしょう。

著者について

Wes McClure氏はテクノロジーとソフトウエアで企業が目覚しい成果を達成するのを、情熱を持って支援しています。ソフトウエア開発の幅広い経験を持ち、ビジネスの目的に合致したソフトウエアを開発する方法の改善を行っています。氏はFull City Techを立ち上げ、専門性を活用して、高品質なソフトウエアを素早く提供したい企業を支援しています。

この記事に星をつける

おすすめ度
スタイル

BT