Personal tools
You are here: Home 原稿・資料 ソフトウェア・テストPRESS Vol.9 (2009年10月) 原稿 開発者から見たテストの現場
Document Actions

開発者から見たテストの現場

佐藤寛之(Tomoyuki Sato)

●●●● 開発者から見たテストの現場

●●● はじめに
 私はアリエル・ネットワーク株式会社の開発部ソリューショングループに所属しています。ソリューショングループは、プロダクトグループが開発しているグループウェア「Ariel AirOne Enterprise」(以下AAE)上で動作するアドインの開発を担当する部署で、お客様から頂いた仕様を基に開発を行う、パッケージというよりは受託開発に近い仕事です。主な担当範囲はプロジェクト管理とアドインの実装で、いわゆるテストエンジニアではありません。とはいえ、ソフトウェア開発においてテストを避けて通ることはできません。この章では、ソリューショングループにおけるテストへの取り組みの変遷と、これまでに携わった実際のプロジェクトにおける試行錯誤の事例と教訓を開発者の視点から紹介したいと思います。

●●● ソリューショングループ テストの変遷

●● チーム発足当初
 ソリューショングループが発足したのは2008年4月のことです。それまでアドインはコアパッケージの開発担当者やコンサルタントが副業的に開発していたのですが、案件数の増加に伴い、開発体制を強化するため専任のチームを立ち上げることとなりました。当時は第二開発部と呼ばれていましたが、今年の7月からソリューショングループという名称になりました。本章ではソリューショングループという呼称で統一します。私が入社したのは2008年6月で、5人目のメンバーとしてソリューショングループに加わりました。
 当時のソリューショングループには、開発プロセスと呼べるものは存在しないも同然でした。当時はまだコアパッケージに対するオプションという認識が濃く、軽く扱われがちだったのが要因と思います。コンサルタントが持ち帰ってきた仕様を基に、個々の開発者が実装し、ざっと動作確認を行ったものをコンサルタントがそのまま顧客先へ持って行く。テストケースを書くことすらまれ。これは、私にとっては恐怖でした。
 私の前職はメーカー系SIerのSEで、パッケージソフトウェアの開発を担当していました。非常に厳格な検査態勢がとられており、独立したQA部門による検査に合格しない限り成果物を社外に出すことはできませんでした。また開発中にも、各工程の完了時に同様に検査が行われていました(そう、忌まわしきウォーターフォールが社内標準なのです)。こうした環境で仕事をしてきた私にとって、不良密度やテストカバレージなどのメトリクス集計による定量的な品質管理や、開発者以外の第三者による最終的な品質保証は当たり前という感覚でした。
 アリエル・ネットワークに入社し、こうした品質保証プロセスのない環境に身を置いてみて、感じたこと、思い知ったことが数多くあります。まず最初に感じたのが、先にも挙げた恐怖感です。検査という最後の砦が取り払われた今、自分の書いたソフトウェアはそのまま顧客先で運用に晒されることとなります。このことから来るプレッシャーは相当なものでした。思えば、以前は自分がバグを見逃しても出荷前に誰かが見つけてくれる、という甘えがあったのだと思います。開発者が本来持つべき品質責任の重さ、というものを、この業界に入って7年目にして改めて実感させられました。
 しかし、この時感じたのは悪いことばかりではありません。開発に要する時間が驚くほど短い、というのも強く感じた点です。若干極端な例ですが、前職ではJavaScriptのコードを1行修正するプロジェクトで、約1ヶ月の期間を要したことがあります。コードの修正時間は10秒だとしても、品質計画、テスト計画、設計、テスト、ドキュメントおよびプログラムのレビューと検査、といったプロセスに必要な時間を積み上げると、これだけの時間がかかってしまうのです。一方でアリエルでは、稼働中のアドインに対する軽微な修正依頼であればせいぜい1〜2日。AAEのワークフロー機能を用いた申請系アドイン2本の新規開発で、開発者2人で開発開始から本番稼働まで約1ヶ月という事例もあります。この時点ではまだ体系的なテストが行われていなかったとはいえ、この開発の迅速さはお客様にとっても大きなメリットだと思います。これはリリース基準に対する考え方に起因するもので、完璧なソフトウェアではなく十分に良いソフトウェア、というスタンスはアリエルの強みの一つだと考えています。

