web-dev-qa-db-ja.com

TDDを実行するときにロギングが必要ですか?

Red、Green、およびRefactorサイクルを実行する場合、テストに合格するための最小のコードを常に記述する必要があります。これは私がTDDについて教えられた方法であり、ほとんどすべての本がプロセスを説明する方法です。

しかし、ロギングについてはどうですか?

正直なところ、本当に複雑なことが起こらない限り、アプリケーションでロギングを使用することはめったにありませんが、適切なロギングの重要性について述べた投稿を数多く目にしました。
そのため、例外をログに記録する以外に、適切にテストされたアプリケーション(ユニット/統合/受け入れテスト)でのログの重要性を正当化できませんでした。

だから私の質問は:

  1. TDDを実行している場合、ログに記録する必要がありますか?失敗したテストは、アプリケーションの何が悪いのかを明らかにしませんか?
  2. 各クラスの各メソッドにロギングプロセスのテストを追加する必要がありますか?
  3. たとえば、本番環境で一部のログレベルが無効になっている場合、テストと環境の間に依存関係が生じませんか?
  4. ログがデバッグを容易にする方法について人々は話しますが、TDDの主な利点の1つは、失敗したテストが原因で何が問題であるかを常に知っていることです。

私が見逃しているものはありますか?

42
Songo

1)TDDを実行している場合、ログに記録する必要がありますか?失敗したテストは、アプリケーションの何が悪いのかを明らかにしませんか?

これは、アプリケーションが必要とするすべての可能なテストがあることを前提としています。ログは、まだテストを記述していないバグを追跡するのに役立ちます。

2)各クラスの各メソッドにロギングプロセスのテストを追加する必要がありますか?

ロガー自体をテストする場合、他の依存関係と同様に、各クラスでロガーを再テストする必要はありません。

3)たとえば、本番環境で一部のログレベルが無効になっている場合、テストと環境の間に依存関係が生じませんか?

人間(およびログアグリゲーター)はログに依存しているため、テストはログに依存すべきではありません。通常、次のようないくつかのログレベルがあり、一部は本番環境で使用され、一部の追加レベルは開発で使用されます。

「Railsログレベルは本番モードの情報であり、開発とテストのデバッグ」- http://guides.rubyonrails.org/debugging_Rails_applications.html

他のアプリケーションも同様のアプローチを使用します。

4)ログがデバッグを容易にする方法について人々は話しますが、TDDの主な利点の1つは、失敗したテストが原因で何が問題であるかを常に知っていることです。

本番環境のバグはすべてのテストに合格しているため、これらの問題を調査するには他の参照が必要になる場合があります。

50
FMJaguar

Logging は、アプリケーションの説明に役立ちます非例外的な動作

イベントログシステムの実行中に発生するイベントを記録して、システムのアクティビティを理解し、問題を診断するために使用できる 監査証跡 を提供します。これらは、特にユーザーとの対話がほとんどないアプリケーション( server アプリケーションなど)の場合、複雑なシステムのアクティビティを理解するために不可欠です...

アプリケーションがどのようにテストされても、例外がどれだけ適切にログに記録されていても、そのユーザーは

プログラムの出力は0ですが、1であると予想していましたが、なぜですか。

(例外ではない)動作を説明するために、アプリケーション構成、パラメーター、およびその他のランタイムの詳細を確認するには、ロギングが必要です。

上記の観点から、ロギングは開発よりも support を重視しています。アプリケーションが稼働した後、プログラマーがさらなる開発に集中できるように、他の誰かにユーザーからの質問を処理させることが望ましいです。

アプリケーションの動作をログに記録すると、誰か他の人がコードを掘り下げることなく、また何が起こっているかを説明するリクエストで開発者の注意をそらさずにプログラムの動作を理解できます。

34
gnat

ここでのほとんどの回答は、正しさの側面に焦点を当てています。ただし、ロギングは別の目的でも機能します。ロギングは、パフォーマンスに関連するデータを収集する方法の1つです。したがって、システムがエラーなしで動作する場合でも、ログが原因でそれが遅い理由を知ることができます。すべての側面を完全にテストした場合でも、テストスイートではわかりません。

もちろん、パフォーマンスが重要なシステムは、いくつかの運用ダッシュボードに主要なパフォーマンスメトリックを提供できますが、「クラシック」ロギングは、異なるレベルの詳細を提供できます。

17
johannes
  1. 通常は当てはまらない100%のテストカバーがない限り、ソフトウェアがクラッシュしないことはわかりません(編集:そして、コメントで述べたように、クラッシュしても、ソフトウェアに依存しない何かが原因である可能性があります。クラッシュ);これは、バグがまったくないソフトウェアを実行できると考えるのと同じです(NASAでもこれを実行できるわけではありません)。したがって、少なくとも、プログラムがクラッシュした場合に考えられる障害をログに記録して、その理由を知る必要があります。

  2. ロギングは、使用しているテクノロジーに応じて、外部ライブラリまたはインターンフレームワークで行う必要があります。つまり、それは以前にテスト済みである必要があり、自分でテストする必要がないということです。すべてのメソッドが想定されていることをログに記録することをテストするのはやり過ぎです。

  3. ログはテスト用ではありません。依存関係は一切ありません。とは言っても、制約が感じられる場合は、テストのロギングを無効にする必要はありませんが、ログは環境に対応するファイルに保存する必要があります(テスト、開発、本番環境には別のファイルが必要です)少なくとも)。

  4. エラーは非常に不明確である可能性があり、1つのTDDテストが失敗したときに何が問題であったかが常に明らかであるとは限りません。ログはより正確でなければなりません。たとえば、並べ替えアルゴリズムを実行していて、テストケース全体が失敗した場合は、アルゴリズムのすべてのテストのログを取得して、問題が実際にどこにあるかを特定できるようにする必要があります。

