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

রুবিতে RSpec টেস্টিং মাস্টার করুন: প্র্যাক্টিক্যাল উদাহরণসহ ব্যাপক টিউটোরিয়াল

আপনি কি আপনার রুবি অ্যাপ্লিকেশনের জন্য RSpec ব্যবহার করে টেস্ট লিখতে শিখতে চান?

তাহলে আপনি সঠিক জায়গায় আছেন!

এই টিউটোরিয়ালে আমি আপনাকে দেখাব কীভাবে করবেন।

সামগ্রী

  • ১ কেন আপনার টেস্ট লিখা উচিত?
      • ১.০.১ এটি ত্রুটির বিপরীতে একটি সেফটি নেট তৈরি করে (রিফ্যাক্টরিং-এর জন্য বিশেষত উপকারী)
      • ১.০.২ এটি আপনার কোড ডকুমেন্ট করতে সাহায্য করে
      • ১.০.৩ এটি আপনাকে একটি ফিডব্যাক লুপ দেয়
      • ১.০.৪ এটি নিশ্চিত করতে সাহায্য করে যে আপনার কোড আপনার প্রত্যাশা অনুযায়ী ফলাফল দিচ্ছে
      • ১.০.৫ এটি আপনাকে একটি রুবি জব পাওয়াতে সাহায্য করে
  • ২ RSpec-এর সাথে শুরু করা
  • ৩ RSpec টেস্টিং উদাহরণ
  • ৪ RSpec Let মেথড
  • ৫ Subject মেথড কীভাবে ব্যবহার করবেন
  • ৬ সব টেস্টের আগে কোড চালানোর পদ্ধতি
  • ৭ টেস্টিং সাবগ্রুপ কীভাবে তৈরি করবেন
  • ৮ একটি টেস্ট অস্থায়ীভাবে ডিজেবল করার পদ্ধতি
  • ৯ নাম দিয়ে উদাহরণ চালানো
  • ১০ RSpec এক্সপেকটেশন এবং ম্যাচার
  • ১১ RSpec ফরম্যাটার
  • ১২ স্লো টেস্ট খুঁজে বের করার পদ্ধতি
  • ১৩ RSpec ভিডিও টিউটোরিয়াল
  • ১৪ সারসংক্ষেপ
    • ১৪.১ সম্পর্কিত

কেন আপনার টেস্ট লিখা উচিত?

কারণগুলো নিচে:

এটি ত্রুটির বিপরীতে একটি সেফটি নেট তৈরি করে (রিফ্যাক্টরিং-এর জন্য বিশেষত উপকারী)

আপনার যদি টেস্ট সিউট না থাকে তবে আপনি আপনার কোড স্পর্শ করতে চাবেন না, কিছু ভাঙা যেতে পারে এর ভয়ে… টেস্ট থাকলে আপনার আত্মবিশ্বাস বেড়ে!

এটি আপনার কোড ডকুমেন্ট করতে সাহায্য করে

আপনার টেস্টগুলো বর্ণনা করে আপনার অ্যাপ্লিকেশন কী করতে হবে।

এটি আপনাকে একটি ফিডব্যাক লুপ দেয়

আপনি যখন TDD করছেন আপনি একটি ফিডব্যাক লুপ পান যা আপনাকে বলে পরবর্তীতে কীতে ফোকাস করবেন, আপনি সহজে ভटकলে উপকারী।

এটি নিশ্চিত করতে সাহায্য করে যে আপনার কোড আপনার প্রত্যাশা অনুযায়ী ফলাফল দিচ্ছে

এটি খুব গুরুত্বপূর্ণ! আপনি যদি কিছু জটিল লজিক লিখছেন, তবে আপনি নিশ্চিত হতে চান এটি অনেক ভিন্ন ইনপুটের সাথে কাজ করছে শুধু একটি উদাহরণ দিয়ে নয়। টেস্টগুলো আপনাকে কনার কেসগুলো খুঁজে বের করতে এবং ডকুমেন্ট করতে সাহায্য করে।

এটি আপনাকে একটি রুবি জব পাওয়াতে সাহায্য করে

অধিকাংশ জব অ্যাপ্লিকেশন আপনার টেস্টিং স্কিলকে যাগবে, আপনার জব পাওয়ার চান্স বাড়িয়ে দেবে।

RSpec-এর সাথে শুরু করা

RSpec কীভাবে কাজ করে বুঝতে আসুন একটি উদাহরণ ধাপে ধাপে যেতে দিয়ে।

আমরা একটি সিম্পল অ্যাপ্লিকেশন লিখব যা ফ্যাক্টোরিয়াল নম্বর খুঁজে বের করে।

