Computer >> 컴퓨터 >  >> 프로그램 작성 >> Ruby

VCR Gem을 사용하여 테스트 도구 모음을 개선하는 방법

Ruby 애플리케이션이 모든 종류의 외부 API를 사용하는 경우 느린 테스트 및 API 속도 제한 문제에 직면했을 것입니다. .

해결책은 무엇입니까?

클라이언트 라이브러리에서 HTTP 메서드를 수동으로 스텁하고 미리 결정된 응답을 반환할 수 있습니다.

하지만 그것은 많은 작업과 추한 코드입니다!

더 나은 솔루션은 Webmock + VCR과 같은 강력한 보석 조합을 사용하는 것입니다. .

WebMock은 다음과 같은 일반적인 HTTP 라이브러리의 HTTP 요청을 가로챕니다.

  • net/http
  • 패러데이
  • 레스트클라이언트
  • … 더 많이!

이것만으로도 유용하지만 응답 데이터를 제공해야 합니다.

여기에서 VCR이 등장합니다...

VCR은 WebMock과 함께 작동하여 코드로 작성된 HTTP 응답을 기록합니다. .

이러한 녹음을 "카세트"라고 합니다.

테스트를 실행할 때 :

VCR은 카세트 파일을 로드하고 녹음된 응답을 반환합니다. 실제 API를 요청할 필요가 없기 때문에 더 빠른 응답을 받을 수 있습니다.

몇 가지 코드 예제를 살펴보겠습니다!

VCR 코드 예

이 예에서는 다음 섹션에서 볼 수 있듯이 VCR과 더 잘 통합되기 때문에 RSpec을 사용할 것입니다.

테스트할 코드는 다음과 같습니다. :

require "faraday"
require "json"

class Github
  def self.user(name)
    url  = "https://api.github.com/users/#{name}"
    data = Faraday.get(url).body

    JSON.parse(data, symbolize_names: true)
  end
end

특정 사용자에 대한 정보를 얻기 위해 Github API에 요청합니다. 매우 간단하지만 VCR 작동 방식을 배우는 데 도움이 됩니다.

이 코드에 대한 테스트는 다음과 같습니다. :

require "rspec/autorun"

require_relative "github_api_example"

describe Github do
  let(:user_response) { Github.user("ruby") }

  it "can fetch & parse user data" do
    expect(user_response).to be_kind_of(Hash)

    expect(user_response).to have_key(:id)
    expect(user_response).to have_key(:type)
  end
end

이것은 실제 API에 도달하고 통과하지만 완료하는 데 0.5초 정도 걸립니다.

한 번의 테스트에 0.5초!

별 것 아닌 것 같지만 100개의 테스트가 있다고 상상해 보세요. 모든 테스트를 실행하는 데 50초가 소요됩니다.

문제를 해결할 시간입니다...

이 코드를 추가하여 VCR을 소개하겠습니다. :

require "vcr"

VCR.configure do |c|
  c.cassette_library_dir = "spec/vcr"
  c.hook_into :webmock
end
<블록 인용>

test_helper에 이 코드를 추가할 수 있습니다. 파일이므로 모든 테스트에서 사용할 수 있습니다.

configure으로 VCR에 카세트 파일을 저장할 위치를 알려주고 WebMock 통합을 활성화하는 것을 차단합니다.

Faraday 또는 Excon을 사용하는 경우 VCR에서 직접 연결할 수 있습니다.

:webmock만 바꾸세요. :faraday 사용 또는 :excon .

다음 :

VCR에 카세트의 이름과 이 아래에서 실행해야 하는 코드를 알려야 합니다.

방법은 다음과 같습니다. :

let(:user_response) do
  VCR.use_cassette("github/user") { Github.user("ruby") }
end

테스트를 실행할 때 VCR은 cassette_library_dir 아래에 파일을 생성합니다. , 이 경우 파일 이름은 spec/vcr/github/user.yaml입니다. , 팔로우하고 계시다면 한 번 보시는 것도 좋을 것 같습니다.

지금 테스트를 실행하면 훨씬 빨라집니다 .

사실...

완료하는 데 0.01초밖에 걸리지 않습니다!

"VCR이 처리 방법을 모르는 HTTP 요청이 생성되었습니다."

이 오류 메시지가 나타나면 다음 두 가지 중 하나를 의미합니다.

1. VCR이 활성화된 상태에서 HTTP 호출을 시도하고 있지만 VCR.use_cassette 외부에 있습니다. 차단합니다.

해결책 :기본적으로 VCR + WebMock은 모든 HTTP 요청을 차단합니다. 구성 옵션으로 이를 변경하거나 누락된 VCR 블록을 추가하거나 RSpec 메타데이터(다음 섹션)를 사용할 수 있습니다.

2. 다른 요청을 하고 이 URL과 일치하지 않는 카세트를 사용하려고 합니다. 예를 들어 테스트 /users/ruby에서 요청하는 경우 , 테스트를 /users/apple 로 변경하면 이 URL에 대해 특별히 카세트가 생성됩니다. 카세트가 다른 URL용이기 때문에 이 오류가 표시됩니다.

해결책 :다른 URL에 대해 다른 카세트를 사용하고 new_episodes를 활성화합니다. 녹화 모드(vcr: { record: :new_episodes } ) 또는 요청 URL을 업데이트한 후 이전 카세트를 삭제하십시오.

RSpec 메타데이터를 사용하는 방법

VCR.use_cassette 방법은 이 보석을 사용하는 좋은 방법입니다.

하지만...

VCR이 자동으로 카세트를 생성하도록 할 수도 있습니다.

어떻게?

VCR.configure 안에 이것을 추가하십시오. 차단:

c.configure_rspec_metadata!

이제 특정 테스트에 대해 VCR을 활성화할 수 있습니다(it 블록) 또는 테스트 그룹(describe) ).

좋아요 :

describe Github, :vcr do
  # ...
end

이렇게 하면 테스트 설명의 이름을 따서 명명된 카세트 파일이 생성됩니다. :

spec/vcr/
└── Github
    ├── can_parse_user_data.yml
    └── can_test_vcr.yml

이렇게 하면 테스트당 하나의 카세트가 생성됩니다.

두 개의 테스트가 동일한 요청을 하고 동일한 데이터를 사용하더라도. VCR에서 별도의 카세트를 만듭니다.

유용한 VCR 옵션 및 팁

카세트에 문제가 있거나 데이터의 새로운 버전이 필요한 경우 카세트 파일을 삭제할 수 있습니다 .

VCR은 새로운 API 응답을 기록하고 문제를 해결할 수 있습니다.

하지만 그렇지 않다면 어떻게 될까요?

디버그 모드를 활성화할 수 있습니다. VCR.configure에서 :

VCR.configure do |c|
  # ...
  c.debug_logger = $stderr
end

이렇게 하면 많은 출력이 생성될 수 있으므로 관심 있는 항목으로만 테스트를 제한하세요.

다음 :

API 응답의 일부로 API 키 또는 기타 민감한 데이터가 있다고 가정해 보겠습니다.

녹음에서 해당 데이터를 필터링할 수 있습니다.

방법은 다음과 같습니다. :

VCR.configure do |c|
  # ...
  c.define_cassette_placeholder("<API_KEY>", ENV["API_KEY"])
end

요약

WebMock 및 VCR gem을 사용하는 방법을 배웠으므로 외부 API 응답을 기다릴 필요 없이 Ruby 앱에 대한 테스트를 작성할 수 있습니다!

VCR Gem을 사용하여 테스트 도구 모음을 개선하는 방법

마음에 드시면 이 기사를 공유하여 더 많은 사람들이 즐길 수 있도록 하는 것을 잊지 마세요.

읽어주셔서 감사합니다 🙂