Go 中的測試驅動 API 開發

王林
發布: 2024-07-18 01:18:11
原創
452 人瀏覽過

Test-driven API Development in Go

介紹

測試驅動開發是確保程式碼經過良好測試和可重構的有效方法。基本想法是透過編寫測試開始開發。這些測試清楚地記錄了期望並為成功實施創建了標準。如果做得正確,您可以在編寫任何程式碼之前清楚地定義函數的預期輸入/輸出。這有一些直接的好處:

  • 您仔細考慮與程式碼互動的介面並將其設計為可測試的
  • 當您開始編寫程式碼時,您的流程不會因手動測試或單步執行執行邏輯來預測結果而中斷。相反,您只需執行測試
  • 透過測驗成為一個令人滿足的目標。將流程分解為一系列明確且可實現的里程碑,使工作變得更加愉快
  • 避免實施後的懶惰和過度自信,這可能會阻止您測試程式碼

現在您已經確信這些好處,您可以按照以下步驟開始測試驅動開發 (TDD):

  1. 編寫或修改測驗
  2. 檢查測試是否失敗
  3. 編寫最少數量的程式碼以使測試通過

這些步驟是循環執行的,因此您總是添加更多測試來挑戰當前的實現。

最後一步,指定編寫最少量的程式碼,如果嚴格遵循,事情可能會變得乏味。在確定何時適合偏離該規則之前,了解該規則存在的原因非常重要。

簡單的例子

您的任務是實作函數 Add(x, y int) int。在跳到實作並傳回 x + y 之前,先寫最簡單的測試:1 + 1 == 2。那麼,通過測試的最簡單實作是什麼?只需返回 2。現在您的測試通過了!

此時,您意識到需要更多測試,因此您加快了步伐並添加了更多測試:

  • 1 + 2 == 3
  • 100 + 5 == 105

現在你的測試失敗了,所以你需要修復實作。這次你不能只回傳 3 或返回 105,所以你需要找到一個適用於所有測試的解決方案。這導致了實現:return x + y.

雖然在這個簡單的範例中感覺過於乏味,但嚴格遵守此方法會導致您編寫多個測試而不是僅僅信任您的實作。當然,您最初返回 x + y 的想法是可行的,但重點是重新訓練自己依賴測試而不是您自己對程式碼的理解。在現實世界中,您並不是唯一一個處理這段程式碼的人,不可避免地會忘記實作細節。這個過程迫使你寫更多的測試並想出更多的方法來打破簡單的實作。

最終,您將獲得經驗並學會在遇到的不同場景中找到平衡點。您將恢復全速實現功能,並發現錯誤更少並編寫更多可維護的程式碼。

HTTP API 的逐步 TDD

讓我們進入一個使用 TDD 實作 HTTP REST API 的更複雜的範例。本逐步指南使用我的 Go 框架babyapi,但這些概念可以應用於任何地方。

babyapi 使用泛型來圍繞 Go 結構建立完整的 CRUD API,從而使創建完整的 REST API 和客戶端 CLI 變得非常容易。除此之外,babytest 套件還提供了一些用於建立端到端 API 表測試的工具。在 API 層級使用 TDD 可以一次全面測試新 API 或功能的 HTTP 和儲存層。

免責聲明:由於babyapi 處理大部分實作並且也用於產生測試樣板,因此從技術上講我們並不是從TDD 開始。然而,當我們向 API 添加對 PATCH 請求的支援時,我們將看到它有多有益。

  1. 建立一個新的 Go 專案


  2. 使用babyapi的簡單範例建立初始main.go


  3. 使用 CLI 產生測試樣板

  4. 透過使用預期的 JSON 填充佔位符來實現每個測試
  5. 運行測試並查看它們是否通過!

    由於 PUT 是冪等的,因此需要包含所有欄位。為了避免這種情況,我們希望新增對使用 PATCH 請求切換 Completed 的支援。我們首先添加一個簡單的測試來了解我們期望此功能的外觀
  6. 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

  7. 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

  8. Update Patch to set the remaining fields

  9. 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

  10. 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

  11. 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.

Conclusion

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:

  • Try it in simple scenarios where a function's input/output is clear and the implementation is not overly complicated. You can write a robust table test for the variety of input/output that could be encountered. Having a clear visual of the different scenarios can simplify implementation
  • If you're fixing a new bug, you have already identified a gap in your testing. Start by writing a test that would have identified this bug in the first place. Then, make this test pass without breaking any existing tests.
  • Similar to the babyapi example, you can use TDD for high-level API tests. Once you have a definition of the expected request/response, you can resume your usual development flow for more detail-oriented parts of the implementation

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中文網其他相關文章!

來源:dev.to
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!