高品質のテストを書く

Dec 18, 2024 pm 12:39 PM

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 までご連絡ください。

ホット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

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

SublimeText3 中国語版

SublimeText3 中国語版

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

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

PHPとPython:2つの一般的なプログラミング言語を比較します PHPとPython:2つの一般的なプログラミング言語を比較します Apr 14, 2025 am 12:13 AM

PHPとPythonにはそれぞれ独自の利点があり、プロジェクトの要件に従って選択します。 1.PHPは、特にWebサイトの迅速な開発とメンテナンスに適しています。 2。Pythonは、データサイエンス、機械学習、人工知能に適しており、簡潔な構文を備えており、初心者に適しています。

PHPでの安全なパスワードハッシュ(例:Password_hash、password_verify)を説明します。 MD5またはSHA1を使用してみませんか? PHPでの安全なパスワードハッシュ(例:Password_hash、password_verify)を説明します。 MD5またはSHA1を使用してみませんか? Apr 17, 2025 am 12:06 AM

PHPでは、Password_hashとpassword_verify関数を使用して安全なパスワードハッシュを実装する必要があり、MD5またはSHA1を使用しないでください。 1)password_hashセキュリティを強化するために、塩値を含むハッシュを生成します。 2)password_verifyハッシュ値を比較して、パスワードを確認し、セキュリティを確保します。 3)MD5とSHA1は脆弱であり、塩の値が不足しており、最新のパスワードセキュリティには適していません。

アクション中のPHP:実際の例とアプリケーション アクション中のPHP:実際の例とアプリケーション Apr 14, 2025 am 12:19 AM

PHPは、電子商取引、コンテンツ管理システム、API開発で広く使用されています。 1)eコマース:ショッピングカート機能と支払い処理に使用。 2)コンテンツ管理システム:動的コンテンツの生成とユーザー管理に使用されます。 3)API開発:RESTFUL API開発とAPIセキュリティに使用されます。パフォーマンスの最適化とベストプラクティスを通じて、PHPアプリケーションの効率と保守性が向上します。

PHP:Web開発の重要な言語 PHP:Web開発の重要な言語 Apr 13, 2025 am 12:08 AM

PHPは、サーバー側で広く使用されているスクリプト言語で、特にWeb開発に適しています。 1.PHPは、HTMLを埋め込み、HTTP要求と応答を処理し、さまざまなデータベースをサポートできます。 2.PHPは、ダイナミックWebコンテンツ、プロセスフォームデータ、アクセスデータベースなどを生成するために使用され、強力なコミュニティサポートとオープンソースリソースを備えています。 3。PHPは解釈された言語であり、実行プロセスには語彙分析、文法分析、編集、実行が含まれます。 4.PHPは、ユーザー登録システムなどの高度なアプリケーションについてMySQLと組み合わせることができます。 5。PHPをデバッグするときは、error_reporting()やvar_dump()などの関数を使用できます。 6. PHPコードを最適化して、キャッシュメカニズムを使用し、データベースクエリを最適化し、組み込み関数を使用します。 7

PHPの永続的な関連性:それはまだ生きていますか? PHPの永続的な関連性:それはまだ生きていますか? Apr 14, 2025 am 12:12 AM

PHPは依然として動的であり、現代のプログラミングの分野で重要な位置を占めています。 1)PHPのシンプルさと強力なコミュニティサポートにより、Web開発で広く使用されています。 2)その柔軟性と安定性により、Webフォーム、データベース操作、ファイル処理の処理において顕著になります。 3)PHPは、初心者や経験豊富な開発者に適した、常に進化し、最適化しています。

スカラータイプ、リターンタイプ、ユニオンタイプ、ヌル可能なタイプなど、PHPタイプのヒントはどのように機能しますか? スカラータイプ、リターンタイプ、ユニオンタイプ、ヌル可能なタイプなど、PHPタイプのヒントはどのように機能しますか? Apr 17, 2025 am 12:25 AM

PHPタイプは、コードの品質と読みやすさを向上させるためのプロンプトがあります。 1)スカラータイプのヒント:php7.0であるため、基本データ型は、int、floatなどの関数パラメーターで指定できます。 3)ユニオンタイプのプロンプト:PHP8.0であるため、関数パラメーターまたは戻り値で複数のタイプを指定することができます。 4)Nullable Typeプロンプト:null値を含めることができ、null値を返す可能性のある機能を処理できます。

PHPおよびPython:コードの例と比較 PHPおよびPython:コードの例と比較 Apr 15, 2025 am 12:07 AM

PHPとPythonには独自の利点と短所があり、選択はプロジェクトのニーズと個人的な好みに依存します。 1.PHPは、大規模なWebアプリケーションの迅速な開発とメンテナンスに適しています。 2。Pythonは、データサイエンスと機械学習の分野を支配しています。

PHP対その他の言語:比較 PHP対その他の言語:比較 Apr 13, 2025 am 12:19 AM

PHPは、特に迅速な開発や動的なコンテンツの処理に適していますが、データサイエンスとエンタープライズレベルのアプリケーションには良くありません。 Pythonと比較して、PHPはWeb開発においてより多くの利点がありますが、データサイエンスの分野ではPythonほど良くありません。 Javaと比較して、PHPはエンタープライズレベルのアプリケーションでより悪化しますが、Web開発により柔軟性があります。 JavaScriptと比較して、PHPはバックエンド開発により簡潔ですが、フロントエンド開発のJavaScriptほど良くありません。

See all articles