********************************************************************** チュートリアル1 セッションS2-a テーマ:ソフトのテストとハードの検証。もっと一緒に考えよう! 講師:赤星博輝(ソリューション・デザイン・ラボラトリー)・片山徹郎氏(宮崎大学) 日時:2007/8/31 8:50〜10:30 ********************************************************************** ---概要--- ソフトのテストとハードの検証には、双方異なる難しさがある。 ソフト開発者とハード開発者がもっと話し合って、テスト・検証手法を改善していく ことが必要。 ソフトの点からは片山氏が、ハードの点からは赤星氏がそれぞれ現状・問題点について 講演。 次の時間のセッションでは、この講演を基に議論。 ---講演(片山氏)--- ○組込みソフトウェアについて 急激に大規模が進んでいる(ソフトが支配的である) 2年前のデータ:開発規模2.4兆円・開発者数17.5万人 この2年間でソフトウェア開発者は66%に増加。 ○組込みソフトウェアの品質の現状 多くの人は、日本製はいいと盲目的に信じている ・2004年度のデータ:不具合のデータが多い ・不具合の内容;こういうのが気がつかなかったの?というレベルのものが多い ・開発期間の短縮:事故多発・ぼろい(頻繁に不具合事例が起きている) ○組込みソフトウェアにおける課題 組込みソフトウェアの品質向上が急務 製品の不具合の大きな部分をソフトウェアが占める ソフトウェア開発において品質の課題が最も重要視 製品出荷後に生じた主な不具合の原因:1番はソフトウェア(この2年間で34.2%→43%) 組込みソフトウェア開発に課せられている課題:1番は設計品質の向上 ○テストの目的 2006年6月アメリカのNIST(国立標準技術研究所)のレポート 「ソフトウェアのバグが、アメリカに年間7兆円(59.5億ドル)の損害を与えている。」 ちゃんとテストをすれば、ソフトウェアのバグの1/3から1/2は防げる *テストとはそもそもなんだ? ・テストでプログラム中のバグの存在は示せても、バグが存在しないこと言うことは 示しえない。by Dijkstra ・バグを全部見つけるのは無理だ。 by Kaner ソフトが複雑大規模になると全部見つけるのは無理だ。最初から放棄している。 ・テストとは、エラーを見つけるつもりでプログラムを実行する過程である。by Myers テストをやっている時正しいと思ってしていると、エラーを見過ごしてしまう。 バグがあるから見つけてやるというつもりでやれ。 正しいのを確認するのがテストではなく、間違っていることを前提に行う。 正しいと思ってやると、正しく見えてしまう。 「第三者検証」にテスト・検証を頼む。 *ソフトウェア工学の世界 ソフトウェアテスティングとは、期待されるビヘイビアを求めて、通常は無限に大きい と考えられる実行ドメインから適正に選定された有限のテストケース集合を用いて、 プログラムビヘイビアの動的検証を行うことである。 「テストとは動的検証」 静的手法は品質の章にまとめられている *テストとは、ソフトウェアの品質を測定すること 一般に言うテストは自分の能力を測るためのもの。 ソフトウェアがどれぐらいの実力があるのかを測定するためのもの。 品質を測定するだけのものじゃないといけない。 確実にソフトウェアの品質を測れるものでなければ、テストではない。 1.プログラムの誤りを見つけること (誤りを見つけられなかったらテストは無駄だったのか?という疑問が出てくる) 2.誤りを見つけられなかったら、このプログラムは正しいのではないか?という確信が増す。 1と2のことが言えるだけのテストをする! ○テストの工程 *コードインスペクション バグになりやすいコーディングをしていないかチェックするコード監査や、 複雑すぎないかを測定するメトリクス分析などを行う。 *単体テスト モジュール内のコードが正しいロジックかどうかをチェックし、予期しない例外について も確認する。 *結合テスト 関数の呼び出しなど、モジュール間のつながりが正しいかをチェックする *機能テスト ソフトウェアに実装された機能が仕様書とあっているかどうかをチェックする *システムテスト ユーザが満足しているかどうかをチェックする *回帰テスト 修正確認用のテストを実施する ○ソフトウェア開発におけるテストにかかる費用 テスト作業は開発におけるボトルネック 工程の費用:圧倒的に「運用と保守」に費用がかかる 運用と保守を除くと、圧倒的にテストに費用がかかっている ○テストの順 *テストケースの作成 テストすべき条件を決める。期待出力を忘れずに。 *テストデータの選定 テストケースを満足するテストデータを選ぶ。 *テストの実施 テストデータを使って、プログラムを実行してストを行う。 *テスト結果の判定 テストの結果が期待出力を満足するかを判定する。 エラー処理には特に注意するべき。期待出力をなおざりにしてはならない。 *テストの充分性の判定 テストが充分実施されたかどうかを判定する。 ○テストの視点 *ブラックボックステスト:要求ビュー、仕様ビュー 中身は考えない。入力と出力のみで判定 *ホワイトボックステスト:設計・実装ビュー、バグ・ビュー 中身を見て考える。 ・要求ビュー ユーザの要求が満足しているかどうかをチェック ・仕様ビュー 仕様どおり実装しているかどうかをチェック ・設計・実装ビュー ロジックが正しいか、実行されないコードはないかなどをチェック ・バグ・ビュー プログラムの特徴などから推測されるバグがきちんと見つかったかどうかをチェック ○テスト作業に付きまとう問題点 *今見つけたバグがソフトウェアに潜む最後のバグかどうかを判断できない テストにかかるコストの問題 テスト作業をどこで終わらせるかという問題 *テストによって、「このプログラムにはまったくバグが存在しない」 =「このプログラムは正しい」ことを示すことはできない。 ソフトウェアに対して、考えられるすべての入力を試すことはできない 時間と費用がかかる(現実的でない・時間が足りない) 残った時間だけでテストするのも駄目。 どこかでやらないといけない。中身の濃いものに!と考えるのが建設的。 ○テストの設計 テスト作業は、時間とお金の都合を考えて、結局どこかで妥協するしかない テストの設計が重要となる ・少ないテストケースで、 ・バグを見つけやすそうな、 ・モレがない、網羅的なテストを。 より重要視するのはどれか?この中のどういう技法があるのか? その技法にどういう長所と短所があるのか?自分で消化して適用する必要がある。 ○代表的なテスト技法 ・同値クラス ・境界値テスト ・制御パステスト ・デシジョンテーブル ・状態遷移テスト ・全ペアテスト(直交表の利用) ・ユースケーステスト ○その他のキーワード ・アドホックテスト:ランダムに。意外と見つかる。 ・探索的テスト:経験則に基づくテスト法 ・実際の環境を意識したテスト:組込み屋さんは意識していることが多い。 一般のアプリの開発者が抜けがちなテスト *テストの順番 ・優先順位をちゃんとつけてテスト ・リスクベーステスト ○システムテスト 一般的な分類:負荷系・評価系・環境系 最近は、ユーザビリティ・セキュリティー・パフォーマンスについてのテストも行う。 ○非機能要求 ユーザが求める機能を実現するために、間接的に働く機能(拡張性・再利用性・性能・ 信頼性・使いやすさ) →モデル化や機能のリストアップが困難 このことが、システムテストの手法が未だ存在しない理由 ○テストの終了条件 *ソフトウェアメトリクス ・プログラムの構造や内容を測るための数値や指標 ・数字が一人歩き。数値の勝手な解釈をしてしまうことがある。正しく読むことが大切。 一般的には、技術とそのチームの進化(改善)の助けとなることが多い メトリクスの限界も知っておくこと メトリクスを目標として使うことは意味があるが、目的になってはいけない ○メトリクス 意外と地味。 どれぐらいメトリクスを取っているか? ・バグのメトリクス ・テストのメトリクス ・ソースコードのメトリクス ・ソフトウェアの信頼性メトリクス ・ビルドのメトリクス ・スケジュールのメトリクス ○最近のキーワード ・リスクを考える ・モデル思考の考え方(モデルベースドテスト) ・「テスト対策」(上流工程での対策) ・テストファースト(TDD) ・テストの自動化 ○テスト戦略の心得 テストをする理由は、つまるところただ1つしかない 重要なところが正しく動作しないリスクがある テスト戦略に関する3つの質問を、自分たちに繰り返し問いかける必要がある ・本当に必要か? ・誰のためか? ・どこまでか? この3つを明らかにできれば、その後の作業もスムーズに行く。 最初に明確に決定し、心構えを持つ。 ○リスクを考える バグがどうやっても発生してしまうならば、発生してしまうバグのインパクトを小さく させることが鍵 ・どんな壊れ方をするのか?不具合のレベルがある。 「JR:信号が壊れた」全部赤になって、青にならない。逆は危険!壊れたことによる 影響を考える。 ・障害発生の可能性と障害発生時の影響をとを段階化することで、リスク度を算出し、 リスク度の高い順に集中的にテストする。 リスクを並べることで、上から順にリスクをつぶせる。 ・発生の可能性と影響を、どういう風に見積もるのか?リスクベースドテストの考え方 「たまたま発生しなかった」→ギャンブル的 ギャンブルをしなくてもいいようにちゃんとテストする。 ○機能完全企画 安全度水準(SIL:Safety Integrity Level) 故障確率を下げる ヨーロッパでは、原発や車などに適用 日本でも導入?→組込み機器にSILを使用・評価するケースが出てくる ○モデル指向の考え方 *MDA ツール上で、モデルからモデルへの変換や、モデルからコードへの変換、モデルの チェックを行っていく 1.モデルからテストを作る 2.モデル上でテストする→テストがいらない? (使用を全てモデル上でチェックできれば) *MDD MDAをベースにシステムを開発する手法 *代表的なモデルとしては、UMLが有名 ○モデル指向の考え方 この考え方を突き詰めると、開発のバックスラッシュモデルが完成する? ここまでいくと、テストの現場からは懐疑的 ・仕様モデルで全部表すことが可能か? ○U2TP テストしようをモデル化するための記述言語として、UMLをプロファイル拡張したもの 更に非機能要求に対して、UML表記にスケジューリングやパフォーマンスに関する要求 をモデル化するための拡張 マイクロソフト社など数社は、ドメイン固有言語(DSL:Domain Specific Language)を 設定するアプローチを提唱 ○「テスト対策」をしよう! *ソフトウェア開発者は、テストを軽視してる? *「テスト工程が開発におけるボトルネック」である理由は? ・テストこそちゃんとやらないといけないのに、ちゃんとやっていない ・テストによるバグ発見→手戻り(バグ)が大きい・ちゃんと作ってない ・テストが尻拭い・だからやり直す。→無駄が大きい *テスト対策とは? ・テスト容易性を考える ・テスト設計の前倒し 「テストありき」を前提に考えることが重要! ○テスト容易性(Testability)を考える テストが容易なようにプログラムを作ろう。 ちゃんと整理整頓されたコーディングを。 ハードウェア屋さんの方が、この辺をちゃんと考えている。 ○テスト設計の前通し *テストの設計をいつやるか? テスト:物ができてから… 設計工程で同時にテストを。 どういうテストをすることになるかをちゃんと考えられる。 設計と同時にテストを考えることで、疑問を持つ→バグを見つけやすい。 ○テストファースト *アジャイル開発に分類されr、Kent Beckによって提唱されたソフトウェアの開発方法論 であるXPの中のプラクティスの1つ *テストは独立したプロセスではなく、コーディングの一部 ・このテストが全部通れば、このコードはちゃんとしている、ということがいえる。 *xUnit ・ソフトウェア開発において、プログラムの単体(ユニット)テストを支援するテスティ ング・フレームワークの総称 *TDDテスト駆動開発 ・テスト手法ではなく開発手法 ○テストの自動化 自動テストは魅力的。 *自動テストの罠 ・自動化すると手動でテストする必要がなくなるか?→ノー 何をテストするのかちゃんと明確化する。 手動でできることと自動でできることをちゃんと考える。それぞれ得意不得意がある。 ・何をどうテストするのか? ユーザが変わると、今までのテストデータは全然使えなくなる。 ○終わりに *ソフトウェアについて ・ソフトウェアの品質を決定付ける「最後の砦」 ・「テストとは、ソフトウェアの品質を正しく測定すること」 ・テストの目的はプログラムの誤りを見つけるため。 ・テスト技術に対してかつてないほどの注目が。 *技術者共通の知識 ・他の工程でも知識は生きる! ・テストを知っているからこそ、上流で対策できる。 ・どれだけのテストデータをあげれるか? ・テストの肯定を知っていれば、違う工程でもその知識は生かせる。 ---講演(赤星氏)--- ○ソフトウェアとの違いはデジタル部分 どちらでも使える技術がどちらにも転がっている。 *設計と検証 ・ソフトではテスト:製品の不良品を取り除くこと ・ハードでは検証:例えばA+B用のハードはちゃんと正しい値が出てくる?仕様に 沿って正しく設計できているか?検証が難しくなってきた。ハード屋さんの悩み。 ○検証意識の高まり ・ハードウェア屋さん:失敗した時のコストが莫大。プレッシャーが大きい。(億単位) ソフトウェアでは、既存のプログラムを再利用・編集ができるが、ハードウェアでは できない。 ソフトウェアよりシビア。 ○検証とは? コーディングしたものと仕様が一致するのか? どう解釈するか:仕様〜コーディングまでの間の過程で既にバグが入っている可能性が ある・冗長性→コスト大 ○検証で確認 ・機能のチェック 周波数やチップ面積などのクリアな項目が決まっている。検証しやすい。 ・性能 動作周波数、面積、レイテンシ、スループット、消費電力… ○課題は? *大規模化・複雑化 設計はとにかく分割してしまえば設計できてしまう。分割設計したものを後で結合。 最後の統合テスト:全てを結合した後で全体を検証する必要がある テストパターンは、モジュール数に指数関数的に比例する。 ○設計複雑度と検証空間 ムーアの法則:指数オーダーで複雑度が増す 人海戦術に走るとできる作業量が増えるが、コミュニケーションコストも増える。 検証に投じる人数を増やすと知識が分散する。 工夫で何とかする! 新技術に期待。 ツールベンダーに強く依存。非常に強いソリューションを提供。(ソフトとハードの 大きな違い) ○効率化の取り組み ・ツールの導入 実機を動かして確認→基盤の情報をHDLに置き換える。机上でシミュレーションできる。 半田付けしなくてすむ。 バーチャルな世界で検証可能。 ・検証言語の導入 ハードウェアの検証用の言語 モデリング能力を高めた 入力値の作成能力を高める ・ウケが悪かった:言語の難しさ 検証言語のほとんどはオブジェクト指向言語(ハードウェア屋さんがうまく使えなかった) 代替案:アスペクト指向言語など。 ・検証手法の導入 教育コストが高い 一回導入ができれば、大幅に検証範囲が広がる ハードウェア設計者たちがあんまり考えていない→ツールベンダーが考える! ○検証の終わりは? テープアウトorシリコンがあがってくる日 指標化 ・カバレッジ:ライン、機能、アサーション ・テストケースの実行 ・信頼度成長曲線 ○最近のキーワード ・制約つきランダム生成 ・アサーション ・フォーマル検証 ・検証手法 ○制約付ランダム生成 ・ランダムでどんどんデータを作る ・シミュレータ環境にどんどん値を入力 ・自動チェック 人手では1秒で1個:シミュレータでは1秒で1000個 ・ランダムに制約付け ピュアなランダムは無駄が多い→有効な値に絞り込む ○アサーション 時間的な依存レベルをアサーションでチェック 入力する値のチェックを自動化 ○ハードウェアのアサーションの特徴 設計とチェックで共通のルール ○検証手法例 検証は毎回手作りだった ライブラリをベースに設計 検証を部品化・再利用 ・ランダム生成 自動でテストパターンを生成し、探索空間を広げる。 ・自動チェックの推進 ランダムで広げた探索空間を自動でチェック ・カバレッジによる終了判定 検証の終わりの明確化 ・部品化の促進 再利用による効率化・検証IPの活用 どんどん自動化しよう! ○去年の議論 ・ハードではDFTというものがあり進んでいる? 多くのバグを発見することはできる。 仕様〜RTL:検証 RTL〜チップ:テスト 設計図に対して、設計図どおりにできているか? ・HWのでーたをSW開発者に出して欲しい ○簡単なDFTの手法 DFT:RTLとチップで動作が違うケースを見つける 実行形式をROMに焼くまでに失敗するかも テスト用の回路を自動で作る ○HWのデータをSW開発者に出してほしい ・なぜ必要なのか? ・そのデータは必要なのか? ・でも、本当に必要なのはコラボレーションなのでは? 本当に必要なのはコラボレーション。データじゃない。 ○終わりに *去年の内容 ・戦うべき相手の認識が必要 何が必要なのかをもう1度考える ・正しい武器を使おう ・頭を使う部分と自動化する部分の選択 ソフトウェア屋さん:自動化に懐疑的。頭の使い方が問題! *今年追加 全体の最適化を考える --- 質疑応答 --- Q1. テスト・検証用の自動化ツールが期待されているが、最近その辺りのビジネス モデルが崩れつつあると思うが? A1. スペシャルなツールを必要とするユーザが少ないため、ベンダーが開発できないの が現状。これはまさにビジネスモデルの崩壊である。 Q2. ハードウェア設計と一言で言ってもいっぱいある。どのあたりを想定しているのか? A2. 基本的にはLSIを考えている。デジタル部分の設計で、使用する言語はHDLを 想定した講演であった。 Q3. ハード・ソフトの開発期間の短縮するためには、協調設計・検証が必要になってく るのでは? A3. テストと検証の考え方、それぞれテスト・検証の立場からのサジェスチョンし合い、 協力して改善していく必要があると考えている。