RSpec-এ side effects মানে হল এমন কোন পরিবর্তন যা কোনো ফাংশন বা মেথড চালানোর পর ঘটে, যেমন কোনো ভ্যারিয়েবল, ডাটাবেস রেকর্ড, ফাইল, বা অন্য কোন বাইরের সিস্টেমে পরিবর্তন আসা। সাইড ইফেক্টস টেস্ট করা অত্যন্ত গুরুত্বপূর্ণ, বিশেষত যখন আপনার কোড বাইরের সিস্টেম বা ডেটা পERSISTেন্সের সাথে কাজ করে।
RSpec বিভিন্ন পদ্ধতিতে সাইড ইফেক্টস টেস্ট করতে সহায়ক, এবং এর মধ্যে ব্লক ব্যবহার করা অন্যতম গুরুত্বপূর্ণ উপায়। ব্লক ব্যবহার করে আপনি কোডের সাইড ইফেক্টসের পরীক্ষা করতে পারেন, যেমন ডাটাবেসে পরিবর্তন, ফাইলের সৃষ্টি, বা বাইরের সিস্টেমে কোন প্রভাব।
সাইড ইফেক্টস কী?
সাইড ইফেক্টস হল সেই সব পরিবর্তন যা কোড চালানোর ফলে ঘটে এবং যেগুলি আপনি পরীক্ষার মাধ্যমে দেখতে পারবেন। এগুলোর মধ্যে হতে পারে:
- অবজেক্টের অবস্থা পরিবর্তন।
- গ্লোবাল ভ্যারিয়েবল পরিবর্তন।
- ডাটাবেস বা ফাইলে লেখা।
- HTTP অনুরোধ পাঠানো বা নেটওয়ার্কের অবস্থায় পরিবর্তন।
উদাহরণস্বরূপ, যখন কোনো ব্যবহারকারী লগ ইন করে এবং ডাটাবেসে তার লগ ইন টাইম স্ট্যাম্প আপডেট হয়, তখন এটি একটি সাইড ইফেক্ট।
সাইড ইফেক্ট টেস্ট করার উদাহরণ
ধরা যাক, আমাদের একটি User ক্লাস আছে যা ব্যবহারকারী লগ ইন করলে last_login অ্যাট্রিবিউট আপডেট করে। আমরা পরীক্ষা করতে চাই যে login মেথডটি কল করলে last_login সঠিকভাবে আপডেট হয়।
উদাহরণ কোড:
class User
attr_accessor :name, :last_login
def initialize(name)
@name = name
@last_login = nil
end
def login
@last_login = Time.now
end
endএখন, আমরা চাই যে যখন login মেথডটি কল হবে, তখন last_login আপডেট হবে। এটির সাইড ইফেক্ট টেস্ট করতে হলে আমরা RSpec ব্যবহার করতে পারি।
১. it ব্লকে সাইড ইফেক্ট টেস্ট করা
আমরা it ব্লকের মধ্যে সাইড ইফেক্ট পরীক্ষা করতে পারি, যেমন last_login পরিবর্তন হওয়া।
describe User do
let(:user) { User.new("Alice") }
it "should update the last_login time when user logs in" do
# আগের last_login টাইম সংরক্ষণ
previous_time = user.last_login
# login মেথড কল করা
user.login
# সাইড ইফেক্ট (last_login পরিবর্তন) পরীক্ষা করা
expect(user.last_login).not_to eq(previous_time)
expect(user.last_login).to be_within(1.second).of(Time.now)
end
endব্যাখ্যা:
previous_timeএ আমরাlast_loginএর আগের মান সংরক্ষণ করেছি, যাতে পরে পরীক্ষণ করতে পারি এটি পরিবর্তিত হয়েছে কিনা।- টেস্টে আশা করা হচ্ছে যে,
loginমেথড কল করার পরlast_loginআগের মানের সমান থাকবে না এবং বর্তমান সময়ের কাছাকাছি হবে।
২. before এবং after ব্লক দিয়ে সাইড ইফেক্ট টেস্ট
before এবং after ব্লকগুলি টেস্টের আগে বা পরে কোড চালানোর জন্য ব্যবহৃত হয়। সাইড ইফেক্ট টেস্ট করার সময় যদি ডাটাবেস বা ফাইলের মতো বাইরের সিস্টেমের সাথে কাজ করতে হয়, তখন এগুলি খুবই কার্যকরী হতে পারে।
উদাহরণ:
ধরা যাক, আমাদের একটি কোড আছে যা ফাইল তৈরি করে একটি সাইড ইফেক্ট হিসেবে:
class FileCreator
def create_file(filename, content)
File.open(filename, "w") { |f| f.write(content) }
end
endএখন, আমরা পরীক্ষা করতে চাই যে সঠিকভাবে ফাইল তৈরি হচ্ছে কিনা।
describe FileCreator do
let(:filename) { "test_file.txt" }
let(:content) { "Hello, World!" }
let(:file_creator) { FileCreator.new }
# টেস্টের পরে ফাইলটি মুছে ফেলা হবে
after do
File.delete(filename) if File.exist?(filename)
end
it "creates a file with the correct content" do
# নিশ্চিত হওয়া যে ফাইলটি শুরুতে নেই
expect(File.exist?(filename)).to be_falsey
# মেথড কল করা যা সাইড ইফেক্ট তৈরি করবে
file_creator.create_file(filename, content)
# নিশ্চিত হওয়া যে ফাইলটি তৈরি হয়েছে এবং সঠিক কন্টেন্ট রয়েছে
expect(File.exist?(filename)).to be_truthy
expect(File.read(filename)).to eq(content)
end
endব্যাখ্যা:
afterব্লক নিশ্চিত করে যে টেস্ট শেষ হলে ফাইলটি মুছে ফেলা হবে, এমনকি টেস্টটি ব্যর্থ হলেও।itব্লকে আমরা প্রথমে নিশ্চিত হচ্ছি যে ফাইলটি নেই, তারপরcreate_fileমেথড কল করার পর এটি তৈরি হয়ে সঠিক কন্টেন্ট ধারণ করছে কিনা পরীক্ষা করা হচ্ছে।
৩. অ্যাসিনক্রোনাস সাইড ইফেক্ট টেস্ট
কিছু সময় সাইড ইফেক্ট অ্যাসিনক্রোনাস বা বিলম্বিত হতে পারে, যেমন ব্যাকগ্রাউন্ড জব চালানোর পর ইমেইল পাঠানো। এমন ক্ষেত্রে আপনি expect এবং ব্লক ব্যবহার করে সাইড ইফেক্টটির জন্য অপেক্ষা করতে পারেন।
উদাহরণস্বরূপ, যদি আপনার একটি ব্যাকগ্রাউন্ড জব থাকে যা ইমেইল পাঠায়:
class UserMailerJob < ApplicationJob
queue_as :default
def perform(user)
UserMailer.welcome_email(user).deliver_now
end
endঅ্যাসিনক্রোনাস সাইড ইফেক্ট টেস্ট:
describe UserMailerJob do
let(:user) { create(:user) }
it "sends a welcome email" do
# প্রথমে নিশ্চিত করি যে কোনো ইমেইল পাঠানো হয়নি
expect(ActionMailer::Base.deliveries.count).to eq(0)
# ব্যাকগ্রাউন্ড জব এঞ্জিক করা
UserMailerJob.perform_later(user)
# অপেক্ষা করে নিশ্চিত করি যে ইমেইল পাঠানো হয়েছে
expect {
perform_enqueued_jobs
}.to change { ActionMailer::Base.deliveries.count }.by(1)
end
endব্যাখ্যা:
perform_enqueued_jobsব্যাকগ্রাউন্ড জবটি সিঙ্ক্রোনাসভাবে চালিয়ে দেয়, যাতে টেস্টের সময় জব সম্পন্ন হয়।expect { ... }.to changeনিশ্চিত করে যে ইমেইল পাঠানোর পর ইমেইল সংখ্যা ১ বাড়বে।
সারাংশ
RSpec-এ সাইড ইফেক্ট টেস্ট করার জন্য ব্লক ব্যবহার করা অত্যন্ত কার্যকরী। ব্লক ব্যবহার করে আপনি ডাটাবেস পরিবর্তন, ফাইল তৈরি বা অ্যাসিনক্রোনাস অপারেশনসের সাইড ইফেক্টস পরীক্ষা করতে পারেন। it, before, after, এবং expect ব্লক সহ RSpec এর টেস্টিং ক্ষমতা সাইড ইফেক্টস সঠিকভাবে যাচাই করার জন্য খুবই উপযোগী।
Read more