●● テスト専任チームの設立
 アドイン開発の案件が増加するにつれ、お客様の要求も高度化・複雑化し、品質に対する要求水準も高まってきました。これを受け、ソリューショングループ内に専任のテストチームが設立されたのが2009年2月のことです。これにより、開発者とテストエンジニアの分業による品質保証体制が整いました。テストチームはコアパッケージの開発チーム内にもありますが、本章では以降、特に断りのない限りソリューショングループ内のテストチームを単にテストチームと呼びます。

● テストチームの初仕事
 体制は整ったものの、テストチームは早速難題に直面することになります。テストを行うにはテストケースが必要ですが、そもそもテストケースのないプロジェクトが数多くあるのです。このため、まずはテストケースを作成するところから始めることになるのですが、アリエルはドキュメントを書かない文化です。仕様書からテストケースを書き起こすという手が使えません。結局、アドインを実際に動かしながら、担当の開発者やコンサルタントに仕様を確認しながらテストケースを作成していくこととなりました。このアプローチの是非については後半で事例を基にして述べますが、ともあれテストチームの頑張りによって、今後の保守のための足場を整えることができました。

● 増え続けるテスト工数
 テスト体制も整い、テストケースも揃いました。これで品質保証体制は万全です。と言いたいところなのですが、今度は品質とは別の問題が浮上してきました。テストに要する工数です。テストチーム設立以前は前述の通りテストにかける時間は短かったので、テストを強化すれば当然ながらその分の開発工数が上積みされます。もちろん、テストが必須のステップであることは間違いありません。しかし、お客様によって品質、スケジュール、機能の優先順位は異なります。テストチームができたばかりの頃は、隅々まで徹底的にテストする、という意識の基にテスト過剰になりがちでした。しかし実際にテストを始めてみると、お客様ごとにテストの粒度や摘出されたバグのトリアージの方針を調整しなければならないということはすぐに分かってきました。
 複雑なワークフローを用いるアドインのテストを行った際の事例です。全ての申請経路のパターンを網羅しようとすると、テストに膨大な時間がかかってしまいます。しかしお客様からは、本番稼働日は動かせないという要件を頂いていました。このため、お客様から入手した運用情報に基づき、現時点で使われる予定のない経路のテストは省略する、実運用にあたり影響度の低いバグは修正せず稼働後に別途対処する、といった措置を執ることにより、当面の運用にあたっては十分な品質で、予定通りのスケジュールで本番稼働にこぎ着けるこどができました。
 テスト工数を考える上で、更に深刻なのはコアパッケージのバージョンアップに伴うリグレッションテストです。コアパッケージのバージョンアップは、通常のソフトウェアにとってのOSのバージョンアップに相当します。原則的に後方互換性は保たれているものの、意図せずに挙動が変わってしまったり、やむを得ず挙動が変更されるケースが考えられるため、コアパッケージのバージョンアップに合わせてアドインの再テストを行う必要があります。コアパッケージは3ヶ月ごとにバージョンアップが行われるため、3ヶ月ごとに既存のアドイン全てのリグレッションテストを行うこととなり、これが大きな負担となります。また、既にアドインが導入され運用されているお客様の場合、アドインのテストが完了するまでコアパッケージのバージョンを上げることができません。
 こうした問題に対処するためには、テストを効率化する仕組みが必要です。現在も試行錯誤の段階ですが、一つの解としてテスト管理ツールの導入を試みました。

●● TestLinkによるテスト管理の試行
 テスト管理ツールであるTestLinkについてはご存じの方も多いかと思います。TestLinkの紹介が趣旨ではないので詳しい説明は省きますが、テストケースやテストの実施状況の管理、結果の集計・分析といった機能を持つツールです。

● 従来のテスト管理
 これまでアリエルでは、プレーンテキストで書かれたテストケースを基にテストエンジニアが手作業で実施するという形態が主でした。コアパッケージの方では、一部をJUnitやJMeterで自動化して毎晩実行しています。しかしアドインについては、実行形態の関係上テストの自動化が難しく、全て手作業でテストしているのが現状です。このため、テストの実施状況を把握するにはテストリーダーが毎日テストエンジニアに状況を確認して集計するしか方法がなく、この管理工数が負担になっていました。このテスト管理を効率化するため、TestLinkを導入し評価することにしました。コアパッケージは規模が大きく試験導入には向かないため、ソリューショングループ内で比較的小規模な案件から試行を始めました。テキストベースのテストからTestLinkへ移行してみての、現場の声を紹介します。

