気難しいプログラマとの人間関係に必要ないくつかのポイント

プログラムの品質保証について

»

 ソフトウェアは製品であり、有償である以上顧客に提供される際には故障がないことを保証しなければならない。

 今でこそこのような理想論を普段耳にする機会はほとんどなくなりましたが、私がプログラマとして働き始めた当初(今から20年以上も前!)、こういった思想が開発現場の中に色濃く根付いているように感じられました。もちろん今日においてもこのような原則が基本的に変わるものではありませんが、上述のような意見は(当時の私がそうであったように)ソフトウェア開発技術者にとって非常に違和感のあるものに聞こえたのではないでしょうか。というのも私たち技術者は、プログラムに混入する障害をゼロにすること、あるいは障害ゼロを保証することが不可能であることを知っているのですから。

 障害がゼロであることを保証することはきわめて困難な作業です。いわゆる悪魔の証明と言われるもので、これを証明するためには少なくともそのプログラムに対して全数テストを行わなければならなくなります。そのプログラムがとりうるありとあらゆる条件、状態、入力データの組み合わせをすべて検証する必要がでてくるでしょう。ところが、そのテスト項目数はプログラムの規模が大きくなるにしたがって指数関数的に増大し、あっという間に天文学的数字となるため、納品期限の存在する一般的な開発においてはこのような検証は物理的には不可能なのです。

 だからといって「まぁ、うちらも頑張ったんで大丈夫だと思いますよ、えへへ」などと曖昧なことを言っても誰も納得しません。ごく小規模で故障がそれほど深刻な事態を引き起こさないようなものならばこういったこともあり得るかもしれませんが、SLAに最高の品質を求められるようなシステム、例えば銀行業務のOLTPなどでは、たった1つの不具合が莫大な損害に発展してしまいます。程度の差こそあれ、このような曖昧な報告が実際の現場において通用することはまずないでしょう。「多分まっすぐ走ると思います」などという自動車を一体誰が購入するでしょうか。私たちは開発を請け負った時点で、提供するソフトウェアが可能な限り障害をゼロに近づけていることを報告する義務を背負っているのです。

 ではどうやって顧客の納得する報告をすればよいのでしょうか。言い換えれば、どうやって私たちはプログラムの品質を証明することができるのでしょうか。その1つの指標がテスト項目の網羅性です。たとえ全数テストが無理だとしても、検証が利用の範囲内において十分に網羅され、そしてそれらが正確に実施されていることを理解してもらえればよいのです。

 例えばある入力値が0から1億までの数値をとりうるとします。全数テストであれば正常系のテストだけでも1億1通りのテスト項目が必要となりますが、実際に必要な検証は、min値、max値、特別な自然数の0といった観点によって施行件数をぐっと減らせることになります。これは、例えば入力値の2と3とではプログラムの挙動が変わらないという論理的・科学的に裏づけのなされた根拠から成り立っており、こうして網羅性が十分であるという根拠を積み重ねていくことでプログラムの品質を立証していくのです。

 このテスト項目の網羅性について最も説明のしやすいものは、単体テストなどで行うコードベースによる網羅性(コードガバレッジ)です。ソースコードそのものがテスト項目であり、命令・分岐といったルートの検証実施率によって明確に網羅性を表すことができます。最近ではツールの充実によってテストの実施や網羅率の計算を簡単に行えるようになっています。ただ、コードガバレッジだけでプログラムの品質を保証するには不十分です。なぜならここで行うテストはプログラム論理の正当性を検証しているに過ぎず、以下のような観点が抜け落ちています。

a) プログラム論理そのものの誤り
b) 機能の網羅性・正当性
c) 他モジュールとのインタフェース
d) ソースコード上に現れない条件

 a) 、b) については機能仕様や設計が明確に定義されている必要があり、顧客側とのコンセンサスを得た機能仕様書や当該モジュールの設計書からテスト項目の網羅性を見極めます。アジャイル型の開発ではソフトウェア要件が出揃っていない状況でリリースが行われるため、この辺りの保証はグレーゾーンになりますが、そもそもアジャイルにおけるイテレーション中のリリースは機能仕様のすり合わせも主な目的の1つであり、開発期間すべてが機能設計工程であると言えるので、これらの保証が問題になることはあまりないでしょう。ただ、顧客側にアジャイル型開発の特性を十分に理解してもらっていないと、例えばすでに合意を得たはずの機能部分の相違などが問題となる可能性があり、この辺りは顧客側とのコミュニケーション、上流従事者の手腕によるところが大きいと思います。a) ~ c) の検証は、どちらかというと単体テストというよりも結合テストやシステムテストの範疇になります。

 d) は並列処理や性能、負荷耐久性、スケーラビリティといった動作・運用環境に依存する問題の検証です。動作環境に依存する問題については、システムテストの環境さえあれば容易にテストの実施が可能ですが、負荷テストのような運用環境に依存する問題については、テストの実施が困難になる場合も多々あります。例えば並列処理の検証では、外側からプログラムをフックするツールを利用したり、プログラム本体にスリープを入れるなどしてクリティカルなタイミングを作りだす工夫が必要となります。テストの実施もさることながら、そもそもテスト項目を抽出すること自体難易度が高く、ある程度の工数と様々な知識・経験を持った人材を要することになるでしょう。テスト項目を決定するためにも、データ競合や排他粒度、デッドロックなどの観点から並列処理に特化した設計指針を事前に策定しておく必要があります。

 アジャイル型の開発では短いイテレーションによってリリースを何度も繰り返しますが、プログラムに修正を加える場合には、その都度修正の影響範囲すべてを再度検証し直さなければプログラム品質を保証したことにはなりません。アジャイルではこのようなレベルダウン検証(リグレッションテスト)は自動化されたテストの実施が前提となっていますが、実際には上述のような自動化の難しい検証が短いイテレーションの中で実施困難な場合があり、この辺り最も苦労する部分の1つでもあります。

 長々と品質について語ってきましたが、そもそもソフトウェアの品質とは、これまで述べてきたようなプログラム品質の話と、利用者の要求にいかにマッチしているかという設計品質の両面があります。世の市場はどちらかといえば設計品質を重視する方向に傾いており、そいういう意味ではアジャイル型開発の重要性は今後も増していくものと私は思います。

Comment(0)

コメント

コメントを投稿する