テスト駆動開発は、十分にテストされ、リファクタリング可能なコードを確保するための効果的な方法です。基本的な考え方は、テストを書くことから開発を始めるということです。これらのテストは期待値を明確に文書化し、実装を成功させるためのルーブリックを作成します。適切に実行すると、コードを記述する前に関数の予想される入出力を明確に定義できます。これにはすぐにいくつかの利点があります:
メリットを理解したら、次の手順に従ってテスト駆動開発 (TDD) を開始できます。
これらの手順はサイクルで実行されるため、常にテストを追加して現在の実装に挑戦することになります。
最後のステップでは、最小限のコードを記述することが指定されていますが、厳密に従うと作業が退屈になる可能性があります。いつルールから逸脱するのが適切かを判断する前に、このルールが存在する理由を理解することが重要です。
あなたには関数 Add(x, y int) int を実装するという使命があります。実装に進んで x + y を返す前に、最も単純なテスト 1 + 1 == 2 を作成します。それでは、テストに合格する最も単純な実装は何でしょうか?リターン 2 です。これでテストは成功しました!
この時点で、さらにテストが必要であることがわかり、ペースを上げてさらにテストをいくつか追加します。
今度はテストが失敗するので、実装を修正する必要があります。今回は単に 3 を返すことも 105 を返すこともできないため、すべてのテストに有効な解決策を見つける必要があります。これにより、return x + y.
という実装が行われます。この単純な例では非常に面倒に感じますが、この方法を厳密に遵守すると、実装を信頼するだけでなく複数のテストを作成することになります。もちろん、x + y を返すという最初のアイデアは機能したでしょうが、重要なのは、コードに対する自分自身の理解ではなく、テストに依存するように自分自身を再訓練することです。現実の世界では、このコード部分に取り組んでいるのはあなただけではないため、必然的に実装の詳細を忘れてしまいます。このプロセスでは、より多くのテストを作成し、単純な実装を壊すためのより多くの方法を考える必要があります。
最終的には経験を積み、遭遇するさまざまなシナリオで機能するバランスを見つけることを学びます。機能のフルスピード実装に戻り、バグが減り、より保守しやすいコードを作成できることがわかります。
HTTP REST API に TDD を使用した、より複雑な例を見てみましょう。このステップバイステップのガイドでは、私の Go フレームワーク、babyapi を使用していますが、この概念はどこにでも適用できます。
babyapi はジェネリックスを使用して Go 構造体を中心とした完全な CRUD API を作成し、完全な REST API とクライアント CLI を非常に簡単に作成できるようにします。これに加えて、babytest パッケージは、エンドツーエンドの API テーブル テストを作成するためのいくつかのツールを提供します。 API レベルで TDD を使用すると、新しい API または機能の HTTP 層とストレージ層を一度に完全にテストできます。
免責事項: babyapi は実装の大部分を処理し、テスト定型文の生成にも使用されるため、技術的には TDD から始めているわけではありません。ただし、API に PATCH リクエストのサポートを追加すると、それがどれほど有益であるかがわかります。
新しい Go プロジェクトを作成する
babyapi の簡単な例を使用して初期の main.go を作成します
テストを実行して、テストが成功することを確認してください。
This test fails since babyapi doesn't support PATCH by default. We can fix it by implementing Patch for the TODO struct. Since we defined our feature with two tests, our simplest implementation isn't just setting Completed = true and we have to use the value from the request
Now we can change the Completed status of a TODO, but we still cannot use PATCH to modify other fields as show by this new set of tests
Update Patch to set the remaining fields
Our tests still fail since we always update the TODO with the request fields, even if they're empty. Fix this by updating the implementation to check for empty values
The new UpdateWithPatch test passes, but our previous tests fail. Since we changed Completed to be *bool, TODOs created with an empty value will show as null
Implement Render for TODO so we can treat nil as false
Implementing the PATCH feature with test-driven development resulted in a robust set of tests and a well-implemented feature. Since we started by defining the expected input and output of a PATCH request in tests, it was easy to see the issues caused by not checking for empty values in the request. Also, our pre-existing tests were able to protect from breaking changes when changing the type of Completed to *bool.
Test-driven development is an effective approach for creating fully tested and correct code. By starting with tests in mind, we can ensure that every piece of code is designed to be testable instead of letting tests be an afterthought.
If you're hesitant about adopting TDD, here are a few ideas to get started:
Even if TDD isn't a good fit for the way you write code, it's still a powerful tool to have in your belt. I encourage you to at least commit some time to trying it out and see how it affects your development process.
以上がGo でのテスト駆動 API 開発の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。