Computer >> คอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Ruby

บทช่วยสอน RSpec ขั้นสุดท้ายพร้อมตัวอย่าง

คุณต้องการเรียนรู้วิธีเขียนการทดสอบสำหรับแอปพลิเคชัน Ruby โดยใช้ RSpec หรือไม่

ถ้าอย่างนั้นคุณมาถูกที่แล้ว !

ในบทช่วยสอนนี้ ฉันจะแสดงให้คุณเห็นวิธีการทำ

สารบัญ

  • 1 ทำไมคุณควรเขียนแบบทดสอบ?
      • 1.0.1 มันสร้างเครือข่ายความปลอดภัยต่อข้อผิดพลาด (มีประโยชน์อย่างยิ่งสำหรับการปรับโครงสร้างใหม่)
      • 1.0.2 ช่วยบันทึกรหัสของคุณ
      • 1.0.3 มันให้วงจรความคิดเห็นแก่คุณ
      • 1.0.4 ช่วยให้คุณแน่ใจว่าโค้ดของคุณให้ผลลัพธ์ที่คุณคาดหวัง
      • 1.0.5 ช่วยให้คุณได้งาน Ruby
  • 2 การเริ่มต้นใช้งาน RSpec
  • 3 ตัวอย่างการทดสอบ RSpec
  • 4 RSpec Let Method
  • 5 วิธีการใช้หัวเรื่อง
  • 6 วิธีรันโค้ดก่อนการทดสอบทั้งหมดของคุณ
  • 7 วิธีสร้างกลุ่มย่อยการทดสอบ
  • 8 วิธีปิดการใช้งานการทดสอบชั่วคราว
  • 9 ตัวอย่างการเรียกใช้ตามชื่อ
  • ความคาดหวังและการจับคู่ RSpec 10 รายการ
  • 11 ตัวจัดรูปแบบ RSpec
  • 12 วิธีค้นหาการทดสอบที่ช้า
  • วิดีโอแนะนำ 13 RSpec
  • 14 สรุป
    • 14.1 ที่เกี่ยวข้อง

ทำไมคุณควรเขียนแบบทดสอบ

นี่คือเหตุผล:

สร้างเครือข่ายความปลอดภัยต่อข้อผิดพลาด (มีประโยชน์อย่างยิ่งสำหรับการปรับโครงสร้างใหม่)

หากคุณไม่มีชุดทดสอบ แสดงว่าคุณไม่ต้องการแตะต้องโค้ดของคุณเพราะกลัวว่าจะมีอะไรเสียหาย...

…การทดสอบช่วยเพิ่มความมั่นใจของคุณ!

ช่วยบันทึกรหัสของคุณ

การทดสอบของคุณอธิบายสิ่งที่แอปพลิเคชันของคุณควรทำ

มันให้วงจรความคิดเห็นแก่คุณ

เมื่อคุณทำ TDD คุณจะได้รับการวนรอบความคิดเห็น ที่บอกคุณว่าควรโฟกัสอะไรต่อไป มีประโยชน์หากคุณฟุ้งซ่านง่าย

ช่วยให้คุณแน่ใจว่าโค้ดของคุณสร้างผลลัพธ์ที่คุณคาดหวัง

อันนี้สำคัญ!

หากคุณกำลังเขียนตรรกะที่ซับซ้อน คุณต้องการให้แน่ใจว่าตรรกะนั้นใช้ได้กับอินพุตต่างๆ มากมาย และไม่ใช่แค่ตัวอย่างที่คุณคิดขึ้นเท่านั้น

การทดสอบสามารถช่วยให้คุณค้นพบเคสเข้ามุมและจัดทำเอกสารได้

มันช่วยให้คุณได้งาน Ruby

การสมัครงานส่วนใหญ่จะประทับใจในทักษะการทดสอบของคุณ และเพิ่มโอกาสในการได้งาน

เริ่มต้นใช้งาน RSpec

เพื่อให้เข้าใจว่า RSpec ทำงานอย่างไร มาดูตัวอย่างทีละขั้นตอน .

เราจะเขียนโปรแกรมง่ายๆ เพื่อหาเลขแฟกทอเรียล

ก้าวแรก :

require 'rspec/autorun'

describe Factorial do
  # ...
end

นี่คือรหัสเริ่มต้นสำหรับการเขียน RSpec first แรกของคุณ ทดสอบ

คุณต้องใช้อัญมณี 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

เมื่อคุณเรียกใช้รหัสนี้ (เช่นโปรแกรม Ruby ปกติ) คุณจะได้รับสิ่งนี้:

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 Method

หากคุณต้องการเขียนการทดสอบจำนวนมาก &ใช้วัตถุเดิมซ้ำ คุณสามารถกำหนดวัตถุเหล่านี้ด้วย 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

