単体テストのタイムアウトを使用してメソッドのパフォーマンスを測定することをお勧めしますか?


14

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

一方、ソースコードに誤った変更を加えると、パフォーマンスに深刻な影響を与える可能性があります。早くこのマイナスの影響に着目前のソースコードは、ソースコントロールに到達し、QA部門によって検証され、問題の報告QA部門によって失われた時間の点で有益であり、開発者が後でそれをいくつかのコミットを固定できます。

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

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

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

このアプローチにはいくつかの問題が予想されます。

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

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

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

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

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

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

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

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


¹実際、ユニットテストは、同等のハードウェアパフォーマンスを備えた開発者のPCでのみ実行されることが期待されています。

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

回答:


3

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

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

製品についてはわかりませんが、この場合、パフォーマンスが不十分な場合、それを「修正」するには多くの作業が必要です。したがって、これを完全にQAに任せた場合の所要時間はひどいです。さらに、パフォーマンスの修正はコードベースの大部分に深刻な影響を与え、以前のQA作業を無効にします。全体として、非常に非効率的で不十分なワークフローです。

そうは言っても、それぞれの問題のポイントは次のとおりです。

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

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

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

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

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


3

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

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

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

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

私はVisual Studioの機能を意識しているわけではありませんが、一般的にはより広範なプロファイリングツールが必要です。


2

私はしばらく前に同様の仕事をしてきましたが、最終的な解決策は単体テストと本格的な自動化されたパフォーマンステストの中間にありました。

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

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

そのため、最終的には、拡張性、柔軟性、および予測可能なシステムがあり、特別な要件に合わせて迅速に調整できます。しかし、実装には多少の努力が必要でした。

質問に戻ります。概念的に単体テストはそのためではありませんが、テストフレームワークの機能を活用できます。テストのタイムアウトを測定する手段として考えたことはありません。これはハングなどの安全策にすぎません。しかし、あなたの現在のアプローチがあなたのために働くなら、それを使い続けてください、実用的です。必要に応じて、いつでも空想することができます。


0

私はあなたがうまくやっていると思う。これがまさにユニットテストのタイムアウトを設定するポイントです。何かがうまくいっているかどうかを確認するために、必要以上に長い時間をかけています。このアプローチには制限がありますが、あなたはすでにそれらを認識しているようですので、それらの制限を念頭に置いている限り、問題は見られません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.