検索

Writing high quality tests

残念ながら、テストは依然として多くの組織で当然の注目を集めていません。開発者はテストをまったく書いていないことに罪悪感を感じているように感じることがありますが、同時にテストコードが適切にレビューされていないことがよくあります。代わりに、レビューでよくチェックされるのはテストがあるかどうかだけですが、テストがあるだけでは十分ではありませんので、これは残念です。実際には、プロジェクト内の他のすべてのコードと少なくとも同じ品質、あるいはそれ以上の品質である必要があります。そうしないと、テストがあまりにも頻繁に失敗したり、理解しにくくなったり、実行に時間がかかりすぎたりするため、実際にテストを行うのをためらう可能性があります。リポジトリ モックの代わりにメモリ内実装を使用することについては、ブログ投稿でこれらの点のいくつかをすでに説明しました。ここで、テストを作成するときに私が気をつけている他の、より一般的なことについて説明したいと思います。

ミニマリズムが鍵です

スタック オーバーフローでは、質問に最小限の再現可能な例を追加するよう求められます。私の意見では、これはまったく同じ理由でテストを作成する場合にも非常に良いアドバイスです。特に、テストを書いてから数か月後にテストを読む場合、起こっていることが少なければ、何が起こっているのかを完全に理解するのがはるかに簡単です。したがって、テストに絶対に必要なコードのみを記述してください。簡単だからという理由だけでさらにコードを追加する誘惑に抵抗してください。ただし、テスト コードはもちろん完全である必要があります。つまり、テストには必要なだけ多くの行が含まれますが、できる限り少なくする必要があります。

100% のコード カバレッジを目指します

これは不人気な意見かもしれませんが、多くの人がこれを悪い習慣だと考えているようですが、100% のコード カバレッジを目指すのは完全に理にかなっていると思います。

チームは、より低い値で妥協することがあります。コードカバレッジは90%。しかし、それは私にとってあまり意味がありません。まず第一に、これらの数値はすべてやや恣意的なものであり、データを使用してバックアップするのは困難です。また、新しいコードを作成する場合、そのしきい値を通過するためにすべてのコードをテストする必要はありません。そして、誰かがなんとかカバレッジを上げることができたとしても、次の人はコード カバレッジを 90% 以上に保ちながらまったくテストを書かずに済んでしまう可能性があり、その結果、誤った自信が生まれてしまいます。

私がよく聞く言い訳の 1 つは、ゲッターやセッターのような単純な関数のテストを書くのは意味がないというものです。そして驚くべきことに、私もそれに完全に同意します。しかし、ここに落とし穴があります: どのテストも実際にこれらのゲッターとセッターを使用しない場合、おそらくそれらを使用する必要はありません。 したがって、100% のテスト カバレッジを達成することがいかに難しいかについて不平を言う代わりに、次のようにします。そもそも、必要のないコードは書かないほうがよいでしょう。これにより、コードの各行に伴うメンテナンスの負担も回避されます。

ただし、小さな落とし穴があります。コードが時々奇妙な動作をするため、テスト実行中に実行された場合でも、コード カバレッジ ツールが一部の行を未カバーとしてマークする可能性があります。このような状況にはあまり遭遇しませんでしたが、これを機能させる方法がない場合は、コードカバレッジから除外します。例えば。 PHPUnit では、codeCoverageIgnore アノテーションを使用してこれを行うことができます:

<?php class SomeClass
{
    /**
     * @codeCoverageIgnore
     */
    public function doSomethingNotDetectedAsCovered()
    {

    }
}

この方法では、この関数はコード カバレッジ分析に含まれません。これは、コード カバレッジ 100% に到達する可能性がまだあることを意味します。また、その値もチェックし続けます。別の方法としては、100% よりも低い値に落ち着くこともありますが、その場合、上記と同じ問題が発生します。他のコードもテストでカバーされていない可能性があり、それが見逃される可能性があります。

とはいえ、コード カバレッジが 100% であっても、コードにバグがないという保証はありません。しかし、アプリケーション コード内に発見されていない行がある場合、その行の潜在的なエラーを検出するためにテストに変更を加えているわけではありません。

良いアサーションを書く

テストが書かれる理由は、コードの特定の動作を主張したいからです。したがって、アサーションはテストの非常に重要な部分です。

