Ruby
 Computer >> コンピューター >  >> プログラミング >> Ruby

どのくらいのテストが多すぎますか?

ひどくテストされたコードを扱うのがどれほど苦痛か知っています。バグを修正するたびに、さらに5つ作成します。そして、物事が 動作しますが、それがそのように設計されたのか、それとも偶然に動作したのかはわかりません。

一方、1つの小さな機能を出荷するために200のテストのように見えるものを書いただけです。 100%のテストカバレッジを達成するには、すでに機能しているコードを常に再設計する必要があります。最高のテストを行ったコードがどういうわけか少なくなっているという感覚を揺るがすことはできません。 読み取り可能。そして最悪の場合、アプリが燃え尽き始めています。

妥協点があるに違いありません。では、適切な量のテストはどれくらいですか?

原則として使用できる適切なラウンド数があれば素晴らしいと思います。アプリコードの2倍の行数、または95%のテストカバレッジです。 しかし、「95%のテストカバレッジ」と言ってもあいまいです。

カバレッジはインジケーターにすることができます 十分にテストされたコードですが、保証ではありません 十分にテストされたコードの。カバレッジが85%のアプリよりもバグが多い、カバーが100%のアプリがあります。

したがって、適切な量のテストを数にすることはできません。代わりに、それはより曖昧で、定義するのが難しい何かについてです。 効率的にテストすることです 。

効率的なテスト

効率的にテストすることは、最小限の作業で最大の利益を得ることがすべてです。いいですね。

しかし、より効率的にテストすることには多くのことがあります。 したがって、特にサイズ、分離、フォーカスの3つについて考えると役立ちます。

サイズ

統合テストは素晴らしいです。これらは、実際の人がアプリを通過する経路を反映しています。 実際の世界で使用されているのと同じように、すべてのコードを連携してテストします。

しかし、統合テストは遅いです。それらは長くて乱雑になる可能性があります。また、システムの1つの小さな部分を徹底的にテストする場合は、多くのオーバーヘッドが追加されます。

ユニットテストは小さいです。彼らはより速く走ります。 システムを作成するときは、システムのごく一部を頭の中に入れておけばよいので、簡単に考えることができます。

しかし、それらは偽物である可能性もあります。単体テスト内で何かが機能するからといって、それが現実の世界でも機能することを意味するわけではありません。 (特に、モックをたくさんしている場合)

では、それらのバランスをどのように取っていますか?

単体テストは高速で簡単に記述できるため、多くの単体テストを作成するのにそれほど費用はかかりません。したがって、エッジケースや複雑なロジックなどをテストするのに最適な場所です。

システムの十分にテストされた部分がたくさんある場合でも、ギャップを埋める必要があります。これらの部分がどのように相互作用するか、そして誰かがあなたのアプリを通過する可能性のある完全な旅をテストする必要があります。ただし、ほとんどのエッジケースとロジックは単体テストでテストされるため、必要なのは、これらのより複雑で低速な統合テストのいくつかだけです。

「テストピラミッド」と呼ばれるこのアイデアが聞こえます。 これはいくつかの統合テストであり、多くの単体テストの基盤の上にあります。そして、それについてもっと知りたい場合は、私の本の第3章、PracticingRailsを見てください。

分離

それでも、システムが複雑な場合は、遭遇する可能性のあるすべての状況をカバーするために、無限の数のテストのように感じるものが必要になる場合があります。これは、アプリのデザインを再考する必要があることを示している可能性があります。 これは、システムの一部が相互に密接に依存していることを意味します。

いくつかの異なる状態のいずれかになり得るオブジェクトがあるとします。

case user.type
when :admin
  message = admin_message
when :user
  message = user_message
when :author
  message = author_message
else
  message = anonymous_message
end

if user.preferred_notification_method = :email
  send_email(message)
elsif user.preferred_notification_method = :text
  send_text_message(message)
else
  queue_notification(message) 
end

ここで考えられるすべてのパスをテストする場合は、12の異なる状況でテストする必要があります。

  1. ユーザーは管理者です。preferred_notification_method メールです
  2. ユーザーは管理者です。preferred_notification_method テキストです
  3. ユーザーは管理者です。preferred_notification_method どちらでもない
  4. ユーザーはユーザーです。preferred_notification_method メールです
  5. ユーザーはユーザーです。preferred_notification_method テキストです
  6. ユーザーはユーザーです。preferred_notification_method どちらでもない
  7. ユーザーは作成者です。preferred_notification_method メールです
  8. ユーザーは作成者です。preferred_notification_method テキストです
  9. ユーザーは作成者です。preferred_notification_method どちらでもない
  10. ユーザーは匿名です。preferred_notification_method メールです
  11. ユーザーは匿名です。preferred_notification_method テキストです
  12. ユーザーは匿名です。preferred_notification_method どちらでもない

「通知方法に基づいてメッセージを送信する」と「ユーザーのタイプに基づいてメッセージを生成する」は結びついているため、テストするケースは非常に多くあります。あなたはかもしれない 少ない数で絞り込めますが、それは明らかではありません。バグを求めているだけです。

