การทดสอบ: กำหนดหรือไม่กำหนด?


16

มันจะดีกว่าถ้ามี

  • ชุดทดสอบที่กำหนดได้ซึ่งส่งผลให้การทดสอบเดียวกันสำเร็จ
  • ชุดทดสอบที่ไม่สามารถกำหนดค่าได้ซึ่งอาจครอบคลุมหลายกรณี

?

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

  • คุณ hardcode แถวใดจากฐานข้อมูลการทดสอบที่ถูกเลือกเป็นอินพุต (เช่นแถวที่ 10 และแถวที่ 412)
  • คุณใช้ตัวสร้างตัวเลขสุ่มเพื่อสุ่มเลือกข้อมูลจากฐานข้อมูล (สองแถวที่เลือกโดยตัวสร้างตัวเลขสุ่ม)

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

อะไรคือเหตุผลในการเลือกสิ่งหนึ่งเหนือสิ่งอื่นใด?


5
การทดสอบนั้นล้มเหลวบางครั้ง martinfowler.com/articles/nonDeterminism.html

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


10
@DCKing: พิจารณาสิ่งที่เกิดขึ้นหากการทดสอบของคุณล้มเหลว โอเคคุณมีข้อบกพร่อง เอ่ออะไรน่ะ? เรียกใช้อีกครั้งในโหมดแก้ไขข้อบกพร่อง! มันประสบความสำเร็จที่ไหน! เช่นเดียวกับที่คุณเรียกใช้ร้อยครั้งถัดไปจากนั้นคุณเขียนปัญหาออกมาเป็นการโจมตีของรังสีคอสมิก การทดสอบที่ไม่แน่นอนนั้นฟังดูไม่ได้เลย หากคุณรู้สึกว่าจำเป็นต้องครอบคลุมพื้นดินมากขึ้นในกรณีทดสอบของคุณครอบคลุมพื้นดินมากขึ้น เริ่มต้น RNG ของคุณด้วยเมล็ดชุดและรัน "ทดสอบ" สองสามร้อยครั้งด้วยค่าสุ่มอย่างสม่ำเสมอ
Phoshi