● TestLinkの良い点
 良かった点としては、まずテスト計画が立てやすくなったということが挙げられます。これまでのプレーンテキストのテストケースでは、テスト全体のボリュームが把握しにくいという問題がありました。TestLinkではテストスイートごとにテストケースの数を表示できるため、特定のアドインのテストケースの件数、特定のお客様のテストケースの件数、などのように必要なテストの量が容易に把握できます。このため、テスト計画をより早くより正確に立てることが可能になりました。
 テストの進捗状況の把握についても効率向上と負担軽減が見られました。前述のように各テストエンジニアからの報告を集計する手間が不要になり、TestLink上で担当者別の進捗や全体の進捗を正確に把握できるようになったことで、テスト管理のオーバーヘッドを減らし、テストエンジニアがテストに集中できるようになりました。またバグ修正を行う開発者にとっても、テストの進捗状況とバグの報告状況をリアルタイムに確認できるため、残存バグ数を推測して作業のスケジューリングが行いやすくなりました。
 もう一つ良かった点として、テストケースが読みやすくなったという声がありました。プレーンテキストのテストケースでは、よく似たテストケースが多数並んでいたり、文章が長かったりすると、テストケースの内容を把握するのに時間がかかったり、内容を誤解してしまうケースがありました。TestLinkではテストケースに文字装飾が行えるため、ポイントになる部分を強調するなど読みやすいテストケースを書くことができます。これは、導入前には予想していなかったメリットでした。

● TestLinkの悪い点
 一方で、いくつか問題もありました。ワークフローのテストなどで複数のテストケースに継続性がある場合、プレーンテキストのテストケースでは事前条件や操作を最初に書いてから各ステップのテストケースを書いていくことで、記述量を減らし効率よくテストケースを作成できました。しかしTestLinkでは個々のテストケースが独立しているため、複数のテストケースで重複する内容も毎回記述しなければならず手間がかかってしまいます。
 また、テストの実施中にテストケースを修正する、という状況はそれほど珍しくありません。作成者が仕様を勘違いしていてテストケースが誤っていたり、単純な誤字脱字があったり、テスト実施中に不明点があり開発者に確認した結果を書き足したり、といったケースです。プレーンテキストのテストケースはその場で簡単に修正できますが、TestLinkではテストケースの実行画面と編集画面が分かれているので、一旦テストの実行を止めて、編集画面に遷移してからテストケースを編集し、また実行画面に戻ってくる、というステップを踏まなければならず、これまた手間がかかります。
 テストケースがTestLinkサーバーに集約されているが故の不便さもあります。サーバーがダウンするとテスト作業が中断されてしまうのです。テストケースがプレーンテキストだった頃は、Subversionからチェックアウトしたテストケースがテストエンジニアの手元にあるので、自分のPCが生きていればテストはできました。しかしTestLinkに移行後は、TestLinkサーバーがダウンするとテストエンジニア全員の作業が止まってしまいます。そう頻繁に発生することではないので、今回試験導入した限りにおいては大きな問題にはなりませんでした。しかし、プロジェクトの規模が大きかったりスケジュールがタイトな場合は、痛いタイムロスになるかもしれません。

● TestLink総評
 このように良い点、悪い点ともに色々ありますが、総合的に見ると高評価でした。テストリーダーからもテストエンジニアからも今後も使い続けたいという評価で、また使い始めるにあたっての抵抗感もほとんどなかったようです。テスト管理ツールを導入していないプロジェクトに携わっている皆様、騙されたと思ってTestLinkを試してみてはいかがでしょうか。


●●● プロジェクト事例
 ここからは、私がこれまでに携わったプロジェクトを例として、テストに関する試行錯誤とそこから得た自分なりの解について紹介します。

●● レガシープログラムの保守
 ドキュメントもない、テストケースもない、コードを書いた人も仕様を把握している人ももういない。そんなプログラムの保守を任されたらどうすべきでしょうか。我が身の不幸を嘆く以外に何かできることはあるでしょうか。
 私がこんなプログラムを保守することになったのは昨年秋のことです。上記の条件を全て満たしている上に、お客様のところで稼働することもなく放置されていたためエンドユーザーから情報を得ることもできません。まさに八方塞がりでした。

