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

เชี่ยวชาญการเขียน Tests ด้วย Three-Phase Pattern ใน Rails

(นี่คือ excerpt สั้นจาก Practicing Rails สมัครที่นี่รับ chapter แรกฟรี!)

ทำงานกับแอปใหม่ Rails generate test ให้:

test/models/bug_test.rb
require 'test_helper' class BugTest < ActiveSupport::TestCase # test "the truth" do # assert true # end end 

Uncomment ตั้งชื่อ พร้อมเขียน test แล้วใช่ไหม? แตต่อไปไหน? เขียนอะไรก่อน? Test code ควรเป็นยังไง?

ถ้าฟอลโลว์ pattern เรียบง่าย จะเปลี่ยน stub lines กลายเป็น test cases ชัดเจน และ well-structured

Three-Phase Test Pattern

Test cases ควรทำงาน 3 phases:

  1. Set stuff up ก่อน ("Arrange")
  2. ทำบางอย่าง ("Act")
  3. ตรวจสอบว่าสิ่งที่คาดหวัง เกิดขึ้นจริง ("Assert")

เช่น ทดสอบ method บน array ใน Ruby ตาม pattern นี้ test อาจเป็น:

test "Array#sort will sort an array of numbers" do # arrange unsorted_array = [7, 4, 2, 3] # act sorted_array = unsorted_array.sort # assert assert_equal [2, 3, 4, 7], sorted_array end 

ง่ายพอ แตทุกส่วนของ test มีที่ไป และแต่ละ stage เกือดบอกว่าเขียนยังไง

บางครั้งไม่ต้อง Arrange phase หรือ Act และ Assert รวมกัน แตยังช่วยให้คิด 3 phases ตอนเขียน tests

Assert Phase Gotcha

มี trick ที่ Assert phase: ไม่ควรใช้ logic เดียวกับ Act phase ใน Assert phase ควรหาคำตอบทางเดียวกัน 2 ทาง ไม่เช่นนั้น ไม่เจอบั๊กในโค้ดที่เรียก เพราะมันแค่ถูกเรียกซ้ำใน Assert

เช่น ทำ math:

test "average returns the average of a set of numbers" do # arrange numbers = [1, 2, 3, 4] # act average = numbers.average # assert # นี่แย่ assert_equal [1, 2, 3, 4].average, average # นี่ดีกว่า assert_equal 2.5, average end 

เรียก [1, 2, 3, 4].average ซ้ำใน Assert แย่ เพราะ average คืน อะไรก็ได้ assertion ก็ยัง pass

ตรงนี้ชัด แตแม้ซับซ้อนขึ้น ให้แน่ใจว่าไม่ได้แค่รันโค้ดเดียวกัน 2 ครั้ง ไม่งั้นแค่ verify ว่า method ถูกเรียก ไม่ใช่ว่าทำงานเหมือนคาดหวัง

ปกติ easiest way หาทางที่ 2 ไปคำตอบ คือ หาคำตอบเองมือ แล้ว hardcode อาจ brittle แตดีกว่า tests พังโดยไม่รู้

ทำไม Three Phases?

ถ้าแยก tests 3 phases จะได้คำถามง่ายขึ้น แทน "เขียน test ยังไง?" โฟกัสแต่ละ phase: "setup ยังไง?", "ทดสอบอะไร?", "คำตอบควรเป็นยังไง?"

คำถามเหล่านี้ยังอาจไม่ง่าย แตคำตอบจะง่ายกว่าคิดทั้ง test พร้อมกัน และถ้าดีใจ อาจ share phases ระหว่าง related tests ทำ test ต่อไปไม่เจ็บปวดเท่าไหร่