প্রথম ধাপ:

require 'rspec/autorun' 
describe Factorial do 
  # ... 
end

এটি আপনার প্রথম RSpec টেস্ট লিখার প্রাথমিক কোড। আপনাকে rspec জেম রিকোয়ার করতে হবে। তারপর একটি describe ব্লক তৈরি করতে হবে সব টেস্ট একসাথে গ্রুপ করার জন্য এবং RSpec কে বলতে হবে আপনি কোন ক্লাস টেস্ট করছেন।

পরবর্তী হলো it ব্লক:

describe Factorial do 
  it "does something" do 
    # ... 
  end 
end

এটি টেস্টের নাম, প্লাস টেস্টের সব কম্পোনেন্ট একসাথে গ্রুপ করার একটি পদ্ধতি। কম্পোনেন্টগুলো হলো:

  • সেটআপ
  • এক্সারসাইজ
  • ভারিফাই

সেটআপ হলো যেখানে আপনি প্রয়োজনীয় অবজেক্টগুলো তৈরি করেন। এটি প্রস্তুতির ফেজ। তারপর আপনি যে মেথডটি এক্সারসাইজ করতে চান সেটা কল করেন এর রিটার্ন ভ্যালু পেতে। শেষে, আপনি এক্সপেকটেশন (RSpec) বা অ্যাসারশন (Minitest) দিয়ে ফলাফল ভেরিফাই করেন।

RSpec টেস্টিং উদাহরণ

এখন যদি আমরা একটি ফ্যাক্টোরিয়াল মেথড লিখতে চাই, তবে আমাদের কিছু বৈধ ভ্যালু অনলাইন বা হ্যান্ড ক্যালকুলেশন দিয়ে খুঁজে বের করতে হবে। তারপর আমরা সেগুলো আমাদের টেস্টের সাথে ব্যবহার করব।

এভাবে:

describe Factorial do 
  it "finds the factorial of 5" do 
    calculator = Factorial.new 
    expect(calculator.factorial_of(5)).to eq(120) 
  end 
end

আপনি যখন এই কোডটি রান করবেন (সাধারণ রুবি প্রোগ্রামের মতো) তবে আপনি পাবেন:

uninitialized constant Factorial (NameError)

এটি স্বাভাবিক কারণ আমাদের এখনো Factorial ক্লাস নেই। আসুন একটি তৈরি করি:

class Factorial end

পরবর্তী এরর হবে:

undefined method 'factorial_of'

আমি factorial_of মেথড তৈরি করে এটাকে ফিক্স করি:

class Factorial 
  def factorial_of 
  end 
end

তারপর আবার কোডটি চালান:

wrong number of arguments (given 1, expected 0)

আরেকটি এরর! কিন্তু জানেন কী? এটি একটি ভালো জিনিস 🙂 এরর কিছু হতাশ होने वाली জিনিস নয়। এগুলো ফিডব্যাক। এখন: factorial_of মেথডে একটি আর্গুমেন্ট যোগ করুন:

class Factorial 
  def factorial_of(n) 
  end 
end

এখন আপনি পাবেন একটি টেস্ট ফেইলিয়ার:

expected: 120 
got: nil

এটি সঠিকভাবে সেটি পয়েন্ট যেখানে আপনি এই মুহূর্তে থাকতে চান! পরবর্তী টাস্ক হলো মেথডটি ইমপ্লিমেন্ট করা:

class Factorial 
  def factorial_of(n) 
    (1..n).inject(:*) 
  end 
end

এবং আপনি পাবেন আপনার প্রথম পাসিং টেস্ট:

. 
Finished in 0.00315 seconds (files took 0.09083 seconds to load) 
1 example, 0 failures

এটিই আমরা টেস্ট-ড্রাইভেন ডেভেলপমেন্ট (TDD) বলি। আপনি প্রথমে টেস্ট লিখেন, তারপর টেস্টগুলো আপনাকে গাইড করে আপনাকে কী করতে হবে সেটা বুঝাতে।

RSpec Let মেথড

আপনি যদি অনেক টেস্ট লিখতে চান এবং একই অবজেক্টগুলো পুনরাবৃত্তি ব্যবহার করতে চান তবে আপনি এই অবজেক্টগুলো let স্টেটমেন্ট দিয়ে ডিফাইন করতে পারেন। এটি এমন দেখয়:

describe Factorial do 
  let(:calculator) { Factorial.new } 
  it "finds the factorial of 5" do 
    expect(calculator.factorial_of(5)).to eq(120) 
  end 
end