8
Pierre Arlaud

主な質問に対する簡単な答えは、原則として、コードのバグはTDDによって公開されません。 Some理想的には多くの可能性がありますが、失敗したテストがないことは、バグがないことを意味しません。これは、ソフトウェアテストにおいて非常に重要な格言です。

まれな状況で、システムで不正な動作が発生するかどうかがわからないため、ロギングは、必然的に問題が発生したときに何が問題かを理解するのに役立つ便利なツールです。

ロギングとTDDは、さまざまな問題に対処します。

8
Andres F.

はい、一般的なケースではロギングが必要です。

ロギングはデバッグに関するものではありません。ええ、そうですね、ログ記録の一部はデバッグに関する場合もあり、開発中に必要がなければ、その部分をスキップできます。

しかし、ロギングのより重要な部分は保守性についてです。適切に設計されたロギングは、次の質問に答える可能性があります。

  • アプリケーションはまだ生きていて、キックしていますか? (1000秒ごとにハートビートをログに記録します。)
  • 過去10か月間にアプリケーションのパフォーマンスは変化しましたか? (ユースケースのパフォーマンスの統計をログに記録します。)
  • 過去10か月間にアプリケーションの負荷は変化しましたか? (リクエストタイプごとのリクエスト数をログに記録します。)
  • インターフェースのいずれかがパフォーマンス特性を変更しましたか?
  • 新しいリリースでは、一部のサブシステムに対して異なる使用特性が発生しますか?
  • DoS攻撃 の下にいますか?
  • どのようなエラーが発生していますか?

これはすべて、ロギングによって実現できます。そして、はい、それは計画され、設計され、テストされるべきです、できれば自動です。

ロギングは、他の機能と同様に、扱いに値する機能です。

5
Jens Schauder

TL; DR:ロギングとTDDは直交しています。一方が存在しても、もう一方は必要ありません

TDDを実行している場合、ログに記録する必要がありますか?失敗したテストは、アプリケーションの何が悪いのかを明らかにしませんか?

概して、私が実装したほとんどのログは、実装のデバッグ用ではなく、運用上のトラブルシューティング用でした(役立つかもしれませんが)。このログ記録の主な対象者は、サーバーを実行する管理者と運用担当者、分析のためにログをサーバーに送信した人、およびログを見て何が起こっているのかを理解しようとする顧客です。

これらのログは、統合ポイントに関連する問題のトラブルシューティングに役立ちます。これには、ネットワークサービス(データベース、石鹸など)、ローカルリソース(ディスク、メモリなど)、不良データ(顧客入力、不良/破損したデータソースなど)などがあります。例外のキャプチャ、障害のロギング、さらには情報ログの実行(設定、構成など)はすべてトラブルシューティングに役立ちます。

各クラスの各メソッドにロギングプロセスのテストを追加する必要がありますか?

ロギングをテストするために必要な場所にテストを追加します。情報をログアウトするための特別な呼び出しがある場合は、それらをテストする必要があります。ただし、アスペクト指向プログラミングまたはメタプログラミングを使用してロギングとログテストを実装すると、テストの負担が軽減される場合があります。

たとえば、本番環境で一部のログレベルが無効になっている場合、テストと環境の間に依存関係が生じませんか?

IoCを使用してコードを記述していて、モックを利用している場合、特定の環境設定に依存することなく、すべてのロギングを効果的にテストできるはずです。

4
dietbuddha

TDDは通常、コーディングのバグを減らすのに役立ちます。仕様のバグや、物事がどのように機能するかについて誤解していることで、それははるかに少なくなります。

「ああ?データメッセージを受け取ることができますbeforeログオンが成功したことを確認できますか?私はそれを知らなかったので、うまく処理できません!」...そういうことです。ロギングは、ソフトウェアが何をしようとしたのかを伝えるのに非常に役立ちますので、間違ったことを見つけることができます。

3
JohnB

私の経験では、TDDを実行しない場合、アプリケーションに優れたレベルのロギングが追加されます。次に、不確実性のレベルが高くなるため、何が起こっているかを確認するためにログを追加します。

一方、TDDを実行しているとき(またはテストのたびにテストしているとき)は、追加するログステートメントがはるかに少なくなります。これは、LOCが少なくなり、(常にではないが)パフォーマンスに影響する可能性があることを意味します。

ただし、開発方法に関係なく、ほとんどの場合、会社では関数の出入りログを半自動的に追加します。私が知っているように、これは生産の問題分析のために必須であると考えられました。

例としては、パブリックインターフェースに存在するEJBサービスBeanのメソッドがあります。もう1つは、関数が複雑な計算を行う場合です。メソッドに数値を入力することは非常に役立ちます(たとえば、目の前の一般的なトピックに戻るための単体テストを作成できます)。

2
dbalakirev