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

เกิดอะไรขึ้นกับการทดสอบของฉัน?

การเขียนโค้ดให้ความรู้สึกง่ายกว่าการเขียนการทดสอบมาก และใช้วิธีแบบบรรทัดเดียวจริงๆ จำเป็นต้องได้รับการทดสอบอยู่แล้ว? มันเป็นเรื่องสังคม! การทดสอบใดๆ ที่คุณเพิ่มเข้าไปจะใช้เวลาในการพัฒนาเพียงสองหรือสามเท่า และครั้งต่อไปที่คุณเปลี่ยนโค้ด คุณจะต้องเปลี่ยนการทดสอบด้วย ดูเหมือนว่าจะเป็นการสิ้นเปลือง โดยเฉพาะอย่างยิ่งเมื่อคุณมีเวลาเหลือเพียงเล็กน้อยในการประมาณการ

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

คุณมาที่นี่ได้อย่างไร? คุณต้องการให้การทดสอบของคุณมีเครือข่ายความปลอดภัยและช่วยให้คุณสร้างโครงสร้างใหม่ได้อย่างมั่นใจ พวกเขาน่าจะช่วยทำให้โค้ดของคุณดีขึ้น! แต่คุณกลับมาครอบคลุมการทดสอบในระดับต่ำในโค้ดที่คุณไม่เข้าใจอีกต่อไป และการทดสอบที่คุณได้ทำลงไปนั้นยากขึ้น เพื่อเปลี่ยนรหัส

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

คุณไม่จำเป็นต้องตัดสินใจ

หากคุณกำลังนั่งอยู่ที่แป้นพิมพ์พยายามตัดสินใจ ไม่ว่าจะต้องทดสอบโค้ดเล็กน้อย แสดงว่าคุณกำลังเดินผิดเส้นทางแล้ว คุณควรตั้งค่าเริ่มต้นเป็น "ทดสอบ!" เสมอ แม้ว่าจะดูเหมือนการทดสอบที่มีโทนสีอ่อนเกินไป ให้เขียนแบบทดสอบ

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

แต่คุณไม่ต้องการที่จะทดสอบมากเกินไป

ชุดทดสอบขนาดยักษ์อาจเป็นปัญหาได้ การทดสอบที่ใช้เวลา 20 นาทีในการดำเนินการนั้นดีพอๆ กับไม่มีการทดสอบเลย เนื่องจากคุณจะไม่ทำการทดสอบตลอดเวลา (คุณบอกว่าคุณจะทำ แต่ฉันรู้ว่าคุณจะไม่ทำ) ที่แย่กว่านั้น หากคุณมีการทดสอบการเปราะมากเกินไป การปรับโครงสร้างใหม่จะเจ็บปวดมากกว่าที่เคยเป็นมา ดังนั้นคุณจะไม่ทำ คุณจะลงเอยด้วยวิธีการที่ยาวกว่านวนิยายส่วนใหญ่

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

class Cart
  def initialize(item_params)
    @line_items = Array(item_params).map {|item| LineItem.new(item[:name], item[:price])}
  end

  def total
    @line_items.sum(&:price)
  end
end

รู้สึกว่าโค้ดที่นี่ต้องทดสอบทั้ง Cart class และ LineItem ระดับ. แต่เป็น LineItem คลาสที่ใช้โดยอะไรอย่างอื่น? หากเป็นเพียงรายละเอียดการใช้งานของ Cart และไม่ได้เผยแพร่สู่โลกภายนอก ต้องมีการทดสอบกี่แบบจริงๆ ก็แค่ทดสอบผ่าน Cartของคุณ คลาส?

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

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

ตัดจำหน่ายต้นทุนการทดสอบของคุณด้วยการพัฒนาจากการทดสอบ

ในส่วนแรก คุณได้เรียนรู้ว่าคุณควรทดสอบทุกอย่าง ในส่วนที่สอง คุณได้เรียนรู้ว่าคุณควรทดสอบอินเทอร์เฟซสาธารณะเท่านั้น เป็นการพัฒนาที่ขับเคลื่อนด้วยการทดสอบซึ่งนำเป้าหมายที่ตรงกันข้ามทั้งสองนี้มารวมกัน

ด้วย Test-Driven Development การทดสอบของคุณจะขับเคลื่อนการออกแบบและการใช้งานโค้ดของคุณโดยทำตามขั้นตอนนี้:

  1. เขียนการทดสอบที่ล้มเหลวโดยถือว่าโค้ดที่คุณต้องการมีอยู่แล้ว
  2. เขียนการใช้งานโค้ดที่ง่ายที่สุดที่ผ่านการทดสอบ
  3. รีแฟคเตอร์เพื่อลบการซ้ำซ้อน (หรือทำให้โค้ดมีความหมายมากขึ้น)
  4. ทำการทดสอบอีกครั้ง (เพื่อให้แน่ใจว่าการทดสอบยังคงผ่าน)
  5. กลับไปที่ขั้นตอนที่ 1

เมื่อทำตามขั้นตอนเหล่านี้ คุณจะทดสอบทุกอย่าง (เนื่องจากไม่ควรเขียนโค้ดใดๆ หากไม่มีการทดสอบที่ล้มเหลว) ในขณะที่ทดสอบเฉพาะอินเทอร์เฟซสาธารณะเท่านั้น (เนื่องจากคุณไม่ได้เขียนการทดสอบใหม่ทันทีหลังจากการรีแฟคเตอร์)

มันไม่ง่ายอย่างนั้นเลย แต่ยังมีวิธีทดลองขับแม้กระทั่งโค้ดที่ซับซ้อนที่สุด

TDD มีข้อดีบางประการ:

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

แล้วฉันจะเริ่มต้นได้อย่างไร

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

ครั้งต่อไปที่คุณใช้งานคุณลักษณะใหม่ ให้ลองทำตามขั้นตอน TDD ด้านบน คุณจะพบว่าตัวเองมีความครอบคลุมของโค้ดเกือบ 100% โดยมีจำนวนงานน้อยที่สุดเท่าที่จะเป็นไปได้ คุณจะมีพื้นฐานที่มั่นคงในการสร้าง และคุณจะมั่นใจได้อย่างเต็มที่ว่าชุดทดสอบของคุณจะปกป้องคุณเมื่อคุณต้องเปลี่ยนรหัสในครั้งถัดไป ปี. หรือวันนี้เมื่อความต้องการของคุณเปลี่ยนไปอีกครั้ง

เมื่อเสร็จแล้ว โปรดส่งอีเมลและแจ้งให้เราทราบว่าเป็นอย่างไร

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