出荷テストコード。なぜあなたはそうしませんか?


17

製品と一緒にテストコードを出荷したいと思います。具体的には、プログラムのコピーを持っている人がだれでも「セルフテスト」ボタンを押すか、コマンドラインで--self-testに合格してユニットの完全なスイートを実行できるようにするオプションを提供します。統合テスト。

私は主にこれを現場で発見された問題のデバッグに役立てたいと思っています。そのため、バグレポートがエンドユーザーから届くと、「また、これら3つのテストが私のマシンで失敗しました」によってサポートされる可能性があります。手動テスターでユニットを実行できるようにしたい| 統合テストも同様です。

ただし、チームのテストでは、テストコードは製品コードではないため、出荷されません。ほとんどのオープンソースプロジェクトにはテストスイートが同梱されているため、私は実際にはこの議論を受け入れていません。閉じたソフトウェアでは珍しいようです。

議論のどちらの側にも証拠や逸話を支持したいと思います。どのスタック交換サイトが最も適切かを推測しましたが、これが適切でない場合はお知らせください。


8
クローズドソースプログラム(または変更されていないオープンソースプログラム)の単体テストが失敗するのはなぜですか?製品にかなりの量のセットアップが必要であり、セットアップの問題がバグの原因であることが多い場合、データベース接続の検証、他の外部サービスへの接続の検証などを行う何らかの「構成の検証」アプリを出荷するのは理にかなっているかもしれませんコードは依存しているなどです。ただし、コードが機能することをすでに検証しているため、単体テストが失敗することは意味がありません。
ジャスティンケーブ


15
フィールドで単体テストが失敗するのはなぜですか?私の頭の外:破損したプログラム。危険なハードウェア。ローカルでは見られなかった競合状態。別の動的ライブラリにリンクされています。ウイルス対策またはOSとの競合。更新が不完全なため、関連ソフトウェアの驚くべきバージョンで使用されている。期待どおりに動作しない他のプロセスとの相互作用。フィールドでバグが発生する理由はたくさんあり、それらの多くはユニットテスト(特定のユニットの定義)からヒットする可能性があります
ジョンチェスターフィールド

7
@JonChesterfield:プログラムにセルフテスト機能を作成することは、おそらく良いことです。そして、そのセルフテスト機能がユニットテストのコードを部分的に再利用できるのであれば、なぜですか?ただし、このような機能と再利用可能なパーツは、「生産コードです」という観点で開発する必要があります。
Doc Brown

2
@JonChesterfieldこれらの原因のほとんどでユニットテストが失敗するのを想像するのは大変です。統合テストは別の問題ですが、余分なものをあまり必要とせずに行うことができれば、統合テストを出荷するメリットがあります。
ローレンペクテル

回答:


19

テストコードには、会社の外部と内部の両方のサードパーティからのコードスニペットが含まれることがあります。これは、ユーザーがバグを報告すると発生します。テスト(リグレッションテストなど)は、それらが提供するコードを組み込んで再現します。多くの場合、バグを再現するためのこのようなコードスニペットのライセンスは不明です。したがって、知的財産の問題に​​注意する必要があります。会社の別の部門または外部パートナーの企業秘密または知的財産を誤って明らかにするテストコードを出荷することは望ましくありません。

別の注意として、テストコードが実稼働コード標準に準拠していることはめったにありません。コードレビューは必ずしも行われません。これは残念ながら一般的であり、これらのテストが開発された時点で目標が設定されていなかった場合、必ずしもテストチームに悪い影響を与えるべきではありません。

一方、多くのテストは単に恥ずかしいほど悪いものであり、テスト中と思われるものをテストすることさえしません。それは別の問題です...

最終的に、これらすべての要因のため、テストをオープンソースとして出荷できるものと、単にできないものに分類することをお勧めします。(カスタムテストを出荷することを念頭に置いて、他のテストをそのセットにゆっくりと移行することもできます。)


サードパーティの問題は本当に良い点です。テストコードを「外部から見える」と「おそらく機密」にグループ化すると、エラーが発生しやすくなり、オーバーヘッドが大きくなります。それは、それ自体がほとんどすべてのブレーカーです、ありがとう。
ジョンチェスターフィールド

はい、事実の後にするのは難しい。出荷テストを開発するための献身的な努力で、あなたはもっと幸運に恵まれると思います。
エリックエイド

@ErikEidt:「オープンソースとして」を削除することを提案しました。これはおそらくOPが意図していたことではないからです-彼はテストをクローズドソースとして出荷したいと思います。
Doc Brown

@DocBrown、私はあなたのポイントを取ります。おそらくOPが投稿のどこかで「オープンソース」に言及したので、おそらく解釈の問題です。いずれにせよ、編集はポイントをうまく一般化します。
エリックエイド

18

出荷テスト?はい。出荷単位テスト?番号。

あなたがコメントで言うように、クライアントコンピューターで製品を実行するときに直面する可能性のある問題には、間違ったdllとのリンクなどの問題が含まれます。これは一般的にユニットテストがキャッチするものではありませんコードをテストします)。

さて、dllを呼び出すロジックを呼び出すUIを呼び出す統合テストスイートを出荷します。統合テストでは、ユニットテストが表示されない、インストールの失敗の他の側面を表示できます。(たとえば、私の現在の製品では、ライセンスによりバンドルできないk-liteコーデックのインストールが必要です。単体テストでは、コードが正常に機能しているように見えても、顧客満足度が得られない場合があります。正しく動作しなかった可能性がありますが、単体テストでも表示されません)。

そのため、代わりに統合テストの一部を出荷します。これは、インストール済みの統合製品に必要なものです。


2

