مقدمة عن Rspec

لاحقا …

1- تنصيب Rspec على نظام التشفيل

يتم تنصيب الإطار rspec عبر التعليمة التالية:

gem install rspec

2- استخدام Rspec ضمن المشروع او الملفات المراد اختبارها

لنفرض لدينا المجلد demo الذي يحتوي ملفات برمجية تقوم بوظيفية معنية والتي نريد اختبارها عبر Rspec بنية المجلد demo هي كالتالي:

|-- demo
|   |-- lib
|   |   |-- movie.rb

محتوى movie.rb

class Movie
	attr_accessor :name,:rank

	def initialize(name,rank=0)
		@name = name
		@rank = rank
	end

	def show
		puts "The name of Movie is #{@name} with rank #{@rank}" 
	end

	def like
		@rank += 1
		puts "I like this Movie. rank: #{@rank}"
	end

	def dislike
	 	@rank -=1
	 	puts "I hite this Movie. rank: #{@rank}"
	end

end

ضمن مسار المجلد السابق demo ننفذ التعليمة التالية rspec --init لتوليد الملفات الضرورية لعمل rspec:

cd demo
rspec --init

نتيجة التعليمة السابقة ستكون كالتالي:

create   .rspec
create   spec/spec_helper.rb

1- الملف spec_helper.rb ضمن المجلد spec يوجد به إعدادات الضرورية لعمل الإطار.
2- الملف rspec. : يوجد ضمنه التعليمات التي يتم تنفيذها بشكل افتراضي او الملفات التي يتم استدعائها بشكل دوري عند التنفيذ

إنشاء ملف الاختبار

الهدف من استخدام rspec هو اختبار صحة الكود المكتوب ضمن الملف movie.rb. ويتم ذلك بإنشاء ملف له نفس اسم الملف المراد اختباره movie_spec.rb

require "spec_helper"
require "movie"

describe Movie do 
	it "should name equal Bye" do
		movie = Movie.new("Bye",2)
		expect(movie.name).to eq("Bye")
	end
end

التعليمة الأولى: هي تضمين لملف الأعدادات spec_helper.rb التعليمة الثانية: هي تضمين لملف movie.rb المراد اختباره

|-- demo
|   |-- lib
|   |   |-- movie.rb
|   |-- spec
|   |   |-- lib
|   |   |   |--movie_spec.rb
|   |   |-- spec_helper.rb
|   |-- .rspec

تنفيذ ملف الاختبار السابق يتم عبر التعليمة التالية:

rspec spec/lib/movie_spec.rb

يمكننا إضافة الخيار color -- لإظهار نتيجة الاختيار بلون مختلف والخيار format doc-- لإظهار نتيجة بشكل هرمي

الخيارات السابقة إذا أردت تنفيذها دائما عند كل عملية اختبار تضاف إلى الملف .rspec

.rspec

--color
--format doc
--require spec_helper

التوابع /method الخاصة ب Rspec

البنية الاساسية ل rspec هي (describe/it).
تستخدم الكلمتين السابقتين للتعبير عن المفاهيم البرمجية كالمحادثة
فرضا لدينا تطبيق برمجي يحتوي على مستخدمين لديهم رصيد، عند تسجيل المستخدم حساب جديد يكون رصيده صفر نعبر عن المفهوم السابق بما يلي

Describe an account when it is first opened.
It has a balance of zero

يسمى التعبير السابق ب السيناريو Scenarios ويكتب برمجيا بالصيغة التالية:

describe "Describe an account when it is first opened" do
  it "It has a balance of zero" do
    user = User.new(:name "username",balance: 0)
    expect(user.balance).to eq(0) 
  end
end

توضيح بسيط لكل method

1- describe / content:
التابعين السابقين متشابيهن من الناحية الوظيفية وويستخدمان لإنشاء مجموعة block من أمثلة الأختبار.
الاختلاف بينما يكون فقط في السياق السيناريو حيث الهدف من describe إنشاء مجموعة من الاختبارات مقابل وظيفة معينة أما الهدف من content نشاء مجموعة من الاختبارات مقابل وظيفة معينة التي لها نفس الحالة. المثال التالي سوف يوضح الفرق:

