(นี่เป็นข้อความที่ตัดตอนมาจาก Practicing Rails ลงทะเบียนที่นี่เพื่อรับบทแรกฟรี!)
คุณกำลังพัฒนาแอปใหม่ และ Rails เพิ่งสร้างการทดสอบให้คุณ:
require 'test_helper'
class BugTest < ActiveSupport::TestCase
# test "the truth" do
# assert true
# end
end
คุณไม่ใส่ความคิดเห็น คิดชื่อ และคุณพร้อมที่จะเขียนแบบทดสอบแล้วใช่ไหม แต่แล้วอะไรล่ะ? คุณเขียนอะไรก่อน รหัสทดสอบของคุณควรมีลักษณะอย่างไร
หากคุณทำตามรูปแบบง่ายๆ คุณจะเปลี่ยนบรรทัดของโค้ดที่ตัดทอนให้กลายเป็นกรณีทดสอบที่มีโครงสร้างชัดเจน
รูปแบบการทดสอบสามเฟส
กรณีทดสอบของคุณควรทำงานในสามขั้นตอน:
- ขั้นแรก คุณต้องตั้งค่าบางอย่าง ("จัดเรียง")
- จากนั้น คุณทำบางสิ่ง ("พระราชบัญญัติ")
- จากนั้น คุณต้องแน่ใจว่าสิ่งที่คุณคาดว่าจะเกิดขึ้นนั้นเกิดขึ้นจริง (“ยืนยัน”)
ตัวอย่างเช่น ลองจินตนาการว่าคุณกำลังทดสอบวิธีการในอาร์เรย์ใน Ruby ตามรูปแบบนี้ การทดสอบของคุณอาจมีลักษณะดังนี้:
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
ง่ายพอ แต่ทุกส่วนของการทดสอบมีที่ที่ต้องไป และการทดสอบแต่ละขั้นตอนแทบจะบอกคุณว่าจะเขียนอย่างไร
บางครั้ง คุณไม่จำเป็นต้องมีระยะการจัดเรียง มิฉะนั้นระยะ Act และ Assert จะถูกรวมเข้าด้วยกัน แต่การคิดถึงทั้งสามขั้นตอนขณะเขียนแบบทดสอบยังช่วยได้อยู่
ขั้นตอนการยืนยัน Gotcha
มีเคล็ดลับสำหรับระยะยืนยัน:คุณไม่ควรใช้ตรรกะเดียวกันกับระยะ Act ที่ใช้ในเฟสยืนยัน คุณควรใช้สองเส้นทางสู่คำตอบเดียวกันเสมอ มิฉะนั้น คุณจะไม่สังเกตเห็นข้อบกพร่องในโค้ดที่คุณกำลังโทร เพราะมันเพิ่งถูกเรียกอีกครั้งในเฟสยืนยัน
ตัวอย่างเช่น หากคุณกำลังทำคณิตศาสตร์:
test "average returns the average of a set of numbers" do
# arrange
numbers = [1, 2, 3, 4]
# act
average = numbers.average
# assert
# this is bad
assert_equal [1, 2, 3, 4].average, average
# this is better
assert_equal 2.5, average
end
กำลังเรียก [1, 2, 3, 4].average
อีกครั้งในเฟสยืนยันไม่ดีเพราะ average
สามารถคืนเกือบ อะไรก็ได้ และคำยืนยันนั้นก็จะผ่านไป
นี่มันค่อนข้างชัดเจน แต่ถึงแม้สิ่งต่างๆ จะซับซ้อนขึ้น อย่าลืมว่าคุณไม่ได้เรียกใช้โค้ดเดิมซ้ำสองครั้ง มิฉะนั้น คุณกำลังยืนยันว่าวิธีการของคุณคือ ถูกเรียก ไม่ใช่ว่ามันทำงานอย่างที่คุณคาดหวังไว้
โดยปกติ วิธีที่ง่ายที่สุดในการหาคำตอบที่สองคือการหาคำตอบด้วยมือและฮาร์ดโค้ด มันอาจจะเปราะบาง แต่ก็ดีกว่าการทดสอบของคุณพังโดยที่คุณไม่รู้ตัว
ทำไมต้องมี 3 เฟส
หากคุณแบ่งการทดสอบออกเป็นสามขั้นตอน คุณมีคำถามที่ง่ายกว่าที่จะตอบ แทนที่จะเน้นว่า "ฉันควรเขียนแบบทดสอบนี้อย่างไร" คุณสามารถเน้นที่แต่ละขั้นตอน:"ฉันควรตั้งค่าการทดสอบนี้อย่างไร", "ฉันกำลังทดสอบอะไร", "คำตอบควรเป็นอย่างไร"
คำถามเหล่านี้อาจยังไม่มีคำตอบที่ง่าย แต่คำตอบจะง่ายกว่าการคิดถึงการทดสอบทั้งหมดในคราวเดียว และถ้าคุณโชคดี คุณยังสามารถแชร์ขั้นตอนระหว่างการทดสอบที่เกี่ยวข้อง ซึ่งจะทำให้การทดสอบครั้งต่อไปของคุณเจ็บปวดน้อยลงมากในการเขียน