もちろん、アサーションを作成するときに最も重要な考慮事項は、コードの動作を正しくテストすることです。しかし、非常に近いのは、コードが失敗したときにアサーションがどのように動作するかです。何らかの理由でアサーションが失敗した場合、問題は開発者にとって可能な限り明らかである必要があります。これが明らかな状況は、この Symfony プル リクエストで現在取り組んでいる状況です。 Symfony にはassertResponseStatusCodeSame メソッドが付属しており、機能テストで応答のステータス コードをチェックできます:

<?php declare(strict_types=1);

class LoginControllerTest extends WebTestCase
{
    public function testFormAttributes(): void
    {
        $client = static::createClient();

        $client->request('GET', '/login');
        $this->assertResponseStatusCodeSame(200);

        $this->assertSelectorCount(1, 'input[name="email"][required]');
    }
}

このテストの問題は、ステータス コードが 200 でない場合に生成される出力です。テストは通常​​開発環境で実行されるため、この URL にアクセスすると Symfony はエラー ページを返し、assertResponseStatusCodeSame メソッドはアサーションが失敗した場合の応答全体。この出力は HTML だけでなく CSS と JavaScript も返すため、非常に長くなります。また、スクロールバック バッファーが文字通り小さすぎてメッセージ全体を読むことができないためです。

これは私がこれまでに遭遇した最悪の例ですが、コード内で間違ったアサーションが使用されている場合は迷惑な場合もあります。上記のassertSelectorCount アサーションの出力を見てみましょう。指定されたセレクターが正確に 1 つの要素を生成しない場合、このアサーションは失敗し、次のメッセージが表示されます。

Failed asserting that the Crawler selector "input[name="email"][required]" was expected to be found 1 time(s) but was found 0 time(s).

発生している問題についてかなり良いアイデアが得られます。ただし、アサーションは別の方法で書くこともできます (自宅ではこれを行わないでください)。

<?php class SomeClass
{
    /**
     * @codeCoverageIgnore
     */
    public function doSomethingNotDetectedAsCovered()
    {

    }
}

これはまったく同じことを行うので、どのバリアントが使用されるかは問題ではない、と主張する人もいるかもしれません。電子メールに必須の入力フィールドが 1 つも存在しない場合、次のメッセージが表示されるため、これは真実からは程遠いはずです。

<?php declare(strict_types=1);

class LoginControllerTest extends WebTestCase
{
    public function testFormAttributes(): void
    {
        $client = static::createClient();

        $client->request('GET', '/login');
        $this->assertResponseStatusCodeSame(200);

        $this->assertSelectorCount(1, 'input[name="email"][required]');
    }
}

これはまったく役に立ちません。問題の解決に取り組む人は、まず問題が実際に何なのかを把握する必要があります。これが示しているのは、常に適切なアサーションを使用する必要があり、PHPUnit にはあらゆる種類のユースケースに適合する多くのアサーションが付属しているということです。場合によっては、カスタム アサーションを作成することが意味があることもあります。

近年人気が高まっている比較的新しい主張は、スナップショット テストです。特にフロントエンドプロジェクトに取り組み始める場合には、大いに役立つようです。以前はReactでよく使っていました。主な要点は、テストが次のようになることです:

Failed asserting that the Crawler selector "input[name="email"][required]" was expected to be found 1 time(s) but was found 0 time(s).

魔法は toMatchSnapshot メソッドで起こります。最初の実行では、ツリー変数の内容が別のファイルに書き込まれます。以降の実行では、ツリー値の新しい値と、以前に別のファイルに保存されていた値が比較されます。何かが変更された場合、テストは失敗し、スナップショットを再度更新するオプションとともに差分が表示されます。これは、テストを瞬時に修正できることを意味します。

これはとても良いことのように聞こえますが、いくつかの欠点もあります。まず、コンポーネントのレンダリングされたマークアップが変更されるたびにテストが失敗するため、スナップショットは非常に脆弱です。第二に、作成者が実際に何をテストしたかったのかが説明されていないため、テストの意図が隠されています。

しかし、私が本当に楽しかったのは、コンポーネントを変更するたびに、そのコンポーネントを使用している他のすべてのコンポーネントが思い出されることでした。これは、次回の実行ではそれらのスナップショットがすべて失敗したためです。このため、私はコンポーネントごとに少なくとも 1 つのスナップショット テストを行うことを好みました。

結論

要約すると、テストの品質を向上させるためにすぐに始められることがいくつかあると思います。

  • テスト内のコードは絶対に必要な最小限にとどめてください
  • 100% のコード カバレッジを目指し、テストできない場合はコード カバレッジ メカニズムからコードを適切に除外します
  • テストが失敗した場合に適切なエラー メッセージを取得するには、正しいアサーションを使用します