ตอนนี้คุณสามารถใช้ calculator . ซ้ำได้ ในการทดสอบทั้งหมดของคุณภายใต้ describe . เดียวกัน บล็อก

สิ่งหนึ่งที่คุณควรทราบเกี่ยวกับ let คือมัน “ขี้เกียจ”

ฉันหมายความว่าอย่างไร

วัตถุจะไม่ถูกสร้างขึ้นจนกว่าคุณจะใช้งานครั้งแรก .

สิ่งนี้สามารถสร้างความแตกต่างได้หากการสร้างวัตถุนี้มีผลข้างเคียง เช่น การสร้างรายการฐานข้อมูล หรือการเขียนไปยังไฟล์

ทางที่ดีควรหลีกเลี่ยงผลข้างเคียงเหล่านี้ แต่ถ้าคุณทำไม่ได้ ให้ใช้ let! วิธีการ

ตัวอย่าง :

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

let! เมธอดไม่ขี้เกียจ ดังนั้นอ็อบเจ็กต์จะถูกสร้างขึ้นก่อนทำการทดสอบใดๆ

วิธีการใช้วิธีการหัวเรื่อง

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 มี hooks การดำเนินการที่คุณสามารถใช้เพื่อเรียกใช้บางสิ่งก่อนและหลังการทดสอบทุกครั้ง หรือทั้งกลุ่มของการทดสอบ

ตัวอย่างเช่น :

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

หากคุณต้องการเรียกใช้โค้ดนี้สำหรับแต่ละตัวอย่าง (example =test ใน RSpec) คุณสามารถใช้ :each แทน :all .

วิธีสร้างกลุ่มย่อยการทดสอบ

หากคุณกำลังทดสอบสถานการณ์ต่างๆ ในแอป การจัดกลุ่มการทดสอบที่เกี่ยวข้องเข้าด้วยกันอาจเป็นประโยชน์

คุณสามารถทำได้โดยใช้บล็อกบริบท ใน RSpec.

นี่คือตัวอย่าง:

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

การกรองนี้อิงตามชื่อการทดสอบ ดังนั้นตัวอย่างด้านบนจะจับคู่การทดสอบใดๆ ที่มีคำว่า “เบคอน” อยู่ด้วย

ความคาดหวังและการจับคู่ RSpec

คุณอาจจำตัวอย่างนี้ที่เราใช้:

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

แต่นี่คืออะไร eq(120) ส่วน?

120 คือค่าที่เราคาดหวัง…

…และ eq คือสิ่งที่เราเรียกว่าผู้จับคู่

การจับคู่เป็นวิธีที่ RSpec เปรียบเทียบ ผลลัพธ์ของวิธีการของคุณ ด้วยมูลค่าที่คาดหวัง .

ในกรณีของ eq , RSpec ใช้ == โอเปอเรเตอร์ (อ่านเพิ่มเติมเกี่ยวกับโอเปอเรเตอร์ Ruby)

แต่ ยังมีคู่อื่นอีก ใช้ได้เลย

ตัวอย่างเช่น be_something จับคู่:

expect(nil).to be_nil

โดยที่ something เป็นวิธีเพรดิเคต (เช่น empty? ) ที่กำลังจะถูกเรียกใช้ผลการทดสอบ

ตัวจับคู่ที่มีประโยชน์อื่นๆ:

  • รวม (สำหรับอาร์เรย์และแฮช)
  • start_with
  • จบ_ด้วย
  • จับคู่ (สำหรับการจับคู่นิพจน์ทั่วไป)
  • อยู่_ระหว่าง
  • have_key / have_value (สำหรับแฮช)
  • be_instance_of
  • ตอบกลับ
  • have_attributes (สำหรับการทดสอบตัวแปรอินสแตนซ์)

เครื่องจับคู่ที่ต้องการ ความสนใจเป็นพิเศษ คือ raise_error จับคู่

เหตุผลก็คือการใช้สิ่งนี้คุณต้องห่อหุ้มความคาดหวังของคุณไว้ภายในบล็อก

ถูกใจสิ่งนี้ :

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

change ตัวจับคู่ทำงานในลักษณะนี้:

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

ตัวจัดรูปแบบ RSpec

เอาต์พุต RSpec เริ่มต้นอยู่ในรูปแบบ "ความคืบหน้า"

ด้วยรูปแบบนี้ คุณจะเห็นจุด (. ) แสดงถึง 1 ผ่านการทดสอบแต่ละครั้ง F สำหรับการทดสอบที่ล้มเหลว (คาดว่า &จริงไม่ตรงกัน) หรือ E สำหรับข้อผิดพลาด

แต่มีตัวเลือกการจัดรูปแบบอื่นที่คุณสามารถใช้ได้

นี่คือรายการ:

  • ความคืบหน้า
  • เอกสาร
  • 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 แล้ว

ตอนนี้ถึงตาคุณแล้วที่จะเริ่มเขียนการทดสอบของคุณเอง!