यदि आपका रूबी एप्लिकेशन किसी भी प्रकार के एक्सटर्नल API का उपयोग करता है तो आपने शायद धीमे टेस्ट्स और API रेट लिमिट्स की समस्या का सामना किया होगा।
समाधान क्या है?
आप अपने क्लाइंट लाइब्रेरी से HTTP मेथड्स को मैन्युअली स्टब कर सकते हैं, और कुछ पूर्व-निर्धारित प्रतिक्रियाएं वापस कर सकते हैं।
लेकिन यह बहुत काम और भद्दा कोड है!
एक बेहतर समाधान है Webmock + VCR जैसे शक्तिशाली जेम्स के संयोजन का उपयोग करना।
WebMock सामान्य HTTP लाइब्रेरीज से HTTP रिक्वेस्ट्स को इंटरसेप्ट करता है, जैसे:
- net/http
- Faraday
- RestClient
- ...और बहुत कुछ!
यह अकेला उपयोगी है, लेकिन आपको अभी भी प्रतिक्रिया डेटा प्रदान करना होगा।
यहाँ वह जगह है जहां VCR आता है...
VCR WebMock के साथ संयोजन में काम करता है ताकि आपके कोड द्वारा की गई HTTP प्रतिक्रियाओं को रिकॉर्ड किया जा सके।
इन रिकॉर्डिंग्स को "कैसेट्स" कहा जाता है।
जब आप अपने टेस्ट्स चलाते हैं:
VCR कैसेट फाइलें लोड करेगा और रिकॉर्ड की गई प्रतिक्रियाएं वापस करेगा। आपको तेज़ प्रतिक्रियाएं मिलेंगी क्योंकि आपको असली API से पूछने की आवश्यकता नहीं है।
आइए कुछ कोड उदाहरण देखते हैं!
VCR कोड उदाहरण
इस उदाहरण के लिए हम RSpec का उपयोग करने जा रहे हैं क्योंकि यह VCR के साथ बेहतर इंटीग्रेट होता है जैसा कि आप अगले भाग में देखेंगे।
यहाँ वह कोड है जिसे हम टेस्ट करना चाहते हैं:
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 को हिट करेगा और पास होगा, लेकिन खत्म होने में लगभग आधा सेकंड लगता है।
एक टेस्ट के लिए आधा सेकंड!
बहुत अधिक नहीं लग सकता, लेकिन कल्पना करें कि आपके पास सौ टेस्ट हैं, उन सभी को चलाने में 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 सेकंड लगते हैं!
"एक HTTP रिक्वेस्ट की गई है जिसे VCR संभालना नहीं जानता"
यदि आप इस एरर मैसेज में भाग लेते हैं तो इसका मतलब दो चीजों में से एक है:
1.आप VCR सक्षम होने के साथ HTTP कॉल करने की कोशिश कर रहे हैं, लेकिन VCR.use_cassette ब्लॉक के बाहर।
समाधान: डिफ़ॉल्ट रूप से VCR + WebMock सभी HTTP रिक्वेस्ट्स को ब्लॉक करते हैं। आप कॉन्फिगरेशन विकल्पों के साथ इसे बदल सकते हैं, लापता VCR ब्लॉक जोड़ सकते हैं, या RSpec मेटाडेटा का उपयोग कर सकते हैं (अगला भाग)।
2.आप एक अलग रिक्वेस्ट बनाने की कोशिश कर रहे हैं और एक कैसेट का उपयोग कर रहे हैं जो इस URL से मेल नहीं खाता। उदाहरण के लिए, यदि आप अपने टेस्ट्स में /users/ruby रिक्वेस्ट करते हैं, तो कैसेट विशेष रूप से इस URL के लिए बनाया जाता है, यदि आप टेस्ट को /users/apple में बदलते हैं तो आपको यह एरर दिखाई देगा क्योंकि कैसेट एक अलग URL के लिए है।
समाधान: अलग-अलग URL के लिए अलग-अलग कैसेट्स का उपयोग करें, new_episodes रिकॉर्डिंग मोड सक्षम करें (vcr: { record: :new_episodes }) या रिक्वेस्ट URL अपडेट करने के बाद पुराने कैसेट को डिलीट करें।
RSpec मेटाडेटा का उपयोग कैसे करें
VCR.use_cassette मेथड इस जेम का उपयोग करने का एक अच्छा तरीका है।
लेकिन...
आप VCR को आपके लिए कैसेट्स स्वचालित रूप से बनाने दे सकते हैं।
कैसे?
VCR.configure ब्लॉक के अंदर यह जोड़ें:
c.configure_rspec_metadata!
अब आप किसी विशेष टेस्ट (it ब्लॉक), या टेस्ट ग्रुप (describe) के लिए VCR सक्षम कर सकते हैं।
इस तरह:
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("", ENV["API_KEY"])
end
सारांश
आपने WebMock और VCR जेम्स का उपयोग करना सीखा ताकि आप एक्सटर्नल API प्रतिक्रियाओं की प्रतीक्षा किए बिना अपने रूबी ऐप्स के लिए टेस्ट लिख सकें!

यदि आपको यह पसंद आया तो इस लेख को शेयर करना न भूलें ताकि अधिक लोग इसका आनंद ले सकें।
पढ़ने के लिए धन्यवाद 🙂