しかし、それらを分解した場合はどうなりますか?

message = get_message_based_on_user_type(user.type)

send_notification(message, user.preferred_notification_method)

これで、各パーツを個別にテストできます。

最初の部分では、ユーザーのタイプごとに正しいメッセージが返されることをテストできます。

2番目の部分では、preferred_notification_methodの値に基づいて、特定のメッセージが正しく送信されることをテストできます。 。

そして最後に、親メソッドがdo_stuff_based_on_user_typeから返されたメッセージを渡すことをテストできます。 send_email_or_textに沿って 。これで、テストする8つの状態があります:

  1. ユーザーは管理者です
  2. ユーザーはユーザーです
  3. ユーザーは作成者です
  4. ユーザーは匿名です
  5. preferred_notification_method メールです
  6. preferred_notification_method テキストです
  7. preferred_notification_method どちらでもない
  8. および親メソッドの1つのテスト

ここでは、コードを分割して4つのテストを保存し、別々にテストできるようにします。 2番目の例では、より少ないテストでうまくいくことがはるかに明白です。そして、状態を追加するにつれて、コードを分割することがさらに良いアイデアになることを想像できます。

分離と読みやすさの最適なバランスを見つけるには、時間と練習が必要です。しかし、適切な場所で依存関係を破れば、はるかに少ないテストでうまくいくことができます。

フォーカス

アプリは十分にテストされている必要があります。 しかし、それはアプリのすべての部分がそのテストで同じ量の注意を払うに値するという意味ではありません。

100%のテストカバレッジを目指しても、すべてをテストすることはできません。たとえば、ビュー内のテキストのすべての行をテストしたり、更新を10秒ではなく5秒ごとにポーリングしたりすることはおそらくないでしょう。

そこで焦点が当てられます。より少なく、より有用なテストを作成します。 そして、あなたが持っている時間を最もよく過ごすことができる場所で意識的な決定をします。

焦点を合わせるのは難しいもう1つのことです。これらは私が最も重要なテストに集中するのを助けるために私が自分自身に尋ねるいくつかの質問です:

  • これは私のアプリの他の部分とどの程度相互接続されていますか?それが壊れた場合、他にいくつのピースが一緒に落ちますか?

  • これが自然に変化する可能性はどのくらいありますか?テストが失敗した場合、それはバグが原因でしょうか、それとも誰かがUIのテキストを更新したことが原因でしょうか?

  • この破壊の影響は何ですか?誰かのクレジットカードに2回請求するのでしょうか、それともテキストが欠落してしまうのでしょうか?

  • この部分はどのくらいの頻度で使用されますか?それはアプリの動作にとって重要ですか、それともフッターのどこかに埋め込まれたアバウトページですか?

だけにすべきではありません 重要な部分をテストします。ただし、感じるアプリがあります テスト時間を上手に使うと、より高品質になります。

誰かがアプリを通過する可能性のあるすべてのパスをテストしようとすると、出荷されることはありません。 TDDは役に立ちますが、すべてのテスト問題を解決できるわけではありません。

もちろん、それはあなたがまったくテストすべきではないという意味ではありません。

テストピラミッドを使用して、テストを小さく保つことができます。依存関係を分離して解除し、m * nを有効にすることができます m + nへのテストケース 。また、優先順位を付けることができるため、アプリの最も重要な部分のテストにより多くの時間を費やすことができます。

それで、あなたはいくらですか テスト?アプリを構築するときに、これらのアイデアのいずれかを検討しますか?そして、アプリのどの部分に焦点を当てるべきかをどうやって知るのでしょうか? コメントを残して、それについてすべて教えてください!


  1. MacBook Pro の価値は?

    お使いの MacBook Pro の価値は、主に使用年数、状態、販売方法によって異なります。プライベートセールは通常、小売店で下取りしたり、Apple の買い戻しプログラムを使用したりするよりも多くのお金を得ることができます。 ただし、通常は 40~65% を得ることができます MacBook Pro が新品で公正な状態であると仮定して、あなたが MacBook Pro に支払った価格の内訳です。 私は、Apple の専門家であり、2019 16 インチ MacBook Pro の所有者であるジョンです。私は多くの Mac を売買してきましたが、このガイドをまとめて、あなたの価値を見

  2. Discordでユーザーを報告する方法

    Discord は、世界中のゲーマーの間で最も人気のあるプラットフォームの 1 つに成長しました。このように大勢のファンがフォローしていると、不正なユーザーや Discord のルールや規制に違反するユーザーに出くわす可能性があります。このため、Discord にはレポート機能があります。 これにより、プラットフォームに攻撃的または不快なコンテンツを投稿するユーザーを報告できます。ユーザーを報告することは、これらのプラットフォームの神聖さを維持するために、Discord を含むすべてのソーシャル メディア プラットフォームで一般的な慣行となっています。ユーザーや投稿を報告するのは簡単なプロセス