科学計算ライブラリの単体テスト


15

以前、ユニットテストの経験が少しありました。(軽jor的ではなく)古典的なソフトウェアエンジニアリングプロジェクト:MVC、ユーザーGUI、データベース、中間層のビジネスロジックなど。 m C#で科学計算ライブラリを作成する(そう、C#が遅すぎること、Cを使用すること、車輪を再発明しないことなど)私たちはそれを必要としています)。ソフトウェア開発業界の観点から見ると、これは小さなプロジェクトです。なぜなら、私はほとんど自分で、そして時々同僚の助けを借りて書いているからです。また、私はそれに支払われません、そして最も重要なのは、学術プロジェクトです。つまり、いつかプロ品質になると期待しています。なぜなら、私はオープンソースになることを計画しているからです。

とにかく、プロジェクトは大きくなり(18,000行程度のコードで、1人のプロジェクトにとっては大きいと思います)、手に負えなくなりました。私はgitをソース管理に使用していますが、大丈夫だと思いますが、古い学校のようにテストしています。つまり、主にシステムの大部分をテストする完全なコンソールアプリケーションを作成しています。このシナリオで単体テストを行うことはできますが、それが私がやるべきことだと思います。問題は、ライブラリの大部分がアルゴリズム(たとえば、グラフアルゴリズム、分類器、数値ソルバー、ランダム分布など)であるということです。これらのアルゴリズムのそれぞれに小さなテストケースを指定する方法がわかりません。確率論的正当性を検証する方法がわかりません。たとえば、分類の場合、精度や再現率などの指標がありますが、ただし、これらのメトリックは、単一のアルゴリズムを判断するよりも2つのアルゴリズムを比較する方が適切です。だから、ここで正確さを定義するにはどうすればよいですか?

最後に、パフォーマンスの問題もあります。まったく異なるテストセットを知っていますが、パフォーマンスは、ユーザーの満足度や他のソフトウェアエンジニアリングメトリックではなく、科学ツールの重要な機能の1つです。

私の最大の問題の1つは、データ構造にあります。kd-treeについて考えられる唯一のテストはストレステストです。大量のランダムベクトルを挿入してから、大量のランダムクエリを実行し、単純な線形検索と比較します。パフォーマンスについても同じです。数値オプティマイザーを使用すると、テストできるベンチマーク関数がありますが、これもストレステストです。これらのテストは単体テストとして分類できるとは思わず、最も重要なのは、それらのほとんどがかなり重いため、継続的に実行されることです。しかし、これらのテストを実行する必要があると思います。2つの要素を挿入してルートをポップすることはできません。はい、0-1-nの場合に機能します。

それで、もしあれば、この種のソフトウェアの(ユニット)テストアプローチは何ですか?そして、コードビルドビルドコミット統合サイクルの周りでユニットテストと重いテストをどのように整理しますか?

回答:


19

科学計算は、実際には単体テストに非常に適していると言えます。明確な入力と出力、明確に定義された事前条件と事後条件があり、おそらくデザイナーの気まぐれに従って1週間おきに変更されることはなく、テストが難しいUI要件もありません。

問題を引き起こす可能性のある要素に名前を付けます。ここでそれらについて何をすべきかです:

  • ランダム化アルゴリズム:2つの可能性があります。ランダム化自体を実際にテストする場合は、多数の繰り返しをスケジュールし、予想されるケースの割合が目的の基準を満たしていることを主張します。(ファントムバグを信頼できない方法で通知するテストスイートは、考えられるすべての欠陥をキャッチしないテストスイートよりもはるかに悪いです)。テストが完全に予測可能になるように注入します。
  • 精度/リコールに関してのみ定義されたアルゴリズム:入力ケースのセット全体を入力し、それらをすべて加算して精度とリコールを測定することを妨げるものは何もありません。テストデータを提供することが生産性のボトルネックにならないように、このようなテストケースを効率的に半自動で生成するだけです。あるいは、適切に選択された入力/出力のペアをいくつか指定し、ルーチンが十分に予測可能な場合、アルゴリズムが目的の入力を正確に計算することをアサートすることもできます。
  • 非機能要件:仕様が実際に明示的なスペース/時間要件を提供する場合、基本的に入出力ペアのスイート全体を実行し、リソース使用量が必要な使用パターンにほぼ適合していることを確認する必要があります。ここでのコツは、最初に独自のテストクラスを調整することです。これにより、サイズが異なる10個の問題を測定できず、測定が速すぎたり、テストスイートの実行が実用的でなくなるほど時間がかかったりしません。PUの実行速度に応じて、さまざまなサイズのテストケースを作成する小さなユースケースジェネレーターを作成することもできます。
  • 高速実行テストと低速実行テスト:単体テストでも統合テストでも、多くの場合、非常に高速なテストといくつかの非常に低速なテストになります。テストを定期的に実行することは非常に価値があるため、私は通常、実用的なルートに進み、すべてを高速スイートと低速スイートに分離します。これにより、高速テストを可能な限り頻繁に実行することができます(コミットする前に確実に)、 2つのテストが「意味的に」一緒かどうか。

+1。どうもありがとう、あなたの答えに洞察があればたくさんあります。ほんの2、3の質問:メタヒューリスティックのような最適化アルゴリズムについてはどうですか。私はたくさんのベンチマーク関数を持っていますが、それらでできることは2つの異なるアルゴリズムを比較することだけです。ベンチマークアルゴリズムも見つける必要がありますか?遺伝的アルゴリズムが正しいとはどういう意味ですか?そして、組換えや突然変異などのタイプのような「パラメータ化可能な」戦略のそれぞれをどのようにテストしますか?
アレハンドロピアド

1
メタヒューリスティックの場合、いくつかの特徴的なI / Oペア、つまりルーチンの「有名な成功」を選択し、メソッド(または2つのうちの良い方)が実際にこの解決策を見つけることを確認します。よく機能する「チェリーピッキング」問題は、もちろん最適化の研究ではありませんが、ソフトウェアテストの場合は問題ではありません。アルゴリズムの品質を主張するのではなく、正しい実装を主張するだけです。それがあなたが証明できる唯一の「正しさ」です。乗算パラメータ化ルーチンについて:はい、私は怖い...テストの組み合わせの量を必要とする
キリアンFoth

それで、すべての正しい実装が正確に解決すべき些細なベンチマークを設計するようなものでしょうか?アルゴリズムの品質を証明する方法はありますか?私はほとんどの場合品質基準を定義できないことを知っていますが、少なくとも変更が達成された品質を低下させないことを望むことができますか?
アレハンドロ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.