এখন আপনি একই describe ব্লকের অধীনে সব টেস্টে calculator পুনরাবৃত্তি ব্যবহার করতে পারেন। let-এর সম্পর্কে একটি জিনিস জানা দরকার এটি "লেজি"। এর মানে কী? অবজেক্টটি প্রথমবার আপনি এটি ব্যবহার করার সময় তৈরি হবে। এটার ফরক পড়তে পারে যদি এই অবজেক্ট তৈরি করার সাইড-ইফেক্ট থাকে, যেমন ডেটাবেস এন্ট্রি তৈরি করা, বা ফাইলে লিখা। সাইড-ইফেক্ট এড়াতে ভালো, কিন্তু আপনি যদি না পারেন তবে let! মেথড ব্যবহার করুন। উদাহরণ:

let!(:user) { User.create("rspec@rubyguides.com") }

let! মেথড নন-লেজি, তাই অবজেক্টটি যেকোনো টেস্ট চালু হওয়ার আগে তৈরি হয়ে যাবে।

Subject মেথড কীভাবে ব্যবহার করবেন

let-এর আরেকটি ভার্সন হলো subject। একমাত্র পার্থক্য হলো আপনার শুধু একটি subject থাকতে পারে, এবং এটি মূল অবজেক্টের একটি ইনস্ট্যান্স হওয়া উচিত যেটি আপনি টেস্ট করছেন। RSpec ইতিমধ্যে একটি ডিফল্ট subject তৈরি করে এমনভাবে:

subject { Factorial.new }

এটিকে "ইম্প্লিসিট সাবজেক্ট" বলা হয়। আপনি এটাকে এভাবে ব্যবহার করতে পারেন:

describe Factorial do 
  it "finds the factorial of 5" do 
    expect(subject.factorial_of(5)).to eq(120) 
  end 
end

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

subject(:calculator) { Factorial.new }

এটি let ব্যবহার করার মতোই আচরণ করে, কিন্তু এটি এক-লাইন এক্সপেকটেশন সক্ষম করে:

it { should be_empty }

সব টেস্টের আগে কোড চালানোর পদ্ধতি

RSpec-এ এক্সিকিউশন হুক রয়েছে যা আপনি ব্যবহার করতে পারেন প্রতিটি টেস্টের আগে ও পরে, বা পুরো গ্রুপের জন্য কিছু চালানোর জন্য। উদাহরণস্বরূপ:

describe Shop do 
  before(:all) { Shop.prepare_database } 
  after (:all) { Shop.cleanup_database } 
end

আপনি যদি প্রতিটি উদাহরণের জন্য (RSpec-এ উদাহরণ = টেস্ট) এই কোড চালাতে চান তবে :each ব্যবহার করুন :all-এর বদলে।

টেস্টিং সাবগ্রুপ কীভাবে তৈরি করবেন

আপনি যদি আপনার অ্যাপে ভিন্ন সিনেরিও টেস্ট করেন তবে রিলেটেড টেস্টগুলো একসাথে গ্রুপ করা সহায়ক হতে পারে। আপনি RSpec-এ context ব্লক ব্যবহার করে এটি করতে পারেন। এখানে একটি উদাহরণ:

describe Course do 
  context "when user is logged in" do 
    it "displays the course lessons" do 
    end 
    it "displays the course description" do 
    end 
  end 
  context "when user it NOT logged in" do 
    it "redirects to login page" do 
    end 
    it "it shows a message" do 
    end 
  end 
end

একটি টেস্ট অস্থায়ীভাবে ডিজেবল করার পদ্ধতি

ডিবাগিং উদ্দেশ্যে একটি টেস্ট ডিজেবল করা সম্ভব। আপনাকে শুধু it-কে xit-এ পরিবর্তন করতে হবে সেই টেস্টগুলোর জন্য যা আপনি ডিজেবল করতে চান। উদাহরণ:

xit "eats lots of bacon" do 
end

খেলা শেষ হলে x সরিয়ে ফেলা ভুলবেন না!

নাম দিয়ে উদাহরণ চালানো

টেস্ট ডিজেবল করার বদলে, আপনি -e ফ্ল্যাগ দিয়ে আপনি যে টেস্টগুলো চালাতে চান সেগুলো ফিল্টার করতে পারেন। উদাহরণ:

> ruby person.rb -e bacon

এই ফিল্টারিং টেস্টের নামের ওপর ভিত্তি করে, তাই উপরের উদাহরণটি "bacon" শব্দ থাকা যেকোনো টেস্টকে ম্যাচ করবে।

RSpec এক্সপেকটেশন এবং ম্যাচার

আপনি সاید আমরা যে উদাহরণটি ব্যবহার করছি সেটি মনে আছে:

