(第四回)JCUnitで2次方程式を解くプログラムをテストする。blogJCUnitの開発日誌(ログ)です。"その時点での"JCUnit作者の理解や考え、開発状況を日本語で書きます。この広告は、90日以上更新していないブログに表示しています。2016-04-10(第四回)JCUnitで2次方程式を解くプログラムをテストする。はじめに本ブログでご案内しているように、javacのバグによりJDK1.7.0_79以前でコンパイルエラーが生じることがわかった。0.6.4をリリースしたので、pom.xmlを以下のように更新して欲しい。</dependency>(第四回)JCUnitで2次方程式を解くプログラムをテストする。前回のエントリでは、FL表を作成し、それにもとづいてJCUnitにテストスイートを生成させたところ、109件ものテストができた。これについてすでに以下のように述べた。テストケースが多すぎる正常系のテストと異常系のテストが混ざっていてレビューしづらい同時に複数の制約に違反するテストケースが多い。この種のテストケースは多くの場合あまり意味がないテストスイートを自動で生成し、かつ自動で実行するとしてもテストケースの数は大きな問題になる。あまりに数が多すぎれば管理ができない。多くのテストが様々な理由で失敗している場合、失敗している理由を捕捉するのに手間がかかる。適切にテストオラクルを作るのが難しい場合、ひとまず現在の挙動を記録しておき、プログラム修正後(リファクタリング等)の次回実行時に前回との差異を点検することでテストとする場合もあろう。した時に、何千何万というテストケースがあったのでは容量を食い過ぎるという場合もある。私としてはテスト対象の外部的な仕様に基づいてテストを設計・実装・実行するために、つまり結合テスト・システムテストの段階で、JCUnitを使いたいのだがそうすると一件のテストの実行時間は短くても500msec、ながければ数分ということがあり得る。この場合、如何に自動で生成・実装・実行されるとしても無駄なテストをする余裕は無い。そもそも、JCUnitは人間が与えたソフトウェアの仕様にそって、テストを生成・実行するものである。テストが意図通りに生成され、実行されているかは人間によるレビューが必要だろう。何万件、何十万件もテストを実施してもそのテストが正しいかをレビュー・点検する方法を欠いているのでは、いささか中途半端というものではないか。正常系と異常系のテストが入り組んでいるのも同じような理由で好ましくない。設計者は正常系の挙動と異常系の挙動を区別してソフトウェアを設計するもので、これらのテストが交互に現れたのではレビューにならない。上述諸点を改善するためにどうする必要があるか?「制約」と「条件」を明確に区別してはどうか?というのがJCUnitのアイデアだ。前回の記事で紹介した@Conditionは実を言えばもともと単にテストを実行する「条件」を記述するためのものだ。ある「OS」という因子があるとして水準が「Windows」のときと「Linux」や「MaxOSX」の時では異なる事項を確認したい。...このように使い分けるためのものだ。「制約」も「条件」の一種と言えるが、こうした普通の条件とは重要な違いがある。通常、アプリケーションやシステムというものは、異常(環境設定、ユーザ入力、内部状態等)を検出したら、その時点で処理を打ち切り、それ以降の処理(それ以外の制約検査も含め)は行わない。一つ以上制約が破られたら、そのテストケースがカバーしようとしている値の組み合わせはそれ以降の正常な処理によって使われない可能性がある。(組み合わせ網羅率の低下)一つのテストケースで複数の制約が同時に破られる(複数の異常が発生する)と、テスト対象システムは最初に検出した異常に反応して処理を打ち切る。したがってこれら複数の異常のうち、(たまたま)システムが検出した異常処理のみが行われる。制約違反を検出して、異常を報告するのはそれ自体システムが備えるべき機能であって、正常機能とは独立して検査する必要がある。組み合わせテストは、処理が最後まで正常に行われるべき場合に、システムが正しく動作するかを効率的に検証するためのテクニックである。7以降であるときに、以下のようなテストスイートが生成されたとしよう。XPであることを検出した時点で、異常を報告して処理を終了する。ブラウザがSafariで言語がEnglishの組み合わせが別のテストケースによって網羅されている保証はどこにもない。良い組み合わせテスト生成ツールほど、テストスイートを小さくまとめるために網羅しなくなる可能性が高いと言える。制約違反を適切に報告できるかもシステムの機能としてテストする場合、それはまとめてではなく一個一個行う必要があることは上に述べたとおりである。10個独立な制約があったら、これらのすべてについて、1個、そして1個だけに違反するようなテストケースをそれぞれ作成する必要があることになる。経験を積んだソフトウェアエンジニアであれば、このあたりは本能的に知っている。「処理対象にして良い文字が入力できるか」をテストする場合には、テストデータに「際どいけど正常な文字」を全部いっぺんに使うように試みる。.,能あをんアヲン?こうすることによって、「処理できるべき文字がすべて処理できるか」については一度にテストが行える。「処理を中断するべき文字がすべて拒否されるか」については一個一個テストを行う必要がある。\が拒否されるかと、"が拒否されるかは別のことなので、両方を一つのテストデータに含めてしまうとどちらによってシステムが処理を拒否したのかがわからなくなってしまう。拒否された場合のメッセージが適正かなどはそれでも検査できるにしても、不当な文字を適正に拒絶できているかは別のことである。JCUnitでの解決方法JCUnitでは以下のようにしてこうした問題に対処することになる。前回のコード例は以下の場所にある。```a```が0の場合、例外が送出される。...行うべき変更は「制約」を前節で述べた方針にそって特別扱いするようJCUnitに指示する。@Conditionで定義していた条件が単なる条件ではなく、特別な取り扱いであることを明示する。以下が変更後のファイルである。```a```が0の場合、例外が送出される。...これを実行してみよう。お気づきのように、今回は34件のテストしか生成されていない。前半(19まで)はすべて成功しているが、後半(20以降)はすべて失敗している。サイズの減少はa,b,cのそれぞれに制約を設定したため、事実上水準の数が減ったためである。複数の因子に関係する制約を加えると、その制約を回避しながら可能な組み合わせをすべて生成するようJCUnitは試みる。これが生じるとテストスイートの大きさはむしろ増すことになる。今回、二次方程式の判別式に関する制約を(3つの因子すべてに関連する)加えている。これはテストケースの数を増す方向に作用する。それ以上に、100よりも大きい水準や-100よりも小さい水準が正常処理に関するテストから取り除いた効果の方が大きかったため全体としてテストケースの数が減ったと見受けられる。前半と後半で成功・失敗がはっきり別れたのは、上述のコード変更でJCUnitが以下の手順でテストスイートを生成するようになったからである。正常テスト(与えられた制約に一つも違反しない)の生成を行う異常テスト(与えられた制約の一個だけに違反しているテスト)を生成する。2.,でまだ網羅されていない因子の水準を一つずつ試す)を生成する。今回の実行結果では、20件が成功しているが第三回の例では6件のみ成功していた。正常系についてテストが不足していた可能性がある。余談この部分をデフォルトにしてしまえばよいような気がしてきた。読者のご意見をこう次第である。17:39(第四回)JCUnitで2次方程式を解くプログラムをテストする。Tweet広告を非表示にする関連記事2018-07-24制約処理について(承前)JCUnitでいかにして制約処理(禁則処理)を行っているか?結局の...2016-03-14(第三回)JCUnitで2次方程式を解くプログラムをテストする。0.6.0にバグがあることとユーザ...2016-03-09(第一回)JCUnitで2次方程式を解くプログラムをテストする。2017でJCUnitの発表をすることになりました。joinedプログラミングはてなブログをはじめよう!dakusuiさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。