単体テストは本当にドキュメントとして使用されていますか?


22

「ユニットテストは、テスト中のコードのドキュメントの非常に重要なソースである」という流れの中でステートメントを読んだ回数を数えられません。それらが真実であることを否定しません。

しかし、個人的には、ドキュメントとしてそれらを使用していることを発見したことはありません。私が使用する典型的なフレームワークの場合、メソッド宣言はそれらの動作を文書化しており、それが私が必要とするすべてです。そして、ユニットテストでは、そのドキュメントに記載されているすべての内容に加えて、内部的なものがバックアップされる可能性があるため、一方では文書化を複製し、他方では無関係なものを追加する可能性があります。

質問は次のとおりです。ユニットテストはいつドキュメントとして使用されますか?コメントがすべてを網羅していないときは?開発者はソースを拡張しますか?そして、ドキュメント自体が公開できない有用で関連性のあるものを公開しますか?


4
単体テストをドキュメントとしてそのまま使用することを考えたことがありません。多くの開発者がそれらを明確に書くのに時間をかけないため、ユニットテストはしばしば読めないと思います。
-superM

10
コメントが間違っている可能性があります。

2
私はあなたのユニットテストについて、具体的求めている知っているが、私はまた、ちょうど別のレベルで、あまりにも本当に有用な文書としてその統合/システムテストを注意したい
JK。

3
「ユニット実験」としてよりよく特徴付けられる単体テストを見てきました。外部要因への依存は、それらをほとんど役に立たないほどにした。彼らも非常に不明瞭でした。(はい、私はそれらをより良くするためにリファクタリングするという長期的な目標を持っていますが、私は他のこともします…)
ドナルフェローズ

4
@Ant単体テストは実際のコードを呼び出し、予想される応答を文書化し、実際の応答と比較します。呼び出されたコードが正しいかどうかはポイントではありません-テストはそれを呼び出す方法を文書化します。

回答:


17

それらは絶対参照ドキュメントではありません

テストのように、コードとの同期が取れなくなる可能性があるため、以下にもコメントが多く適用されることに注意してください(ただし、強制力は劣ります)。

そのため、最終的に、コードを理解する最良の方法は、読み取り可能な作業コードを持つことです

可能な限りハードワイヤードの低レベルコードセクションまたは特に扱いにくい条件を記述しない場合、追加のドキュメントが重要になります。

  • テストは不完全な場合があります。
    • APIは変更され、テストされていませんでしたが、
    • コードを書いた人は、テストする最も重要なメソッドの代わりに、最初にテストする最も簡単なメソッドのテストを書いたので、終了する時間がありませんでした。
  • テストは廃止される可能性があります。
  • テストは非自明な方法で短絡され、実際には実行されません。

しかし、彼らはまだ有用なドキュメント補完です

ただし、特定のクラスが何をするのか疑問がある場合、特にかなり長く、あいまいでコメントがない場合(種類を知っている...)、私はすぐにそのテストクラスを見つけてチェックしようとします:

  • 彼らが実際にチェックしようとするもの(開発者が「簡単な」テストのみを実装するという上記のエラーを行った場合を除き、最も重要なヒントについてのヒントを与えます)、
  • コーナーケースがある場合。

場合はプラス、BDD-スタイルを使用して書かれた、彼らはクラスの契約のかなり良い定義を与えます。IDEを開いて(またはgrepを使用して)メソッド名と多田のみを表示します。動作のリストがあります。

回帰とバグもテストが必要

また、回帰およびバグレポートのテストを作成することをお勧めします。何かを修正し、ケースを再現するテストを作成します。それらを振り返ると、たとえば、関連するバグレポートと古い問題に関するすべての詳細を見つけるための良い方法です。

実際のドキュメントを補完するものであり、少なくともこの点で貴重なリソースであると思います。適切に使用すれば、優れたツールです。プロジェクトの早い段階でテストを開始し、それを習慣にすると、非常に優れたリファレンスドキュメントになる可能性があります。すでにコーディングベースが悪臭を放っているコーディングコーディングの悪い既存のプロジェクトでは、慎重に扱ってください。


どうしてダウン投票されたのかと聞いてもいいですか?そこで何があなたを夢中にさせますか、あなたは何に反対しますか?
ヘイレム

2
引数の(IMO)の最良の部分は最小のフォントで記述されています-コードを理解する最良の方法は、最初に読み取り可能なコードを用意することです。これを「読みやすく動作するコード」に変更しますが、同意します。その後、ユニットテストをもう一度見ると、実行中のテストは動作中のコードであるため(すべてのコードと同様、読み取り可能である必要があります)、うまくいけば実際にはかなり良い(多くの場合ローカルすぎる)ドキュメントです。
ジョリスティマーマンズ

@MadKeithV:ありがとう。「読みやすく動作するコード」に更新し、そのビットを上に押し上げました。
ヘイレム

11

1つの解釈は、単体テストは「実行可能なドキュメント」であるということです。コードに対して単体テストを実行すると、テストが成功するように記述されたときと同じように実行されているかどうかがわかります。そのようにして、ユニットは実行可能な方法で、ある時点でシステムの機能を「文書化」します。

