(第三回)JCUnitで2次方程式を解くプログラムをテストする。blogJCUnitの開発日誌(ログ)です。"その時点での"JCUnit作者の理解や考え、開発状況を日本語で書きます。この広告は、90日以上更新していないブログに表示しています。2016-03-14(第三回)JCUnitで2次方程式を解くプログラムをテストする。0.6.0にバグがあることとユーザビリティを向上する必要があることがわかり、0.6.2をリリースした。本稿を試すにあたっては以下のようにpom.xmlを更新して欲しい。</dependencies>hamcrestライブラリへの依存は今回のJCUnitへの変更とは関係ないのだが、本稿の記述範囲で使用するためにここに含めた。お手数をおかけするがよろしくお願い申し上げたい。今回からここに例題のソースコードを格納することにした。https://github.com/jcunit-team/jcunit-examples.gitとして欲しい。なにかあればコメント欄などでご連絡頂きたい。(第三回)JCUnitで2次方程式を解くプログラムをテストする。第一回で多くのテストが失敗していたが、その結果を分析して二次方程式ソルバーの仕様書を更新した。aが0の場合、例外が送出される。a,b,cのいずれかの絶対値が100より大きい場合、例外が創出される。0を満たさない場合、例外が送出される。0を満たす実数x1とx2出力される解x1またはx2を上述の2次方程式に代入した時、その誤差は0.01を越えない。(問題2:丸め誤差)これをJCUnitを用いたテストとして実現してみよう。今回ステップ・バイ・ステップで作るJCUnitのテストは以下の場所に完成版がおいてある。QuadraticEquationTestこのコードの解説記事としてお読みいただくと時間の節約になるかもしれない。因子と水準を設計・実装する。a,b,cの三つはいずれも整数で境界値は100と-100である。これら一個一個を因子(Factor)とし、それらについてテストに用いるべき水準を列挙するとこんなふうになろうか。「ソフトウェアテストHAYST法入門」3などで"FL表"と呼ばれている表にあたる。ここでは各水準は100やInteger.MIN_VALUEといった具体的な値だが、実務の大規模で複雑なテストにおいては、各水準は抽象的に定義しなけらばならない場合が多い。a,b,cはそれぞれ別の因子なので、二次方程式ソルバーのような簡単なソフトウェアをテストするならともかく、普通は別の表にまとめたほうがよかろうと思う。テスト設計書をドキュメントとして作るならば、だが。cについてはこの制約は関係ないので正常値である。それはともかく、これをJCUnitの記法で書くならこうなる。{...}の中に写しとっているだけだ。制約を設計・実装する。aが0の場合、例外が送出される。(問題4:a==0)ここで使うアノテーションは@Conditionである。因子aにはその水準が0の場合は異常であるという制約がある。これをJavaのメソッドとして実現すると以下のようになる。違反している場合にfalseを返すことになっている。制約を実装するメソッドは、booleanを返す引数なしのものである必要がある。これに反するとJCUnitは実行時にエラーを報告する。制約2の場合、このようになる。a,b,cのいずれかの絶対値が100より大きい場合、例外が創出される。(問題3:巨大な係数)Javaで書き下すと以下のようになる。これも非常に直接的だ。}そして最後の制約、判別式の判定だ。0を満たさない場合、例外が送出される。(問題1:虚数解)Javaで書くとこう。正常の場合と異常の場合、あるいは特定の制約が満たされなかった場合等でテスト対象に対して期待するべき動作は異なる。if文で、現在どの条件でテストを実施しているかを書いてみてもいいが、それでは担当者によるむらも生じるし、その判定文自体のバグも心配になる。JCUnitでは、上で定義にした制約を参照してどのメソッドを用いてテスト対象の動作を検証するべきかを定義できる。ここでは正常系の場合と、上で定義した各制約のうち制約1の場合だけを説明する。出力される解x1またはx2を上述の2次方程式に代入した時、その絶対値は0.01未満になる。(問題2:丸め誤差)ということになる。これをJCUnitで表現すると以下のようになる。})は「@Conditionメソッドがすべて成立(trueを返した)時に実行する」という意味である。(Then)すると確かに解ける。}この部分はaIsNonZeroメソッドがfalseになったとき、という意味だ。})そして、JUnitの機能で送出されるべき例外の型を確認している。IllegalArgumentException.class)このメソッド宣言部の意味はこうなる。(Then)するとIllegalArgumentExceptionを投げる。これも見たとおりの意味だ。実行(その1)さて、ここまで出来上がったテストを実行するとどうなるか?読者のIDEで実行してみて欲しい。109件のテストを生成し、6件のみが成功する。109件にまで増えている理由は、各因子の水準が増えていることによる。実のところ上で「制約」を定義したものの「制約違反を避けるように組み合わせを選ぶ」処理がまだ作られていない。これは次回、解決方法とともに論じたいが「組み合わせテスト」の趣旨から外れるこまった問題だ。失敗が増えている理由は、例外を送出するべきところ送出する処理がテスト対象にまだ実装されていないからだ。生成されたテストスイートや実行結果を見てみると、いくつか改善したい点がある。テストケースが多すぎる正常系のテストと異常系のテストが混ざっていてレビューしづらい同時に複数の制約に違反するテストケースが多い。この種のテストケースは多くの場合あまり意味がない。3これらについても次回はもう少し深く議論し、JCUnitでの解決方法を示したいと思う。今回の記事を書いてみて思ったのだが、@Whenアノテーションは@Givenという名前の方がよかったかもしれない。(Then)するとIllegalArgumentExceptionを投げる。これはBDDっぽくってひょっとしてかっこいいのではなかろうか。読者諸賢のご意見を賜りたいところである。08:01(第三回)JCUnitで2次方程式を解くプログラムをテストする。1.7.0_79以前でコンパイルできない。2017でJCUnitの発表をすることになりました。joinedプログラミングはてなブログをはじめよう!dakusuiさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。