web-dev-qa-db-ja.com

単体テストのタイムアウトを使用してメソッドのパフォーマンスを測定することは良い考えですか?

特定のアクションの最大実行時間を指定する 非機能要件 があるプロジェクトでは、QAはハードウェアとハ​​ードウェアの両方の正確な負荷の下で正確なハードウェアを使用して専用マシンでこのアクションのパフォーマンスをチェックする必要があります要件で指定されている荷重。

一方、ソースコードに誤った変更を加えると、パフォーマンスに重大な影響を与える可能性があります。 この悪影響を早期に発見beforeソースコードがソース管理に到達し、QA部門によって検証されます、 QA部門が問題を報告したり、開発者が後で数回のコミットで修正したりすることで、時間を節約できるというメリットがあります。

これを行うには、それは良いアイデアですか?

  • ユニットテストを使用して、同じアクションの実行に費やされた時間²n回を把握するには、

  • C#で[TestMethod, Timeout(200)]属性を使用して テストごとのタイムアウト を使用するには?

このアプローチにはいくつかの問題があると思います。

  • 概念的に、単体テストは実際にはそのためではありません。コードのごく一部をテストするだけで、機能要件のチェックも統合テストも行われません。また、パフォーマンステストも行いません。

  • Visual Studioの単体テストタイムアウトは、初期化とクリーンアップがこれらのテストに存在しないか、結果が短すぎて結果に影響しないことを考慮して、実際に測定されることが予想されるものを測定しますか?

  • この方法でパフォーマンスを測定することは醜いです。ハードウェアや負荷などに関係なく、任意のマシンでベンチマークを実行することは ベンチマークを実行するように であり、あるデータベース製品が常に他の製品よりも速いことを示しています。一方で、これらの単体テストが最終的な結果であるとは限らず、QA部門で使用されるものでもありません。これらの単体テストは、期待されるパフォーマンスに関する一般的なアイデアを提供するためだけに使用され、基本的に開発者に警告するために使用されます彼の最後の変更が何かを壊し、パフォーマンスに重大な影響を与えたこと

  • テスト駆動開発(TDD) これらのテストでは不可能です。コードの実装を開始する前に、そもそもどのように失敗するでしょうか?

  • パフォーマンステストが多すぎると、テストの実行に必要な時間が影響を受けるため、このアプローチは短いアクションのみに限定されます。

これらの問題を考慮に入れて、QA部門による実際のパフォーマンスメトリックと組み合わせる場合、このような単体テストを使用することは依然として興味深いと思います。

私が間違っている?これに単体テストを使用することがまったく受け入れられない他の問題はありますか?

私が間違っている場合、ソースコードがソース管理に到達する前に、ソースコードの変更がパフォーマンスに重大な影響を与えたことを開発者に警告する正しい方法 QA部門によって検証されていますか?


¹実際、単体テストは、同等のハードウェアパフォーマンスを持つ開発者のPCでのみ実行されることが期待されています。これにより、パフォーマンステストに失敗することのない最速のマシンと、テストに合格することができない最遅のマシンとの間のギャップが減少します。

²アクションとは、実行に数ミリ秒かかるかなり短いコードのことです。

14

このアプローチも使用しています。つまり、特定のマシンで定義された負荷シナリオの下で実行時間を測定するテストがあります。通常の単体テストにはこれらを含めないことを指摘しておくことが重要です。ユニットテストは基本的に、変更をコミットする前に、開発者のマシンで各開発者によって実行されます。これがパフォーマンステストに意味をなさない理由については、以下を参照してください(少なくとも私たちの場合)。代わりに、統合テストの一部としてパフォーマンステストを実行します。

これは検証を除外すべきではないことを正しく指摘しました。テストが非機能要件のテストであるとは想定していません。代わりに、それを単なる潜在的な問題の指標と見なします。

あなたの製品についてはわかりませんが、私たちの場合、パフォーマンスが不十分な場合、それを「修正」するために多くの作業が必要であることを意味します。したがって、これを完全にQAに任せた場合のターンアラウンドタイムは恐ろしいものです。さらに、パフォーマンスの修正はコードベースの大部分に深刻な影響を及ぼし、以前のQA作業が無効になります。全体として、非常に非効率的で満足のいくワークフローではありません。

そうは言っても、ここにそれぞれの問題へのいくつかのポイントがあります:

  • 概念的には、これはユニットテストの目的ではないことは事実です。しかし、テストでQAがすべきことを検証するものではないことを誰もが知っている限り、問題はありません。

  • Visual Studio:VSの単体テストフレームワークを使用しないため、それについては何も言えません。

  • 機械:製品によって異なります。製品がカスタムの個別デスクトップマシンを使用するエンドユーザー向けに開発されたものである場合、実際には、さまざまな開発者のマシンでテストを実行する方が現実的です。私たちの場合、指定された仕様のマシン用に製品を提供し、これらのパフォーマンステストをそのようなマシンでのみ実行します。実際、クライアントが最終的に16コア以上を実行する場合、デュアルコア開発者マシンでパフォーマンスを測定してもあまり意味がありません。

  • TDD:初期障害は一般的ですが、必須ではありません。実際、これらのテストを早期に作成すると、従来の単体テストではなく回帰テストとして機能します。テストが早い段階で成功することは問題ありません。しかし、開発者が非機能的なパフォーマンス要件を認識していなかったために、開発者が物事を遅くする機能を追加するときはいつでも、このTDDテストがそれを見つけるという利点を得ることができます。たくさん起こって、それは素晴らしいフィードバックです。毎日の作業を想像してください。コードを記述し、コミットし、昼食を取り、戻ったときに、ビルドシステムは、高負荷環境で実行するとこのコードが遅すぎることを通知します。 TDDテストが最初に失敗しなかったことは、私が受け入れるのに十分いいことです。

  • 実行時:前述のように、これらのテストは開発者のマシンでは実行されず、一種の統合テストのビルドシステムの一部として実行されます。