クロスプラットフォームを提供しながら、すべての単一CPUコア、SIMD組み込み関数、GPU、GPGPUなどを使用するマルチスレッドの次世代AAAゲームエンジンなど、ハードウェアのあらゆるインチをカバーしている領域でこの懸念を強く理解できました製品。

これらの場合、最悪の悪夢は多くの場合、テストされた最初の5,000の異なるマシン/プラットフォームでテスト(ユニットと統合)に合格しますが、あいまいなGPUモデルのドライバーバグのために5,001番目に失敗します。これについて私は震えを与えます-あなたはおそらくこれらを事前にテストしたり予測することはできません。

特に、GPUシェーダーを作成する場合、関係するすべてのGPUモデル/ドライバーによって実施される移植可能な標準保証がほとんどないため、作成するコードの半分が未定義の動作を引き起こす逆抽選をプレイすることになります。最近では掃海艇をプレイするようになってきていますが、これは人々にいくつかのアイデアを与えるはずです:http : //theorangeduck.com/page/writing-portable-opengl。90年代後半から2000年代初頭にこれを試してみるのは本当に恐ろしく、ずっと掃海艇でした。

この種のケースでは、安定したリリースの前に製品を本当に固め、自信を持って感じるために、非常に幅広いハードウェアとオペレーティングシステムを持つ10,000人以上のテスターのチームが必要になることがよくあります。必ずしもすべての企業が、このような幅の試験基盤を持っている余裕ができ、そしてすべてではない、それは右(すべて広く顕著な問題が修正されなければならない行うには規律を持って前に、他のいくつかの内部プレアルファ/アルファ段階かに非常に多くのテスターを有すること冗長なレポートが殺到すると、開発者はパッチと祈りのパニックに陥ります。

この場合に推奨するのは、他の人が提案したもので、統合テストの分散セットに焦点を当てています。インストーラーにバンドルして、ユーザーが開発者に渡すことができるインストールが失敗した理由の詳細を提供することに注意を払って、基本的な診断チェックに合格するように要求できます。

もう1つ(上司を納得させることができれば)連続した統合を行うために幅広いハードウェアを使用できるようにすることです。ハードウェア/ OSコンボの多様性、メリット。CIサーバーの最低限のハードウェア要件をモデル化するさまざまながらくたハードウェアが必要です。

しかし、もう1つ提案することがあります。

ロギング

上記のシナリオのようなものを扱っている場合、最も問題となる傾向があるこれらのことをテストすることはできません(最悪の時間に表示され、おそらく非常に特定のハードウェア/ OSコンボに制約される問題であるため、最も網羅的なテストスイートです。

しかし、不明瞭なハードウェアの非互換性や完全なドライバーの不具合、間違ったdylib(実際にこの懸念に直面したことはありません)に対するリンクなど、これらの種類の問題のほとんどは、ソフトウェアの起動をはるかに超えません。通常、大まかに言えば、クラッシュしてすぐに燃えてしまいます。

正気のために、避けられないものを受け入れることをお勧めします。包括的にテストできない可能性があるこれらのことについては、おそらく何もできません。ハリケーン(不可能)を防ごうとはしないで、それらの窓に乗り込みましょう。

通常、ここでできる最善の方法は、できるだけ早く問題を見つけて(問題のリストを絞り込むために)できるだけ詳細に問題を見つけ、報告後に問題をできるだけ早く修正することです。

この場合、ロギングは命の恩人になります。これらの種類のフィールドについては、誰も読まないこれらのスパムテクニカルログを作成できます。多くの場合、関連するのは、ユーザーがドライバーの不具合のためにクラッシュに直面する前にログに記録された最後の行だけです。たとえば、クラッシュを監視し、ユーザーがコピーできるログの最後の行を表示する外部プロセスまたはフックを書くことができますクラッシュダンプに加えて、貼り付けます。

これには詳細な情報が必要になることが多く、これらのハードウェア/プラットフォーム/ドライバーの問題に対するコードの最も影響を受けやすい領域の多くはパフォーマンスが重要であるため、ロギングが実際に遅くなるほど頻繁にログが発生する可能性があるこの厄介な問題がありますソフトウェアをダウンします。

この場合の便利なトリックは、1回実行されたものが2回目、3回目などに正常に実行されるという仮定に依存することです。これは最も適切な仮定ではありませんが、多くの場合「十分に良い」(そして何よりも無限に良い) 。これにより、少し外部状態を使用して、何かが既にログに記録されたときを追跡し、コードがループで繰り返し呼び出されるような非常にきめ細かいケースのログ記録の後続の試行をスキップできます。

とにかく、これが役立つことを願っています。私は過去にこの種の誘惑に遭遇しましたが、私と私のチームの過去の経験の結果として、GPUコーディング(GPGPUとシェーダー)を取り巻くパラノイアが少しあります(他のチームメンバーが実際にこれらの特定のRadeonモデルでのアンチエイリアシングされたラインのレンダリングでクラッシュするATIグリッチのように、後のリリース後、クリープが私に与えられました。

ロギングはそこに私たちの尻を救ったものであり、私たちが聞いたことのないオンボードGPUを備えた10,001番目の不明瞭なプロトタイプマシンの問題を頻繁に見ることができ、コードの最後の行ですぐに障害が2になった場所を正確に見つけるまたは疑わしい3行のコード。たとえば、精巧なシェーダー内にある場合、GPUシェーダー内でログを記録できないため、SOLのようなものですが、少なくともロギングを使用して、どのシェーダーに問題が発生したかをすぐに確認できます調査を開始します。


2
ロギングコードのメモは賢いです。現在、主にパフォーマンスの問題のためにログを生成していません。そのため、デバッグにはコアダンプが含まれます。インストーラーに診断テストを組み込むこともお勧めです。詳細な返信ありがとうございます。
ジョンチェスターフィールド
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.