Go에서 테스트 기반 API 개발

王林
풀어 주다: 2024-07-18 01:18:11
원래의
497명이 탐색했습니다.

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를 반환할 수 없으므로 모든 테스트에 작동하는 솔루션을 찾아야 합니다. 이는 x + y를 반환하는 구현으로 이어집니다.

사소한 예에서는 이것이 지나치게 지루하게 느껴지지만 이 방법을 엄격하게 준수하면 구현을 신뢰하는 대신 여러 테스트를 작성하게 됩니다. 물론, x + y를 반환하려는 초기 아이디어는 효과가 있었을 것입니다. 그러나 요점은 코드에 대한 자신의 이해보다는 테스트에 의존하도록 스스로를 재교육하는 것입니다. 현실 세계에서는 이 코드를 작업하는 사람이 여러분뿐만이 아니며 필연적으로 구현 세부 사항을 잊어버리게 됩니다. 이 프로세스를 통해 더 많은 테스트를 작성하고 단순한 구현을 깨는 더 많은 방법을 생각하게 됩니다.

결국 경험을 쌓고 직면하는 다양한 시나리오에서 작동하는 균형을 찾는 방법을 배우게 됩니다. 기능의 최고 속도 구현으로 돌아가서 버그가 적고 유지 관리 가능한 코드가 더 많이 작성된다는 사실을 알게 될 것입니다.

HTTP API에 대한 단계별 TDD

HTTP REST API에 TDD를 사용하는 좀 더 복잡한 예를 살펴보겠습니다. 이 단계별 가이드에서는 내 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은 멱등적이므로 모든 필드가 포함되어야 합니다. 이를 방지하기 위해 Completed with PATCH 요청 전환에 대한 지원을 추가하려고 합니다. 먼저 이 기능이 어떤 모습일지 간단한 테스트를 추가해 보겠습니다.
  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 학습자의 빠른 성장을 도와주세요!