Quickcheckとそのバリアント ( Javaにもある) は興味深いようです。ただし、学術的な関心は別として、実際のアプリケーションのテスト (たとえば、GUI アプリケーションまたはクライアント/サーバー、または StackOverflow 自体を使用することさえ) で本当に役立ちますか? 同様のテスト ジェネレーターを使用した経験があれば、歓迎します。
11 に答える
はい、そうですね。いえいえ、もともと QuickCheck を開発した方に師事したことがありますが、とても面白い方です。
2004 年に戻ると、QuickCheck を使用して Haskell プログラムをテストすることを余儀なくされましたが、これには良い面と悪い面がありました。Haskell はそれ自体が少し手ごわいものだったので、たいてい悪いことでしたが、実際に機能させてみると、それほど素晴らしいものではありませんでした。
ジョンはそれ以来、何年も前に書いたものを完成させ、実際にエリクシオンが複雑な通信ハードウェアをテストするのを手伝いました.2,000万行ほどのコードでバグを発見し、彼のアプローチによってそれをわずか3ステップに減らしました. 彼は素晴らしい講演者なので、彼が得意なことを紹介するのを聞くのはいつも楽しいことですが、全体として、彼が QuickCheck で行ったことは私にとって新しいことでした。そこで私は彼に、これを市場に出すことにどのような関心を持っているのか尋ねました。彼はこのアイデアにオープンでしたが、当時彼のビジネス (QuickCheck をベースとしていた) は比較的新しく、彼が注力する他の分野がありました。これは現在 2007 年です。要点は、QuickCheck を使用しなくても、QuickCheck から学ぶことができるということです。
しかし、QuickCheck とは何ですか? これは組み合わせテスト フレームワークであり、プログラムをテストする興味深い方法です。Microsoft Research の人々は、似たようなPexを構築しました。Pex は、IL を調べてテストを自動的に生成します。ただし、John は、関数の可能な入力およびテスト プロパティのジェネレータを作成します。プロパティは簡単にテストできるもので、より形式的です。たとえば、リストを反転しますか? リストを逆にすることは、リストを 2 つに分割し、それぞれを個別に逆にしてから、逆にした 2 つの半分を逆の順序で連結することと同じことです。
1,2,3,4 // original
1,2 3,4 // split into A and B
2,1 4,3 // reverse A and B
4,3,2,1 // concat B and A
これは、仕様と呼ばれる QuickCheck でテストする優れた特性であり、結果は非常に驚くべきものです。
Pex は優れていますが、QuickCheck ほどクールではありません。Pex は物事を単純化します。QuickCheck はそうしますが、優れた仕様を作成するには多くの労力が必要です。
QuickCheck の威力は、エラーが発生したときに、テストの失敗の原因となった入力を可能な限り最小の形式に減らすことです。テストが失敗した原因となった状態の進行の詳細な説明を残します。力ずくでコードを壊そうとする他のテスト フレームワークと比較して。
これは、テスト仕様の書き方によって可能になります。QuickCheck は疑似ランダム性に依存して入力を作成します。これにより、バックトラックが可能になり、テストに合格しない非常に小さな入力を見つけることができます。
QuickCheck プロパティを記述するのはより多くの作業ですが、最終的にはより良いテストになります。ジョン自身が言ったように、バグの 70% は単体テストによって発見されますが、残りの 30% がプログラムのクラッシュを引き起こします。QuickCheck はこれらの最後の 30% をテストしています。
離散イベントシミュレーションを含む実際のHaskell問題を実行しました。そこで、MVarsとChannelsに相当するものとともに、継続モナドに基づいたDESライブラリを作成しました。これが正しく機能することを確認する必要があったので、たとえば、チャネルに書き込まれた同時データの2つのストリームが何もドロップせずに正しくマージされることを示すために、一連のQuickCheckプロパティを作成しました。
また、QuickCheckを使用して、範囲セットおよび10進ライブラリのプロパティを文書化および検証しました。
私の経験では、QuickCheckは時々素晴らしいです。重要なプロパティを簡潔に要約できれば、そのプロパティを提供するアルゴリズムは厄介ですが、QuickCheckは大きなメリットになります。一方、アルゴリズムは検証したいプロパティと同等であることがよくあります。その場合、私はより単純なプロパティを探します。たとえば、関数「foo」が厳密に単調ではないと想定されているとします。その後、あなたは書くことができます
prop_fooMonotonic x y = (x > y) ==> (foo x >= foo y)
私は QuickCheck を多くの個人的なものに使用しています。過去 6 か月以内:
QuickCheck を実行して、画像圧縮プログラムでの色変換と離散コサイン変換をテストしました。
QuickCheck を実行して、数値最適化のために作成した記号微分モジュールをテストしました。
QuickCheck を実行して、Bentley と Sedgewick のスタイルで三分探索ツリーをテストしました。
QuickCheckが単体テストのニーズをすべて満たすことはめったにありませんが、始めるには最適な方法です。また、QuickCheck の法則は優れたドキュメントを作成します。
主にプロトコルとパーサーの実装をテストするために、主に簡単な方法で、かなり多く使用してきました。
ただし、ここに私の個人的な経験からの些細なことはありません: http://www.haskell.org/haskellwiki/QuickCheck_as_a_test_set_generator
ScalaCheck (Scala の QuickCheck) はFunctional Javaをテストするために使用されます。これは、特にQuickCheck for Java を実装するライブラリです。
AFAIK XMonadはQuickCheckで広範囲にテストされています
私はHaskellを本番環境で小さなヘルパーツールの開発にしか使用していません。主な理由は、私が知っている Haskell を読む唯一の開発者だからです。私は QuickCheck を広範囲に使用しましたが、C# で同様の機能が利用できないことに本当に腹を立てました。だから私はそれを自分で書いてみることにしました。私も Pex を調べましたが、最小限の入力を見つけるために使用されるプログラム探索手法は、QuickCheck が行う方法よりも面白くないことがわかりました。
私は QuickCheck を使用して、任意の言語で記述されたコマンドライン プログラムの動作をテストしています。
低レベルまたは動的に型付けされたプログラムがクラッシュする入力を見つけるのに特に役立ちます。
便宜上、http://hackage.haskell.org/package/proctestを作成しました。これには、この方法でコマンドライン プログラムをテストするために hspec および HUnit と一緒に使用される QuickCheck の例が含まれています。
LG Linux Mobile プラットフォームで SMS PDU エンコーダーとデコーダーをテストするために QuickCheck を使用しました。当時私が開発したソフトウェアの (古い) バージョンは、 http://hackage.haskell.org/package/GenSmsPdu-0.1からダウンロードできます。
これは私のプロジェクトではありませんが、このcontainers
パッケージでは QuickCheck がかなり広範囲に使用されています。個人的には、それを使って、私が書いたばかげた小さなプライム シーブを の 1 つと比較してarithmoi
みましたarithmoi
。