expect(calculator.factorial_of(5)).to eq(120)

কিন্তু এই eq(120) পার্টটি কী? ১২০ হলো আমরা যে ভ্যালু এক্সপেক্ট করছি… এবং eq হলো আমরা যা একটি ম্যাচার বলি। ম্যাচারগুলো হলো RSpec কীভাবে আপনার মেথডের আউটপুট আপনার এক্সপেক্টেড ভ্যালু-এর সাথে কমপেয়ার করে। eq-এর ক্ষেত্রে, RSpec == অপারেটর ব্যবহার করে (রুবি অপারেটর সম্পর্কে আরও পড়ুন)। কিন্তু অন্যান্য ম্যাচারও রয়েছে যা আপনি ব্যবহার করতে পারেন। উদাহরণস্বরূপ, be_something ম্যাচার:

expect(nil).to be_nil

যেখানে something হলো একটি প্রিডিকেট মেথড (যেমন empty?) যা টেস্ট রেজাল্টের ওপর কল হবে। অন্যান্য উপকারী ম্যাচার:

  • include (অ্যারে ও হ্যাশের জন্য)
  • start_with
  • end_with
  • match (রেগুলার এক্সপ্রেশন ম্যাচিং জন্য)
  • be_between
  • have_key / have_value (হ্যাশের জন্য)
  • be_instance_of
  • respond_to
  • have_attributes (ইনস্ট্যান্স ভেরিয়েবল টেস্ট করার জন্য)

একটি ম্যাচার যেটির বিশেষ মনোযোগ দরকার সেটি raise_error ম্যাচার। কারণ এটি ব্যবহার করতে আপনাকে আপনার এক্সপেকটেশনকে একটি ব্লকে র‍্যাপ করতে হয়। এভাবে:

expect{ :x.count }.to raise_error(NoMethodError)

change ম্যাচারও এভাবে কাজ করে:

expect{ stock.increment }.to change(stock, :value).by(100)

RSpec ফরম্যাটার

ডিফল্ট RSpec আউটপুট "প্রগ্রেস" ফরম্যাটে থাকে। এই ফরম্যাটে আপনি ডট (.) দেখবেন প্রতিটি পাসিং টেস্টকে প্রতীক করে, F ফেইলড টেস্টের জন্য (এক্সপেক্টেড ও একচুয়াল ম্যাচ করে না), বা E এরর জন্য। কিন্তু অল্টার্নেটিভ ফরম্যাটিং অপশনও রয়েছে। এখানে একটি তালিকা:

  • progress
  • documentation
  • json
  • html

আপনি -f ফ্ল্যাগ দিয়ে এনেবল করতে পারেন:

> ruby factorial.rb -f d 
Person eats lots of healthy food 
writes many articles 
Finished in 0.00154 seconds (files took 0.09898 seconds to load) 
2 examples, 0 failures

ডকুমেন্টেশন ফরম্যাট আপনার টেস্ট ডেসক্রিপশন ব্যবহার করে আউটপুট জেনারেট করে।

স্লো টেস্ট খুঁজে বের করার পদ্ধতি

RSpec-এ একটি খুব হ্যান্ডি অপশন রয়েছে আপনার টেস্টগুলো প্রোফাইল করার জন্য। শুধু --profile ফ্ল্যাগ পাস করলে আপনি দেখতে পাবেন প্রতিটি টেস্ট কতক্ষণ লাগছে এবং খুব স্লোগুলো ফিক্স করতে পারবেন। এখানে একটি উদাহরণ:

> ruby factorial.rb --profile 
Factorial finds the factorial of 5 
0.00043 seconds

RSpec ভিডিও টিউটোরিয়াল

সারসংক্ষেপ

আপনি RSpec টেস্টিং ফ্রেমওয়ার্ক ব্যবহার করে টেস্ট লিখা শিখলেন। এখন আপনার পালা আপনার নিজস্ব টেস্ট লিখা শুরু করার! পড়ার জন্য ধন্যবাদ!

  1. জাভা ৮ স্ট্রিমস সাজানো: প্র্যাকটিক্যাল কোড উদাহরণ ও টিপস

  2. Linux Watch কমান্ড 습득: সিনট্যাক্স, অপশন এবং প্রয়োগিক উদাহরণ

  3. ব্যাশ শেল ফাংশন মাস্টার করুন: ৬টি প্র্যাক্টিক্যাল উদাহরণ ও টিপস

  4. ব্যাশ স্ক্রিপ্টিং মাস্টার করুন: ৫টি রিয়েল-ওয়ার্ল্ড উদাহরণসহ প্র্যাক্টিক্যাল ইন্ট্রোডাকশন