3
Frank

私はほとんどあなたの考えに沿っています。独立したフローで私の推論を立てるだけです。

1。改善/高速化する前に機能させる
コードがパフォーマンス測定を提供する前に(保証は言うまでもありません)、最初にコードを作成する必要があります正しい、つまり、機能的に機能させます。機能的に間違っているコードを最適化することは、時間の浪費であるだけでなく、開発の妨げにもなります。

2。システムのパフォーマンスは完全なシステムでのみ意味があります
通常、意味のあるパフォーマンスは常に特定のインフラストラクチャに依存するため、システム全体でのみ確認する必要があります。たとえば、モックテスト中にモジュールがローカルテキストファイルから回答を受け取ったが、本番環境ではデータベースからフェッチした場合、以前の

。パフォーマンスのスケーリングは目標ごとに行う必要があります
機能的なシステムができたら、システムのパフォーマンスを分析し、ボトルネックを見つけて理解する必要があります場所パフォーマンスをスケールアップする必要があります。完全なシステムのパフォーマンスを知る前に盲目的にすべてのメソッドを最適化しようとすると、無駄な量の作業(重要ではないメソッドの最適化)が発生し、コードが不必要に肥大化する可能性があります。

Visual Studioの機能についてはまだ承知していませんが、一般的にはより広範なプロファイリングツールが必要です。

3
Dipan Mehta

私は少し前に同様のタスクを経験しましたが、最終的なソリューションは、単体テストと本格的な自動化されたパフォーマンステストの中間にありました。

特定の順序ではないいくつかの考慮事項。これは役立つ場合があります。

  • QAによるパフォーマンステストは労働集約的であり、独自のスケジュール(たとえば、反復で1回)があったため、ソース管理を打つことは問題ではありませんでした。
  • 私たちのシステムは大規模でモジュール式であり、ユニットテストは私たちのニーズに対して細かすぎました。特別な「ファット」ユニットテストを作成して、関心のある特定の領域でパフォーマンスの問題を引き起こしました(これらも分類されていますが、これは実装の詳細)。
  • 単体テストには通常の制約が引き続き適用されます。それらは小さく、高速で、適切なものでなければなりません。
  • テストフレームワークの影響を排除するために、それらは特別なラッパーによって実行されていたため、特定の操作にかかる時間正確にがわかっていました。
  • 実際の実装が完了する前にそれらを書くことは可能です(結果によっては、プロセスによっては無関係または有用になる場合があります。開発者は実装をまだ実験中であり、全体的な状況を知りたいと考えています)。
  • それらはeachビルド後にCIサーバーによって実行されていたため、合計実行時間は比較的短く保つ必要があります(そうでない場合、問題を引き起こした正確な変更を特定するのがかなり難しくなります)。
  • CIサーバーは強力で、ハードウェアが修正されたため、これを専用マシンとして数えました(リモートビルドエージェントを使用することで、本当に専用サーバーを使用することが可能です)。
  • テストラッパーは、すべての関連情報(ハードウェア仕様、テスト名/カテゴリ、システム負荷、経過時間など)を収集し、それをレポートとして、またはデータベースにエクスポートしました。
  • JIRAがそれらのレポートをプルし、いくつかのコントロール(以前のリリースを現在のバージョンにオーバーレイするなど)で名前/カテゴリ/ビルド番号でナイスチャートを描画するためのガジェットを用意したので、開発者はその影響をすばやく確認でき、マネージャーは概要を取得できます(一部の赤、すべて緑、それは彼らにとって重要です)。
  • 収集された統計を使用することにより、プロジェクトが時間とともにどのように進んでいるかを分析することができました。

したがって、最終的に、特別な要件に合わせてすばやく調整できる、スケーラブルで柔軟で予測可能なシステムができました。しかし、それを実装するにはいくらかの努力が必要でした。

質問に戻ります。 概念的には単体テストはそのためのものではありませんが、テストフレームワークの機能を活用できます。テストのタイムアウトを測定する手段と見なしたことはありません。これは、ハングなどのセーフティネットにすぎません。しかし、現在のアプローチがうまくいくなら、それを使い続け、実用的です。必要が生じた場合は、いつでも後で気に入ることができます。

2
Oleg Kolosov

元気だと思います。これがまさにユニットテストタイムアウトのポイントです。何かがway、wayを必要以上に長く取っているかどうかを確認します。このアプローチには制限がありますが、あなたはすでにそれらに気づいているようですので、それらの制限を念頭に置いている限り、問題は発生しません。

0
Mike Baranczak