● ソースコードを読みながらテストケースを書く
 一般的に、ソースコードを読みながらテストケースを書くのはあまり良いプラクティスではありません。本来テストケースは、プログラムがどう動くべきかという仕様に基づいて書かれるべきもので、実装に基づいて書かれたのでは本末転倒です。
 そうは言っても、ソースコードだけが得られる情報の全てである場合には選択の余地はありません。まずはソースコードを解読しながらテストケースを書き起こすことから始めるべきです。期待されている通りに動作するかをテストすることはできなくても、こうして書かれたテストケースにはいくつかの意味があると考えています。
 まずはドキュメントとしての意味です。誰かがそのプログラムについて知りたいと思ったとき、(特にプログラマ以外にとっては)テストケースがあれば理解が容易になるでしょう。またプログラムの仕様について誰かと議論する際にも役立ちます。「このテストケースの期待値がこうなるように修正してくれ」といった具合です。仕様について話すとき、相手はプログラマではないことがほとんどでしょう。
 また、今後の保守の足場としてもテストケースは重要です。リファクタリングを行ったり修正依頼を受けて修正を行ったとしても、テストケースさえあればそれを再消化することで、少なくとも修正前の時点より品質が落ちていないことを確認できます。
 いずれにしても、プログラムの現時点での状態をテストケースとして書き表すことにはメリットがあります。テストケースを書く過程でバグに気付くこともあるでしょう。こうして足場を整え、その上で拡張の都度テストケースを追加していけば、プログラムの保守性は徐々に改善されていくはずです。

●● テスト環境の構築ミスによるトラブル
 テスト環境の構築も、適切なテストを行うための重要なタスクです。環境はお客様ごとに異なるため、プロジェクトの開始にあたっては稼働環境や運用について十分な情報を入手し、できるだけ稼働環境に近いテスト環境を用意する必要があります。この情報入手が不十分だったためにトラブルを招いてしまった事例を紹介します。

● 一般ユーザーからはマスタが見えない
 AAEでは、複数のアドイン間で連携を行うことができます。よく使われるのが、あるアドインをマスタとして扱い、他のアドインでそのマスタのデータを参照するパターンです。あるお客様向けに申請業務用のアドインを開発していた際、申請ワークフローの経路を設定するマスタを用意して、マスタで設定された経路に従って申請書が流れる仕組みを作りました。社内でのテストは問題なくパスし、お客様のテスト環境でも正常に動作していたため順調と思われました。しかしカットオーバー直後、お客様から「ワークフローが動かない」というトラブル報告を受けることとなってしまいました。
 調査の結果、原因はアクセス権限の設定にありました。AAEには、各アドインやアドイン内のデータに対して、ユーザーや組織ごとに閲覧、編集、削除などの権限を設定するアクセスコントロールの機能があります。テスト時にはアクセス権限を特に意識していなかったため、申請用のアドインもマスタも全員が閲覧できる状態になっていました。しかし本番環境では、マスタはシステムを管理している部門からしか閲覧できない設定となっていました。このため一般ユーザーが申請を行おうとした場合、マスタからワークフローの経路を取得できなかった、というわけです。この運用についての情報を開発段階で確認していれば、マスタへのアクセスは管理者権限で行うように実装することでトラブルを避けられたはずです。

● 漢字1文字は2バイトか3バイトか
 あるお客様向けに開発したアドインで、入力フォームのあるフィールドにデフォルトで文字列を入れておくように実装したことがあります。かなり長めの文字列でしたが開発環境では問題なく動作していました。ところがお客様のテスト環境に導入してみると、その文字列が長さ制限に引っかかってエラーが発生し、入力内容が保存できないという状況になりました。
 社内の環境とお客様の環境の差異を調べたところ、データベースの内部文字コードが社内環境はShiftJIS、お客様の環境はUTF-8であることが判明しました。AAEでは通常の文字列型であるstring型は最大2000バイトです。問題のデフォルト文字列は1文字2バイトのShiftJISでは約1700バイトでしたが、1文字3バイトのUTF-8では約2500バイトになり、string型の上限を超えてしまっていました。AAEには実質的に長さ制限のないlarge_string型も用意されているため、フィールドの型を変更することで対処しました。しかし、開発段階でお客様の環境についての情報を入手していれば、最初からlarge_stringで実装するか、少なくともテストで検出できたはずです。

