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

เขียนการทดสอบที่ดีขึ้นด้วยรูปแบบสามเฟส

(นี่เป็นข้อความที่ตัดตอนมาจาก Practicing Rails ลงทะเบียนที่นี่เพื่อรับบทแรกฟรี!)

คุณกำลังพัฒนาแอปใหม่ และ Rails เพิ่งสร้างการทดสอบให้คุณ:

test/models/bug_test.rb
require 'test_helper'

class BugTest < ActiveSupport::TestCase
  # test "the truth" do
  #   assert true
  # end
end

คุณไม่ใส่ความคิดเห็น คิดชื่อ และคุณพร้อมที่จะเขียนแบบทดสอบแล้วใช่ไหม แต่แล้วอะไรล่ะ? คุณเขียนอะไรก่อน รหัสทดสอบของคุณควรมีลักษณะอย่างไร

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

รูปแบบการทดสอบสามเฟส

กรณีทดสอบของคุณควรทำงานในสามขั้นตอน:

  1. ขั้นแรก คุณต้องตั้งค่าบางอย่าง ("จัดเรียง")
  2. จากนั้น คุณทำบางสิ่ง ("พระราชบัญญัติ")
  3. จากนั้น คุณต้องแน่ใจว่าสิ่งที่คุณคาดว่าจะเกิดขึ้นนั้นเกิดขึ้นจริง (“ยืนยัน”)

ตัวอย่างเช่น ลองจินตนาการว่าคุณกำลังทดสอบวิธีการในอาร์เรย์ใน 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 เฟส

หากคุณแบ่งการทดสอบออกเป็นสามขั้นตอน คุณมีคำถามที่ง่ายกว่าที่จะตอบ แทนที่จะเน้นว่า "ฉันควรเขียนแบบทดสอบนี้อย่างไร" คุณสามารถเน้นที่แต่ละขั้นตอน:"ฉันควรตั้งค่าการทดสอบนี้อย่างไร", "ฉันกำลังทดสอบอะไร", "คำตอบควรเป็นอย่างไร"

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