高品質のテストを書く
残念ながら、テストは依然として多くの組織で当然の注目を集めていません。開発者はテストをまったく書いていないことに罪悪感を感じているように感じることがありますが、同時にテストコードが適切にレビューされていないことがよくあります。代わりに、レビューでよくチェックされるのはテストがあるかどうかだけですが、テストがあるだけでは十分ではありませんので、これは残念です。実際には、プロジェクト内の他のすべてのコードと少なくとも同じ品質、あるいはそれ以上の品質である必要があります。そうしないと、テストがあまりにも頻繁に失敗したり、理解しにくくなったり、実行に時間がかかりすぎたりするため、実際にテストを行うのをためらう可能性があります。リポジトリ モックの代わりにメモリ内実装を使用することについては、ブログ投稿でこれらの点のいくつかをすでに説明しました。ここで、テストを作成するときに私が気をつけている他の、より一般的なことについて説明したいと思います。
ミニマリズムが鍵です
スタック オーバーフローでは、質問に最小限の再現可能な例を追加するよう求められます。私の意見では、これはまったく同じ理由でテストを作成する場合にも非常に良いアドバイスです。特に、テストを書いてから数か月後にテストを読む場合、起こっていることが少なければ、何が起こっているのかを完全に理解するのがはるかに簡単です。したがって、テストに絶対に必要なコードのみを記述してください。簡単だからという理由だけでさらにコードを追加する誘惑に抵抗してください。ただし、テスト コードはもちろん完全である必要があります。つまり、テストには必要なだけ多くの行が含まれますが、できる限り少なくする必要があります。
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 サイトの他の関連記事を参照してください。

ホットAIツール

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

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

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

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

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

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

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

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

ホットトピック











JWTは、JSONに基づくオープン標準であり、主にアイデンティティ認証と情報交換のために、当事者間で情報を安全に送信するために使用されます。 1。JWTは、ヘッダー、ペイロード、署名の3つの部分で構成されています。 2。JWTの実用的な原則には、JWTの生成、JWTの検証、ペイロードの解析という3つのステップが含まれます。 3. PHPでの認証にJWTを使用する場合、JWTを生成および検証でき、ユーザーの役割と許可情報を高度な使用に含めることができます。 4.一般的なエラーには、署名検証障害、トークンの有効期限、およびペイロードが大きくなります。デバッグスキルには、デバッグツールの使用とロギングが含まれます。 5.パフォーマンスの最適化とベストプラクティスには、適切な署名アルゴリズムの使用、有効期間を合理的に設定することが含まれます。

セッションハイジャックは、次の手順で達成できます。1。セッションIDを取得します。2。セッションIDを使用します。3。セッションをアクティブに保ちます。 PHPでのセッションハイジャックを防ぐための方法には次のものが含まれます。1。セッション_regenerate_id()関数を使用して、セッションIDを再生します。2。データベースを介してストアセッションデータを3。

PHP開発における固体原理の適用には、次のものが含まれます。1。単一責任原則(SRP):各クラスは1つの機能のみを担当します。 2。オープンおよびクローズ原理(OCP):変更は、変更ではなく拡張によって達成されます。 3。Lischの代替原則(LSP):サブクラスは、プログラムの精度に影響を与えることなく、基本クラスを置き換えることができます。 4。インターフェイス分離原理(ISP):依存関係や未使用の方法を避けるために、細粒インターフェイスを使用します。 5。依存関係の反転原理(DIP):高レベルのモジュールと低レベルのモジュールは抽象化に依存し、依存関係噴射を通じて実装されます。

phpstormでCLIモードをデバッグする方法は? PHPStormで開発するときは、PHPをコマンドラインインターフェイス(CLI)モードでデバッグする必要がある場合があります。

システムが再起動した後、UnixSocketの権限を自動的に設定する方法。システムが再起動するたびに、UnixSocketの許可を変更するために次のコマンドを実行する必要があります:sudo ...

記事では、入力検証、認証、定期的な更新など、脆弱性から保護するためのフレームワークの重要なセキュリティ機能について説明します。

静的結合(静的::) PHPで後期静的結合(LSB)を実装し、クラスを定義するのではなく、静的コンテキストで呼び出しクラスを参照できるようにします。 1)解析プロセスは実行時に実行されます。2)継承関係のコールクラスを検索します。3)パフォーマンスオーバーヘッドをもたらす可能性があります。