● まとめ
 稼働環境と同じ環境でテストする、というのは基本中の基本です。とはいえ、十分に情報を集めたつもりでも何かが漏れてしまうことはあり得ます。開発にあたって事前入手が必要な情報については、例えばチェックリストを用意するなど確認漏れを防ぐ仕組みを考えるのが良いと思います。私が担当しているアドイン開発では、コアパッケージの設定ファイル、コアパッケージのバージョンやパッチの適用状況、アプリケーションサーバーやDBMSなどのミドルウェア、お客様の組織構造やセキュリティポリシー、といった情報を確認するようにしています。
 お客様の環境へ導入予定の有償ミドルウェア製品が費用などの関係で用意できず、開発環境やテスト環境は代替品で構築せざるを得ないこともあるかもしれません。例えば、アプリケーションサーバーとしてWebSphereを導入予定だが社内ではTomcatで代替する、といった場合です。特に開発環境は、高価な有償製品を開発者の数だけ用意するのが難しく、無償製品で代替することが多いと思います。こうした場合は、環境の差異による影響範囲を慎重に検討することが重要です。

●● はじめてのテスト駆動開発
 私はこれまで書いてきたようなアドインの開発の他に、Lotus NotesからAAEへの移行を支援するツールの開発を担当しています。このツールはフルスクラッチで書き起こしたJavaアプリケーションです。テストの自動化が難しいアドインに対し、JavaのアプリケーションであれはJUnitが利用できます。そこで、以前から興味を持っていたテスト駆動開発を試してみることにしました。

● 疑問と先入観
 興味を持っていた反面、テスト駆動開発には懐疑的でもありました。いくつか理由はありますが、実装より前に失敗するテストケースを書くことの意味がよくわからなかった、というのが主な理由です。それ以前に携わったプロジェクトで、設計→実装→テストケース作成→テスト、という逐次型の開発プロセスに慣れきっていたのが原因の一つかもしれません。実装イメージが固まらないうちにテストケースを書くのは時間がかかるし、実装の結果プログラムの挙動が変わったらテストケースも書き直すことになり、結果的に効率が悪いのではないか、という疑念を払拭できずにいました。

● TDDで学んだテストの楽しさ
 このように疑問はあったものの、食わず嫌いはよくありません。全体のクラス構成を考えた後、比較的シンプルなクラスを選んでテストケースを書き、テストを実行して失敗させ、実装して、テストを実行する、という手順をいくつかのメソッドについて繰り返してみました。確かに最初のうちは効率がよいとは言えない状況でした。しかしこのサイクルを繰り返し慣れていくうちに、徐々に効率は上がり、それとともに疑問は解けていきました。
 実装イメージが固まらないうちにテストケースを書くのは時間がかかる、というのは完全に問題の取り違えでした。実装イメージを固める作業が、コーディングからテストケース作成に移っただけなのです。テストケースを書いた後、テストをパスするようにコードを書くのに要する時間は明らかに短くなりました。テストを書いている間は、実装の詳細を気にすることなくコードがどう動作すべきかに集中することができ、コードを書いている間は、コードに期待される振る舞いは既にテストとして書かれているので、どうやってテストをパスするかに集中することができます。1度に考えることが1つになったので、個々の作業の効率は良くなり、結果として開発全体の効率が向上しているのが実感できました。
 JUnitによる徹底したテストの自動化は、日々の開発作業にリズムと自信を与えてくれました。テスト→コード→リファクタリング、というサイクルをできるだけ短い時間で繰り返すことで、デバッグは範囲を局所化できるため容易になり、グリーンバーを見れば気分良く次の作業にとりかかれます。普段は専らEmacsでコードを書いている私ですが、このツールの開発に限ってはEclipseを使っています。テスト結果が直感的に色で分かることの心理的効果は大きいと考えているからです。テストを楽しむことは、テストエンジニアだけでなく開発者にとっても重要なことです。

● 今後に向けて
 すっかりテスト駆動開発の虜になった私ですが、残念ながらアドインの開発には適用が難しいのが現状です。独自のフレームワークを用いており、データ構造はXMLで定義し、ロジック部分はECMAScriptで記述しMozilla Rhinoで動かします。こうした形態のため、自動テストが難しいのです。とはいえ、諦めたわけではありません。ロジック部分はJUnitかJsUnitでうまくテストする方法があるかもしれません。実行結果はDBに収まるので、DBUnitを使えるかもしれません。画面周りもSeleniumを試す価値はあるでしょう。まずは部分的にでも自動化の余地がないかを考えるのが今後の課題です。


Copyright(C) 2001 - 2006 Ariel Networks, Inc. All rights reserved.