ユニットテストとテスト駆動開発の戦略


16

私は、科学コンピューティングのテスト駆動開発の大擁護者です。実際のところ、このユーティリティは驚異的であり、コード開発者が知っている古典的な問題を本当に軽減します。ただし、一般的なプログラミングでは発生しない科学的コードのテストには固有の困難があるため、TDDテキストはチュートリアルとしてそれほど有用ではありません。例えば:

  • 一般に、与えられた複雑な問題に対する正確な答えはアプリオリにわからないので、どのようにテストを書くことができますか?

  • 並列度が変化します。最近、MPIタスクを3の倍数で使用すると失敗するが、2の倍数で動作するというバグに遭遇しました。さらに、一般的なテストフレームワークは、MPIの性質上、MPIにあまり適していません。タスクの数を変更するには、テストバイナリを再実行する必要があります。

  • 科学コードには、多くの場合、密結合され、相互に依存し、交換可能なパーツが多数あります。私たちは皆、レガシーコードを見てきましたが、良いデザインを放棄してグローバル変数を使用することがどれほど魅力的かを知っています。

  • 多くの場合、数値的手法は「実験」であるか、コーダーがその方法を完全に理解しておらず、理解しようとしているため、結果を予測することは不可能です。

科学コード用に書いたテストの例:

  • 時間積分器については、正確な解をもつ簡単なODEを使用し、積分器が所定の精度内でそれを解くかどうかをテストします。さまざまなステップサイズでテストすることにより、精度の順序が正しいです。

  • ゼロ安定性テスト:境界/初期条件が0のメソッドが0のままであることを確認します。

  • 補間テスト:線形関数が与えられた場合、補間が正しいことを確認します。

  • レガシー検証:正しいことがわかっているレガシーアプリケーションのコードのチャンクを分離し、テストに使用するためにいくつかの離散値を引き出します。

手動での試行錯誤は別として、特定のコードチャンクを適切にテストする方法がわからないことがよくあります。数値コード用に記述するテストの例や、科学ソフトウェアをテストするための一般的な戦略を提供できますか?


内挿テストの意味を明確にしてください。
ドミトリーカバノフ

回答:


8

製造ソリューションの方法

精密化の研究を通じて、メソッドが精度の理論的な順序を達成していることを確認します。

回答の保存。ソリューションのビット単位および標準単位での再現。


元の投稿でMMSに言及するつもりでした。コードの検証には適していますが、単体テストの観点からはまったく価値がありません。それらのテストが失敗した場合、それはどこで、またはなぜかについての手がかりを提供しません。
アウレリウス

3
2×2×2

MMSで私が見た多くの文献は、基本的にはグローバルなソリューションです。たとえば、CFD問題の場合、製造されたソリューションは翼型解析かもしれません。このテストが失敗した場合、せいぜい5,000行のコードに原因を絞り込んでいるので、TDDにとってはまったく価値がありません。実際の失敗がどこで発生したのかはわかりません。2x2x2の問題は非常に価値があり、個人的には頻繁に使用することに同意します。しかし、大規模なシステムでのみ発生する問題に遭遇することはかなり一般的です。私は最近、大きな問題でのみ現れるifortコンパイラのバグを発見しました。
アウレリウス

@Aurelius:ここでは引数はありません。さまざまなテストを用意し、それらをすべて頻繁に実行する必要があります。
ビル・バルト

@Aurelius額面では、MMSは単体テストではなく、機能テストまたは受け入れテスト(つまり、システム全体)です。ただし、コードには多くの場合、別々のステージがあります(または、それらに分割することができます)。例えば、移流、圧力、粘度。その後、これらの段階の1つ(「ユニット」)のみをテストできます。同様に、BCなしでコードをテストしてから、BCでテストすることもできます。友人がユニットテストで博士号を取得し、プログラムをユニットに分割することを余儀なくされたことで最大のメリットが得られたため、ユニットテストできるようになりました...他の方法で私は知らない)。
hyperpallium

6

ビルはあなたの懸念に対処するいくつかの方法をすでにリストしています。

3番目のポイントに対処します。いいえ、部品間に強い結合を導入する理由はありません。反対に、関数またはクラスに明確に定義されたインターフェイスがある場合、たとえば線形ソルバーを別のものに交換したり、タイムステッピングスキームを交換したりするのがはるかに簡単になります。抵抗するだけで、これらのコンポーネントを個別にテストできます。私たちはこれをdeal.IIで何十年も行いました。

4番目のポイント:メソッドが実験の場合、メソッドを使用した実験はテストを構成します。分析がない限り、これらのテスト結果を可能な限り利用する必要があります。しかし、通常は、たとえばメソッドの順序に期待があるか、特定のクラスの解、たとえばある程度までの多項式に対して正確であることがわかります。これらを検証することは実験の一部である必要があり、分析が向上するにつれてテストを追加できます。


1
Guidoの答えに追加するために、彼が話す経験は、変更ごとにdeal.IIで実行する〜3,000のテストにエンコードされています:dealii.org/developer/development/…。正確な回答がわからない場合の対処方法については、テストを作成し、今日の回答と昨日(またはテストを作成したとき)の回答を比較してみましょう。コードの出力の変更を見つける方法があると、答えが間違っているのか、以前に間違った答えを修正したのかわからない場合でも、貴重です。
ヴォルフガングバンガース

3

私は最近、計算科学のTDDに関するこの論文を見つけました。私はまだそれを読んでいませんので、それが良いかどうかはわかりませんが、うまくいけば助けになるかもしれません。

http://cyber.ua.edu/files/2014/12/u0015_0000001_0001551.pdf


1
私はいくつかのイントロと結論をざっと読み、標準的な博士論文と同等の品質レベルを仮定して、これはプロセスを(高レベルの方法で)説明し、その有効性に関する実際の測定値を提供します。これはかなりの発見だと思います。
ゴドリックシーア

リンクは無効です。意味:Nanthaamornphong、A.「計算​​科学および工学ソフトウェア開発におけるテスト駆動開発およびリファクタリング技術の有効性」。博士論文、Uni アラバマ(2014)。
-AlQuemist
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.