1
(ในที่สุดก็มาถึงเครื่องที่ฉันสามารถค้นหา twitter ได้อย่างเหมาะสม - " การทดสอบนั้นล้มเหลวบางครั้ง " มาจาก #FiveWordTechHorrors บน Twitter - ต้องการให้เครดิตอย่างเหมาะสม)

คำตอบ:


30

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

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

แก้ไข: การใช้ตัวสร้างตัวเลขสุ่มเพื่อเลือกข้อมูลการทดสอบบางครั้ง IMHO อาจเป็นสัญญาณว่าขี้เกียจเกินไปเกี่ยวกับการเลือกข้อมูลการทดสอบที่ดี แทนที่จะโยน 100,000 ค่าสุ่มเลือกค่าการทดสอบและหวังว่ามันจะเพียงพอที่จะค้นพบข้อบกพร่องที่ร้ายแรงทั้งหมดโดยบังเอิญใช้สมองของคุณดีขึ้นเลือก 10 ถึง 20 "กรณี" ที่น่าสนใจ "และใช้สำหรับชุดทดสอบ สิ่งนี้จะไม่เพียงส่งผลให้การทดสอบของคุณมีคุณภาพดีขึ้น แต่ยังมีประสิทธิภาพที่สูงขึ้นของชุดการทดสอบอีกด้วย


ขอบคุณสำหรับคำตอบ. ความคิดเห็นของคุณเกี่ยวกับความคิดเห็นที่ฉันทำกับคำถามของฉันคืออะไร?
DCKing

1
@ DCKing: หากคุณคิดว่าเครื่องกำเนิดไฟฟ้าแบบสุ่มจะดีกว่าในการเลือกกรณีทดสอบที่ดีกว่าคุณ (สิ่งที่ฉันสงสัย) ให้ใช้หนึ่งครั้งเพื่อหาชุดข้อมูลทดสอบที่โปรแกรมของคุณล้มเหลวและนำชุดค่าผสมเหล่านั้นมารวมกัน ของชุดทดสอบของคุณ
Doc Brown

ขอบคุณอีกครั้ง. อัปเดตคำตอบของฉันเพื่อไม่ให้ดูเหมือนกับแอป MVC เพียงอย่างเดียว
DCKing

1
ในบริบท UI บางอย่าง (เช่นเกมที่รับอินพุตคอนโทรลเลอร์) ที่มีโปรแกรมทดสอบที่สร้างการป้อนคีย์แบบสุ่มจะมีประโยชน์สำหรับการทดสอบความเครียด พวกเขาสามารถค้นพบข้อบกพร่องที่หายากด้วยการป้อนข้อมูลโดยเจตนา
Gort the Robot

@StevenBurnap: วิธีที่ฉันเข้าใจคำถามฉันคิดว่า OP มีการทดสอบการถดถอยแบบดั้งเดิมมากกว่าในใจ แน่นอนฉันเห็นด้วยว่าการทดสอบความเครียดเป็นกรณีพิเศษซึ่งอาจขึ้นอยู่กับฮาร์ดแวร์และทำให้เกิดพฤติกรรมที่ไม่ได้กำหนดไว้แม้ว่าคุณจะไม่ใช้เครื่องกำเนิดไฟฟ้าแบบสุ่มก็ตาม นั่นคือสิ่งที่อธิบายไว้ในบทความที่เชื่อมโยงกับ MichaelT ในความคิดเห็นแรกด้านล่างคำถาม และแม้กระทั่งในการทดสอบความเครียดด้วยการป้อนข้อมูลแบบสุ่มอย่างน้อยก็สามารถพยายามทำให้พฤติกรรมกำหนดขึ้นได้โดยใช้เมล็ดแบบสุ่มที่กำหนดไว้
Doc Brown

4

ทั้งที่กำหนดขึ้นและไม่กำหนดขึ้นได้

ฉันจะแบ่งพวกเขาดังนี้

การทดสอบหน่วย

สิ่งเหล่านี้ควรมีการทดสอบที่แน่นอนแบบกำหนดซ้ำได้ด้วยข้อมูลเดียวกันทุกครั้ง การทดสอบหน่วยมาพร้อมกับส่วนของโค้ดเฉพาะที่แยกได้และควรทดสอบในลักษณะที่กำหนดขึ้นได้

การทดสอบความเครียดเชิงหน้าที่และอินพุต

สิ่งเหล่านี้สามารถใช้วิธีการที่ไม่ได้กำหนดไว้กับคำเตือนต่อไปนี้:

  • ความจริงนั้นชัดเจนและถูกเรียกออกมา
  • ค่าสุ่มที่เลือกจะถูกบันทึกและสามารถลองใหม่ได้ด้วยตนเอง

3

ทั้งสอง

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

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

  • รายการว่างเปล่า
  • รายการที่มีองค์ประกอบเดียว
  • รายการที่มีองค์ประกอบเดียวกันทั้งหมด
  • รายการที่มีองค์ประกอบที่ไม่ซ้ำกันหลายรายการ
  • รายการที่มีองค์ประกอบหลายรายการซึ่งบางรายการซ้ำกัน
  • รายการที่มีNaN, INT_MINและINT_MAX
  • รายการที่เรียงลำดับแล้วบางส่วน
  • รายการที่มี 10,000,000 องค์ประกอบ

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

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

  • ใช้การทดสอบ nondeterministic เพื่อค้นหาข้อบกพร่องในรหัสของคุณ
  • ใช้การทดสอบที่กำหนดขึ้นเพื่อตรวจสอบการแก้ไขในรหัสของคุณ

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


-1

คุณไม่ต้องการการกำหนดขึ้นจริงหรือไม่กำหนด

สิ่งที่คุณอาจต้องการคือ "เสมอเหมือนกัน" กับ "ไม่เหมือนกันเสมอ"

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

แต่เมื่อพบข้อผิดพลาดสิ่งที่คุณต้องทำคือรันการทดสอบด้วยหมายเลขบิลด์เดียวกันและทำซ้ำได้


1
หรือถ้าคุณไม่มีหมายเลขบิลด์ให้ใช้ให้วางค่าเริ่มต้นของเมล็ดในเอาต์พุตของการทดสอบการทำงานเพื่อให้คุณสามารถรันการทดสอบอีกครั้งด้วยเมล็ดเดียวกัน
RemcoGerlich
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.