一方、機能を理解するために、ユニットドキュメントコードを「ドキュメント」として実際に読むことはほとんどありません。単一の単体テストは、テスト対象のクラスの背後にある実際のシステムについて多くを伝えることができるように、あまりにもローカライズされ、具体的かつ抽象的です。


5

ドキュメントでコードの仕組みを知りたい場合、単体テストは、コードのユニットが予想されるエッジケース、およびミス(別名バグ)の両方のケースで機能する方法の完璧な小さな例です。また、コードを記述する前にテストを作成して、ビジネス/要件の観点からコードが行うべきことの基礎とすることもできます。

ドキュメントを置き換えていますか?いや

それらはドキュメントの役に立つ補遺ですか?はい。


4

私はユニットテストを次のように見ています:

  • ドキュメントが正しいことを証明する方法(ドキュメントがAPI実装と一致すると仮定)。
  • 特定の機能の使用方法を開発者にデモする方法。ユニットテストフィクスチャ/ユニットテスト自体は通常、十分に小さく、すぐに学習できます。
  • そして、明らかに回帰バグを見つけます。

ある程度までは、既存のドキュメントを補完するものとして見ることができますが、ドキュメントとしてではありません。


3

別の質問をして、あなたの質問に答えます。

新しいAPI /ルーチンを使用して、使用しようとしているもののコード例を探すためにヘルプを起動した頻度はどれくらいですか?コードサンプルのオンライン検索のためにGoogleに切り替えることに失敗しましたか?

これは、ユニットテストをドキュメントとして使用する場合とまったく同じです。

  • 実際には、複数のテスト(例)が必要なので、単体テストは通常​​のコード例よりも少し厳密になる可能性があります。
  • ユニットテストで適切な使用法を説明できれば幸いです。たとえば、通常のオブジェクトまたはモックオブジェクトを介して、すべての重要な依存関係を明確に示します。(そうでなければ、それらは特に良い単体テストではありません。)
  • 注:コメントまたは「通常のドキュメント」にコード例が記載されている場合、実際にはDRYの原則に違反しています。また、これらのコード例は時間の経過とともに簡単に不正確になる可能性がありますが、定期的に実行される単体テストではその可能性は大幅に低くなります。
  • 単体テストが徹底的である場合(通常はifが大きい場合)、追加情報を提供する必要があります。
    • すべての既知のエッジケースが明確に示されています。
    • スローされる可能性があるすべての予期される例外。
    • 以前に見つかったすべてのバグ(これは、ユニットの新しいクライアントを作成するときよりも、テスト対象のユニットを拡張するときのほうがおそらく便利です)。
    • ユニットに関連付けられているすべての基礎となるビジネスルール。(もしあれば)

私はユニットテストは、彼らがいてもドキュメントとして慣れるする傾向がないかなりの数の理由がある疑いがある可能性があり、より伝統的なドキュメンテーションに優れた補完することが:

  • 私は、テスト自体が目的のために十分に書かれていないことが多いことを提案しようと思います。他の答えは、次のテストについてすでに示唆しています:
    • 不完全な。
    • 紛らわしい。(テスト中のメソッドを直接呼び出さないテストケースを見てきました-呼び出される前に呼び出しスタックの3/4レベル深くに行き、メソッドを呼び出すための前提条件が複雑なクラス階層の異なる場所に散在しています。 )
    • 古い。(通常、テスト古くなると失敗しますが、常にそうであるとは限りません)。
  • 例の必要が生じたときはいつでも、実動コードですでに利用可能な使用例がたくさんあります。
  • テスト対象のユニットは非常によく記述されているため(自己文書化)、メソッドには例は必要ありません。私は望む!
  • プログラマーとしての私の経験では、来週の火曜日にディープエンドとRTFMに飛び込みたいと思います...
  • DRYの原則に違反するドキュメントとコメント。

2

TL; DRユニットテストとAPIコメントは相補的です。コードで最もよく記述されているものと、散文で記述されているものがあります。

ユニットテストは主に、APIコメントで説明するのが難しい(そして扱いにくい)特殊なケースとエッジ条件を文書化するのに役立ちます。また、APIコメントは通常、APIを使用したい人に向けられています。

コードを変更したい場合は、通常、さらに多くのことを知る必要があり、その一部はコメントに入れるのが困難です(そして、これらのコメントはすぐに古くなってしまいます)。その場合、単体テストはドキュメントとしても機能します。

例:(a, b)特定の計算を実行するメソッドm があります。後方互換性の要件のために、それは特殊なケースの入力を必要a=0a=-1が、唯一の場合はbNULLです。それをコメントに入れることは複雑で冗長であり、要件が後で削除されると古くなる可能性があります。

あなたがチェックの行動といういくつかのユニットテストを作る場合m(0, NULL)m(-1, x)あなたはいくつかの利点が得られます。

  • 正しい動作の説明は明確であり、誤解が減ります
  • コメントとは異なり、人々はコードを変更するときに要件を見落とすことはできません

しかし、あなたの例では、その動作がコメントにまったく文書化されていない場合、ユーザーはそのエッジケースで予期しない結果を得る可能性があります。これはまったく良いことではありません。
stijn

@stijn:はい。その場合、おそらく最善の方法は、ドキュメント内の特別なケースについて簡単に言及し、さらに厄介な詳細についての単体テストを行うことです。
sleske
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.