私の意見では、これらのいくつかのルールに従うだけで、すでに大きな違いが生まれ、コードベースでの作業を長期間楽しむのに役立ちます!

以上が高品質のテストを書くの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
トラフィックの高いウェブサイトのPHPパフォーマンスチューニングトラフィックの高いウェブサイトのPHPパフォーマンスチューニングMay 14, 2025 am 12:13 AM

thesecrettokeepingaphp-poweredwebsterunningsmootlyunderheavyloadinvolvesseveralkeystrategies:1)emform opcodecoduceSciptionexecutiontime、2)aatabasequerycachingwithiThing withiThistolessendavasoload、

PHPでの依存関係注射:初心者向けのコード例PHPでの依存関係注射:初心者向けのコード例May 14, 2025 am 12:08 AM

コードをより明確かつ維持しやすくするため、依存関係が関心(DI)に注意する必要があります。 1)DIは、クラスを切り離すことにより、よりモジュール化されます。2)テストとコードの柔軟性の利便性を向上させ、3)DIコンテナを使用して複雑な依存関係を管理しますが、パフォーマンスの影響と円形の依存関係に注意してください。

PHPパフォーマンス:アプリケーションを最適化することは可能ですか?PHPパフォーマンス:アプリケーションを最適化することは可能ですか?May 14, 2025 am 12:04 AM

はい、最適化されたAphPossibleandessention.1)CachingingusapCutoredatedAtabaseload.2)最適化、効率的なQueries、およびConnectionPooling.3)EnhcodeCodewithBultinctions、Avoididingglobalbariables、およびUsingopcodeching

PHPパフォーマンスの最適化:究極のガイドPHPパフォーマンスの最適化:究極のガイドMay 14, 2025 am 12:02 AM

keyStrategIestsoSificlyvoostphpappliceperformanceare:1)useopcodecachinglikeToreexecutiontime、2)最適化abaseの相互作用とプロペラインデックス、3)3)構成

PHP依存性噴射コンテナ:クイックスタートPHP依存性噴射コンテナ:クイックスタートMay 13, 2025 am 12:11 AM

aphpDependencyInjectionContaineriSATOULTAINATINAGECLASSDEPTINCIES、強化測定性、テスト可能性、および維持可能性。

PHPの依存噴射対サービスロケーターPHPの依存噴射対サービスロケーターMay 13, 2025 am 12:10 AM

SELECT DEPENTENCINGINOFCENT(DI)大規模なアプリケーションの場合、ServicElocatorは小さなプロジェクトまたはプロトタイプに適しています。 1)DIは、コンストラクターインジェクションを通じてコードのテスト可能性とモジュール性を改善します。 2)ServiceLocatorは、センター登録を通じてサービスを取得します。これは便利ですが、コードカップリングの増加につながる可能性があります。

PHPパフォーマンス最適化戦略。PHPパフォーマンス最適化戦略。May 13, 2025 am 12:06 AM

phpapplicationscanbeoptimizedforspeedandEfficiencyby:1)enabingopcacheinphp.ini、2)PreparedStatementswithpordatabasequeriesを使用して、3)LoopswithArray_filterandarray_mapfordataprocessing、4)の構成ngincasaSearverseproxy、5)

PHPメールの検証:電子メールが正しく送信されるようにしますPHPメールの検証:電子メールが正しく送信されるようにしますMay 13, 2025 am 12:06 AM

PHPemailvalidationinvolvesthreesteps:1)Formatvalidationusingregularexpressionstochecktheemailformat;2)DNSvalidationtoensurethedomainhasavalidMXrecord;3)SMTPvalidation,themostthoroughmethod,whichchecksifthemailboxexistsbyconnectingtotheSMTPserver.Impl

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SecLists

SecLists

SecLists は、セキュリティ テスターの究極の相棒です。これは、セキュリティ評価中に頻繁に使用されるさまざまな種類のリストを 1 か所にまとめたものです。 SecLists は、セキュリティ テスターが必要とする可能性のあるすべてのリストを便利に提供することで、セキュリティ テストをより効率的かつ生産的にするのに役立ちます。リストの種類には、ユーザー名、パスワード、URL、ファジング ペイロード、機密データ パターン、Web シェルなどが含まれます。テスターはこのリポジトリを新しいテスト マシンにプルするだけで、必要なあらゆる種類のリストにアクセスできるようになります。

MantisBT

MantisBT

Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強力な PHP 統合開発環境

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい