কম্পিউটার টিউটোরিয়াল

রুবিতে VCR মাস্টার করুন: টেস্ট পারফরম্যান্স ও নির্ভরযোগ্যতা বাড়ান

আপনার রুবি অ্যাপ্লিকেশন যদি যেকোনো এক্সটার্নাল 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 হিট করবে এবং পাস করবে, কিন্তু এটি প্রায় আধা সেকেন্ড নেবে।

শুধু একটি টেস্টের জন্য আধা সেকেন্ড!

হয়তো খুব বেশি লাগছে না, কিন্তু কল্পনা করুন আপনার সো টেস্ট আছে, সেটা ৫০ সেকেন্ড লাগবে সবগুলো রান করার জন্য।

এখন সেটি ফিক্স করি...

চলুন 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, আপনি যদি ফলো করছেন তবে আপনি এটিকে একবার দেখতে চাইতে পারেন।

আমি যদি এখন টেস্টগুলো রান করি তবে এটি অনেক দ্রুত হবে।

বস্তুতঃ

এটি শুধু ০.০১ সেকেন্ড নেয় ফিনিশ होने!

"An HTTP request has been made that VCR does not know how to handle"

আপনি যদি এই এরর মেসেজ পান তবে এর মানে দুটি জিনিসের একটা:

১. আপনি VCR ইনেবল থাকাকালীন একটি HTTP কল করার চেষ্টা করছেন, কিন্তু VCR.use_cassette ব্লকের বাইরে।

সমাধান: ডিফল্টলি VCR + WebMock সকল HTTP রিকোয়েস্ট ব্লক করে। আপনি কনফিগারেশন অপশন দিয়ে এটিকে পরিবর্তন করতে পারেন, অনুপস্থিত VCR ব্লক যোগ করতে পারেন, বা RSpec মেটাডেটা ব্যবহার করতে পারেন (পরবর্তী সেকশন)।

২. আপনি একটি ভিন্ন রিকোয়েস্ট করার চেষ্টা করছেন এবং একটি ক্যাসেট ব্যবহার করছেন যা এই 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 রেসপন্সের জন্য অপেক্ষা ছাড়া আপনার রুবি অ্যাপের টেস্ট লিখতে পারেন!

রুবিতে VCR মাস্টার করুন: টেস্ট পারফরম্যান্স ও নির্ভরযোগ্যতা বাড়ান

আপনি যদি এটি পছন্দ করেন তবে এই আর্টিকেলটি শেয়ার করতে ভুলবেন না যাতে আরও মানুষ এর উপভোগ করতে পারে।

পড়ার জন্য ধন্যবাদ 🙂


  1. পুরনো রাউটারকে রিপিটার হিসেবে ব্যবহার ও কনফিগার করে WiFi উন্নত করুন

  2. আপনার ম্যাকএতে অ্যানিমেটেড GIF वालপেপার হিসেবে ব্যবহার করুন

  3. AASM দিয়ে রুবিতে স্টেট মেশিন মাস্টার করুন: একটি প্র্যাক্টিক্যাল গাইড

  4. স্ক্রিন রেকর্ডিং দিয়ে প্রোডাক্টিভিটি বাড়ান: একটি প্র্যাক্টিক্যাল গাইড