describe "launch the rocket" do
  before(:each) do
    #prepare a rocket for all of the tests
    @rocket = Rocket.new
  end
 
  context "all ready" do
    before(:each) do
      #under the state of ready
      @rocket.ready = true
    end
 
    it "launch the rocket" do
      @rocket.launch().should be_true
    end
  end
 
  context "not ready" do
    before(:each) do
      #under the state of NOT ready
      @rocket.ready = false
    end
 
    it "does not launch the rocket" do
      @rocket.launch().should be_false
    end
  end
end

وايضا يستخدم content في حالات مجوعات الأمثلة المتداخلة nested example groups

2- it / specify: ايضا التابعين لهما نفس الوظيفة وهي التعبير / التصريح عن مثال الاختبار

3- before يستخدم لتنفيذ block من التعليمات البرمجية قبل كل اختبار.
لديه خيارين:

  1. before(:all) : ينفذ block من التعليمات البرمجية مرة واحدة قبل تشغيل جميع الأمثلة.
  2. before(:each) : ينفذ block من التعليمات البرمجية مرة واحدة قبل تنفيذ كل مثال على .حدى
    مثال :
before(:all) do 
  
end

#run before block
it { ... }
it { ... }
it { ... }

before(:each) do 
  
end
# run before block
it { ... }
# run before block
it { ... }
# run before block
it { ... }
# run before blockk
it { ... }

أفضل استخدام before يكون مع content.

  • content : إنشاء مجموعة من الاختبارات مقابل وظيفة معينة التي لها نفس الحالة.
  • before : إنشاء قائمة من action للحصول على حالة معينة.

4- let: تشبه before إلا أنها تتصف بأنها كسولة lazily اي ان block البرمجي لا يتم تنفيذه إلى عندما يتم استدعائه

مثال:

let(:post) { Post.new(title: "title",published: true)}
it {  exprct (post.published).to be_true   } // تم استدعاء post

5- subject:
يستخدم لتعيين شيء معين لاختباره. يفضل استخدامه مع describe


6- **let مع subject**

~~~ruby
require 'spec_helper'

describe Card do
  subject do
    Card.new(card_type)
  end
  
  describe "#value" do  
    context "Two of Hearts" do
      let(:card_type) { "2H" }
      its(:value) { should == 2 }
    end
  
    describe "Face Cards" do  
    
      context "King of Clubs" do
        let(:card_type) { "KC" }
        its(:value) { should == 13 }
      end
  
      context "Queen of Clubs" do
        let(:card_type) { "QC" }
        its(:value) { should == 12 }
      end

      context "Jack of Hearts" do
        let(:card_type) { "JH" }
        its(:value) { should == 11 }
      end
    end
    
    context "Bad Value" do
      it "should raise StandardError" do
        expect { card = Card.new("ZZ") }.to raise_error(StandardError)
      end
    end
  end
end

الرموز الخاصة بالتوقع (expectations syntaxes)

يستخدم Rspec كل من should و expect بشكل افتراضي.

لا فرق بينما إلا بطريقة الاستخدام.

فيما يلي أمثلة على استخدام كل منها :

3.should eq(3)   <=> expect(3).to eq(3)
3.should_not eq(4) <=> expect(3).not_to eq(4)
actual.should be_true <=> expect(actual).to be_true
5.should be > 4 <=> expect(5).to be >  4
[1, 2, 3].should  include(1) <=> expect([1, 2, 3]).to  include(1)
actual.should  match(/expression/) <=> expect(actual).to match(/expression/)
...

تسمى كل منeq, be_true, include, be > 4 , match ضمن الأمثلة السابقة ب matchers يمكن الإطلاع على تفصيل أكثر عنها (وظيفتها وطريقة استخدامها) من خلال التوثيق Built in matchers.

تفعيل/تعطيل كل من should و expect

يتم عبر configure تفعيل او تعطيل كل من should و expect كما يلي:

RSpec.configure do |config|
  config.expect_with :rspec do |c|
    c.syntax = :expect             # disables `should`
    # or
    c.syntax = :should             # disables `expect`
    # or
    c.syntax = [:should, :expect]  # default, enables both `should` and `expect`
  end
end

خاتمة

الشرح السابق هو شرح مبسط على الإطار Rspec واستخدامه بشكل عام.
سوف أقوم بكتابة مقالة آخرى إن شاء الله تبين طريقة استخدام الإطار ضمن مشروع Rails بالتفصيل.

الوسوم:

التصنيفات:

آخر تعديل: