เหตุใดการทดสอบหน่วยล้มเหลวจึงมองว่าไม่ดี


93

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

โดยส่วนตัวฉันคิดว่านี่ไม่ใช่เหตุผลที่ควรจะเป็นด้วยเหตุผลดังต่อไปนี้:

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

  2. เป็นเรื่องไม่สำคัญที่จะคิดการทดสอบหน่วยที่จะล้มเหลว หรือเกิดขึ้นแน่นอนกับการทดสอบหน่วยที่จะยุ่งยากในการแก้ไข

  3. หาก ณ เวลาใดเวลาทุกหน่วยทดสอบผ่านแล้วไม่มีภาพใหญ่ของรัฐของซอฟต์แวร์ ณ เวลาใด ๆ ไม่มีแผนงาน / เป้าหมาย

  4. มันขัดขวางการเขียนหน่วยทดสอบล่วงหน้า - ก่อนดำเนินการ

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

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


ความคิดเห็นไม่ได้มีไว้สำหรับการอภิปรายเพิ่มเติม การสนทนานี้ได้รับการย้ายไปแชท
maple_shaft

คำตอบ:


270

คำถามนี้มีความเข้าใจที่คลาดเคลื่อนหลายประการของ IMHO แต่คำถามหลักที่ฉันอยากจะให้ความสำคัญคือมันไม่ได้แยกความแตกต่างระหว่างสาขาการพัฒนาท้องถิ่นลำตัวการจัดเตรียมหรือการแยกสาขา

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

ในการจัดเตรียมหรือรีลีสสาขาการทดสอบที่ล้มเหลวคือ "การแจ้งเตือนสีแดง" ซึ่งแสดงว่ามีบางสิ่งผิดปกติอย่างสิ้นเชิงกับเซ็ตการแก้ไขบางอย่าง

ฉันยังแนะนำว่าแม้การปล่อยซอฟต์แวร์ที่มีการทดสอบหน่วยที่ล้มเหลวก็ไม่จำเป็นว่าจะไม่ดี

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

หากคุณมีการทดสอบสำหรับข้อบกพร่องที่ยอมรับและรู้จักกันดีให้ใช้คุณลักษณะปิด / เพิกเฉยของเครื่องมือทดสอบหน่วยของคุณ นอกจากนี้เพิ่มตั๋วที่มีลำดับความสำคัญต่ำลงในตัวแก้ไขปัญหาของคุณดังนั้นปัญหาจะไม่ถูกลืม


18
ฉันคิดว่านี่เป็นคำตอบที่แท้จริง OP กล่าวถึง "ขั้นตอนการเปิดตัว" และ "บางหน้าจอ [แสดงผลการทดสอบ]" ซึ่งฟังดูเหมือนเซิร์ฟเวอร์การสร้าง การเปิดตัวไม่เหมือนกับการพัฒนา (ไม่พัฒนาในการผลิต!); มันดีที่จะมีการทดสอบที่ล้มเหลวใน dev พวกเขาเป็นเหมือนสิ่งที่ต้องทำ ทั้งหมดควรเป็นสีเขียว (DONE) เมื่อผลักไปที่เซิร์ฟเวอร์การสร้าง
Warbo

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

5
@SebastiaanvandenBroek: ขอบคุณสำหรับการตอบกลับที่ดี เพียงเพื่อให้ชัดเจน: IMHO ล้มเหลวในการทดสอบหน่วยควรจะหายากแม้ในลำเนื่องจากการล้มเหลวดังกล่าวบ่อยเกินไปจะรบกวนทั้งทีมไม่ใช่แค่คนที่ทำการเปลี่ยนแปลงซึ่งทำให้เกิดความล้มเหลว
Doc Brown

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

1
+1 แม้ว่าฉันขอแนะนำให้เพิ่มเล็กน้อย (เป็นตัวหนา) ในประโยคนี้: "สิ่งนี้ยุ่งยากและมีข้อผิดพลาดได้ง่ายทำให้ผู้คนไม่สนใจความล้มเหลวในชุดทดสอบเป็นเสียงรบกวนและทิ้งส่วนใหญ่ของการทดสอบหน่วยอัตโนมัติ .
mtraceur

228

... การทดสอบหน่วยทั้งหมดที่ผ่านเป็นสีเขียว - ซึ่งน่าจะดี

มันเป็นสิ่งที่ดี ไม่ "ควรจะ" เกี่ยวกับเรื่องนี้

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

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

เป็นเรื่องไม่สำคัญที่จะคิดการทดสอบหน่วยที่จะล้มเหลว

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

วิธีเปรียบเทียบความคิดของนักพัฒนาและผู้ทดสอบ:

  • นักพัฒนาหยุดทันทีที่รหัสทำในสิ่งที่พวกเขาต้องการ
  • ผู้ทดสอบหยุดทำงานเมื่อพวกเขาไม่สามารถทำให้รหัสหยุดพักได้อีกต่อไป

สิ่งเหล่านี้เป็นมุมมองที่แตกต่างอย่างสิ้นเชิงและเป็นเรื่องยากสำหรับนักพัฒนาหลายคนที่จะตกลง

หรือเกิดขึ้นแน่นอนกับการทดสอบหน่วยที่จะยุ่งยากในการแก้ไข

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

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

หาก ณ เวลาใดเวลาทุกหน่วยทดสอบผ่านแล้วไม่มีภาพใหญ่ของรัฐของซอฟต์แวร์ ณ เวลาใด ๆ ไม่มีแผนงาน / เป้าหมาย

การทดสอบ "รูปภาพ" เพียงอย่างเดียวให้คุณเป็นภาพรวมที่รหัส "ใช้งานได้" ณ เวลาที่มีการทดสอบ มันวิวัฒนาการมาอย่างไรหลังจากนั้นเป็นเรื่องราวที่แตกต่าง

มันขัดขวางการเขียนหน่วยทดสอบล่วงหน้า - ก่อนดำเนินการ

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

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

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

นี่ไม่ใช่การใช้ชีวิตในโลกแห่งความฝันใช่ไหม

ถ้ามีอะไรที่มันอาศัยอยู่ในโลกแห่งความจริงยอมรับว่านักพัฒนาจะไม่รอบรู้มิได้ infallable ที่เราทำทำผิดพลาดและที่เราต้องมีความปลอดภัยสุทธิที่จะจับเราถ้าและเมื่อเราทำเลอะ!
เข้าสู่การทดสอบ

และมันไม่ขัดขวางความเข้าใจที่แท้จริงของรหัสจริงเหรอ?

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


7
@Tibos: การปิดใช้งานการทดสอบเป็นเหมือนการแสดงความคิดเห็นฟังก์ชั่น คุณมีการควบคุมเวอร์ชัน ใช้มัน.
เควิน

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

4
@dcorking: ฉันหมายถึงอย่าคอมเม้นท์โค้ดให้ลบมันทิ้ง หากคุณตัดสินใจในภายหลังว่าคุณต้องการมันแล้วให้เรียกคืนจากการควบคุมเวอร์ชัน การยืนยันการทดสอบที่ปิดใช้งานไม่แตกต่างกัน
Kevin

4
"เป็นไปได้อย่างยิ่งที่การทดสอบของคุณจะไม่ครอบคลุมทุกกรณี" ฉันจะไปไกลที่จะบอกว่าสำหรับทุกชิ้นส่วนที่ไม่ใช่เรื่องเล็ก ๆ น้อย ๆ ของการทดสอบรหัสแน่นอนคุณไม่ได้ครอบคลุมทุกกรณี
corsiKa

6
@Tibos ผู้เสนอของการทดสอบหน่วยบอกว่าเวลารอบจากการเขียนการทดสอบที่ล้มเหลวในการเขียนรหัสสำหรับมันควรจะมีขนาดเล็ก (เช่น 20 นาทีบางคนเรียกร้อง 30 วินาที) หากคุณไม่มีเวลาเขียนโค้ดในทันทีมันอาจซับซ้อนเกินไป ถ้ามันไม่ซับซ้อนให้ลบการทดสอบเนื่องจากสามารถเขียนใหม่ได้หากคุณสมบัติที่ถูกทิ้งนั้นได้รับการเพิ่มอีกครั้ง ทำไมไม่แสดงความคิดเห็นออกมา? คุณไม่ทราบว่าจะมีการเพิ่มคุณสมบัตินี้อีกครั้งดังนั้นการทดสอบความคิดเห็น (หรือรหัส) จึงเป็นเพียงแค่เสียงรบกวน
CJ Dennis

32

เหตุใดการทดสอบหน่วยล้มเหลวจึงมองว่าไม่ดี

ไม่ใช่ - การพัฒนาที่ขับเคลื่อนด้วยการทดสอบนั้นสร้างขึ้นจากแนวคิดของการทดสอบที่ล้มเหลว ความล้มเหลวในการทดสอบหน่วยเพื่อการพัฒนาไดรฟ์ล้มเหลวในการทดสอบการยอมรับเพื่อผลักดันเรื่องราว ...

สิ่งที่คุณกำลังขาดหายไปคือบริบท ; การทดสอบหน่วยอนุญาตให้ล้มเหลวได้ที่ไหน

คำตอบปกติคือการทดสอบหน่วยได้รับอนุญาตให้ล้มเหลวในแซนด์บ็อกซ์ส่วนตัวเท่านั้น

แนวคิดพื้นฐานคือ: ในสภาพแวดล้อมที่มีการทดสอบความล้มเหลวร่วมกันจะต้องใช้ความพยายามเป็นพิเศษในการทำความเข้าใจว่าการเปลี่ยนแปลงรหัสการผลิตได้นำข้อผิดพลาดใหม่มาใช้หรือไม่ ความแตกต่างระหว่างศูนย์และไม่ใช่ศูนย์นั้นง่ายต่อการตรวจจับและจัดการมากกว่าความแตกต่างระหว่าง N และไม่ใช่ N

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

ในทำนองเดียวกันในระหว่างการขึ้นนักพัฒนาใหม่สามารถทำงานได้เร็วขึ้นเนื่องจากพวกเขาไม่จำเป็นต้องใช้เวลาในการค้นหาว่าการทดสอบที่ล้มเหลวนั้นเป็น "ยอมรับ"

จะมีความแม่นยำมากขึ้น: วินัยคือการทดสอบที่ทำงานในระหว่างการสร้างจะต้องผ่าน

นอกจากนี้เป็นที่ดีที่สุดที่ฉันสามารถบอกอะไรผิดกับการมีการทดสอบความล้มเหลวที่มีความพิการ

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

เทคนิคเดียวกันเหล่านั้นสามารถใช้เพื่อปิดการทดสอบความล้มเหลวได้เช่นกัน

หนึ่งในแบบฝึกหัดที่ฉันได้ทำในการปล่อยจุดคือการจัดการกับการพัฒนาผลิตภัณฑ์ที่มีการทดสอบที่ล้มเหลวมากมาย คำตอบที่เราเกิดขึ้นนั้นก็คือการผ่านชุดการปิดการทดสอบที่ล้มเหลวและจัดทำเอกสารแต่ละชุด นั่นช่วยให้เราไปถึงจุดที่การทดสอบที่เปิดใช้งานทั้งหมดผ่านไปได้อย่างรวดเร็วและการจัดการ / ผู้บริจาคเป้าหมาย / เจ้าของทองจะได้เห็นว่าธุรกิจการค้าใดที่เราทำเพื่อไปถึงจุดนั้นและสามารถตัดสินใจอย่างชาญฉลาดเกี่ยวกับการล้างข้อมูล

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


ผมจะได้กล่าวว่า "มี ... ไม่มีอะไรผิดกับการมีความล้มเหลวในการทดสอบว่าเป็นคนพิการ "
CJ Dennis

การเปลี่ยนแปลงนั้นชัดเจนในความหมาย ขอขอบคุณ.
VoiceOfUnreason

26

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

การทดสอบหน่วยไม่ได้อยู่ที่นั่นเพื่อตรวจสอบว่ารหัสของคุณไม่มีข้อบกพร่อง

ฉันคิดว่านี่เป็นความเข้าใจผิดที่สำคัญ หากนี่คือบทบาทของพวกเขาคุณคาดหวังว่าจะมีการทดสอบที่ล้มเหลวทั่วทุกสถานที่ แต่แทน

การทดสอบหน่วยตรวจสอบว่ารหัสของคุณทำในสิ่งที่คุณคิด

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

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

การทดสอบการยอมรับอาจเป็นสิ่งที่คุณต้องการ

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


2
ฉันเคยต้องเปลี่ยนห้องสมุดด้วยอีก การทดสอบหน่วยช่วยฉันรับรองว่ากรณีมุมทั้งหมดยังคงได้รับการปฏิบัติเหมือนกันด้วยรหัสใหม่
Thorbjørn Ravn Andersen

24

ผมดูว่ามันเป็นเทียบเท่าซอฟแวร์ของดาวน์ซินโดรหน้าต่างหัก

การทดสอบการทำงานบอกฉันว่ารหัสมีคุณภาพที่กำหนดและเจ้าของรหัสนั้นใส่ใจกับมัน

สำหรับเมื่อคุณควรใส่ใจเกี่ยวกับคุณภาพที่ค่อนข้างขึ้นอยู่กับสาขาซอร์สโค้ด / พื้นที่เก็บข้อมูลที่คุณกำลังทำงานอยู่ รหัส Dev อาจมีการทดสอบที่ใช้งานไม่ได้ซึ่งระบุว่ากำลังดำเนินการอยู่ (หวังว่า!)

การทดสอบที่เสียหายในสาขา / พื้นที่เก็บข้อมูลสำหรับระบบสดควรตั้งค่าเสียงระฆังเตือนทันที หากการทดสอบที่เสียหายได้รับอนุญาตให้ดำเนินการต่อที่ล้มเหลวหรือหากพวกเขาทำเครื่องหมายอย่างถาวรว่า "เพิกเฉย" - คาดว่าจำนวนของพวกเขาจะเพิ่มขึ้นเมื่อเวลาผ่านไป หากสิ่งเหล่านี้ไม่ได้รับการตรวจสอบเป็นประจำจะมีการตั้งค่าแบบอย่างที่ดีว่ามันจะเหลือการทดสอบที่เสียหาย

มีการดูการทดสอบที่ใช้งานไม่ได้ในหลาย ๆ ร้านเพื่อให้มีข้อ จำกัด ว่าสามารถใช้รหัสที่เสียหายได้หรือไม่


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

1
@ Luaan ใช่มันค่อนข้างจะถือว่าการทดสอบหน่วยทั้งหมดจะถูกสร้างขึ้น แน่นอนว่าไม่ใช่เรื่องแปลกสำหรับผู้จัดการสร้างเพื่อฝานและทดสอบลูกเต๋าผ่านแอตทริบิวต์บางอย่างขึ้นอยู่กับระยะเวลาที่พวกเขาเรียกใช้พวกเขาเปราะและเกณฑ์อื่น ๆ มากมาย
Robbie Dee

คำตอบนี้ยอดเยี่ยมจากประสบการณ์ของฉัน เมื่อบางคนคุ้นเคยกับการเพิกเฉยต่อการทดสอบที่ล้มเหลวหรือทำลายแนวปฏิบัติที่ดีที่สุดในบางจุดให้เวลาผ่านไปสองสามเดือนและคุณจะเห็น% ของการทดสอบที่เพิกเฉยเพิ่มขึ้นอย่างมากคุณภาพของโค้ดลดลงถึงระดับ "แฮ็คสคริปต์" . และมันจะเป็นเรื่องยากมากที่จะจำทุกคนในกระบวนการ
usr-local-ΕΨΗΕΛΩΝ

11

นี่คือการเข้าใจผิดตรรกะพื้นฐาน:

ถ้าเป็นสิ่งที่ดีเมื่อการทดสอบทั้งหมดผ่านมันจะต้องไม่ดีถ้าการทดสอบใด ๆ ล้มเหลว

ด้วยการทดสอบหน่วยก็เป็นสิ่งที่ดีเมื่อการทดสอบทั้งหมดผ่าน มันเป็นสิ่งที่ดีเมื่อการทดสอบล้มเหลว ทั้งสองไม่จำเป็นต้องอยู่ในการต่อต้าน

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


แนวความคิดที่น่าสนใจ ฉันเห็นการเข้าใจผิดของคำถามมากขึ้นเช่นนี้: "เนื่องจากเป็นการดีเมื่อการทดสอบหน่วยล้มเหลวจึงไม่ดีเมื่อการทดสอบทั้งหมดผ่าน"
Doc Brown

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

9

คำตอบของ Phill W นั้นยอดเยี่ยม ฉันไม่สามารถแทนที่ได้

อย่างไรก็ตามฉันต้องการมุ่งเน้นไปที่ส่วนอื่นที่อาจเป็นส่วนหนึ่งของความสับสน

ในบางองค์กรเห็นได้ชัดว่าส่วนหนึ่งของกระบวนการวางจำหน่ายซอฟต์แวร์คือการใช้การทดสอบหน่วย แต่ ณ เวลาใดก็ตามการทดสอบหน่วยจะต้องผ่าน

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

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


สิ่งนี้สามารถสร้างความขัดแย้งตามกฎของทีม ฉันพบสิ่งนี้จริง ๆ ไม่กี่สัปดาห์ที่ผ่านมา:

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

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

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


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

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

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

1
คุณสมบัติธงแก้ไขความขัดแย้งที่ชัดเจน
RubberDuck

1
@ Flater ใช่สำหรับ reworking ตรรกะที่มีอยู่ด้วย
RubberDuck

6

หากคุณไม่แก้ไขการทดสอบหน่วยทั้งหมดคุณสามารถเข้าสู่สถานะที่ไม่มีใครแก้ไขการทดสอบที่เสียหายได้อย่างรวดเร็ว

  1. ไม่ถูกต้องเนื่องจากการทดสอบผ่านหน่วยไม่แสดงรหัสสมบูรณ์

  2. มันไม่น่าเชื่อเลยที่จะเกิดโค้ดที่ยากต่อการทดสอบเช่นกันซึ่งเป็นผลดีจากมุมมองของการออกแบบ

  3. การครอบคลุมรหัสสามารถช่วยได้ (แม้ว่าจะไม่ใช่ยาครอบจักรวาล) การทดสอบหน่วยเป็นเพียงส่วนหนึ่งของการทดสอบ - คุณต้องการการทดสอบการรวม / การยอมรับ


6

ในการเพิ่มคะแนนสองสามข้อให้กับคำตอบที่ดีอยู่แล้ว ...

แต่ ณ เวลาใด ๆ การทดสอบหน่วยทั้งหมดจะต้องผ่าน

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

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

คำตอบอื่น ๆ ครอบคลุมถึงขอบเขตของการทดสอบ

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

หาก ณ เวลาใดเวลาทุกหน่วยทดสอบผ่านแล้วไม่มีภาพใหญ่ของรัฐของซอฟต์แวร์ ณ เวลาใด ๆ ไม่มีแผนงาน / เป้าหมาย

ทำไมต้องมีโรดแมพ

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

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


6

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

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

public class MyProgram {
  public boolean alwaysTrue() {
    return true;
  }

  @Test
  public void testAlwaysTrue() {
    assert(alwaysTrue() == true);
  }
}

เป็นเรื่องไม่สำคัญที่จะคิดการทดสอบหน่วยที่จะล้มเหลว หรือเกิดขึ้นแน่นอนกับการทดสอบหน่วยที่จะยุ่งยากในการแก้ไข

ในกรณีนั้นอาจไม่ใช่การทดสอบหน่วย แต่เป็นการทดสอบการรวมหากมีความซับซ้อน

หาก ณ เวลาใดเวลาทุกหน่วยทดสอบผ่านแล้วไม่มีภาพใหญ่ของรัฐของซอฟต์แวร์ ณ เวลาใด ๆ ไม่มีแผนงาน / เป้าหมาย

จริงเรียกว่าการทดสอบหน่วยสำหรับเหตุผลตรวจสอบหน่วยของรหัสขนาดเล็ก

มันขัดขวางการเขียนหน่วยทดสอบล่วงหน้า - ก่อนดำเนินการ

นักพัฒนา จะยับยั้งการเขียนการทดสอบใด ๆหากพวกเขาไม่เข้าใจประโยชน์ของมันโดยธรรมชาติของพวกเขา (นอกเสียจากพวกเขามาจาก QA)


“ ผู้พัฒนาจะขัดขวาง [sic] การเขียนการทดสอบใด ๆ ตามลักษณะของพวกเขา” - นั่นเป็นเรื่องไร้สาระที่สุด ฉันทำงานที่ บริษัท พัฒนาซอฟต์แวร์ที่ฝึก TDD และ BDD
RubberDuck

@RubberDuck ฉันพยายามที่จะตอบคำถาม "ข้อเท็จจริง" และฉันพูดเกินจริง ฉันจะอัปเดต
user7294900

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

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

@ BenVoigt ฉันไม่คิดว่าฉันคาดว่าจะให้คำตอบ "โปรแกรมที่สำคัญ"
user7294900

4

มันส่งเสริมแนวคิดที่ว่ารหัสควรสมบูรณ์และไม่มีข้อบกพร่อง

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

เป็นเรื่องไม่สำคัญที่จะคิดการทดสอบหน่วยที่จะล้มเหลว หรือเกิดขึ้นแน่นอนกับการทดสอบหน่วยที่จะยุ่งยากในการแก้ไข

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

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

หาก ณ เวลาใดเวลาทุกหน่วยทดสอบผ่านแล้วไม่มีภาพใหญ่ของรัฐของซอฟต์แวร์ ณ เวลาใด ๆ ไม่มีแผนงาน / เป้าหมาย

การทดสอบนั้นเป็นเป้าหมายขนาดเล็กมากขึ้น ในการพัฒนาโดยอาศัยการทดสอบโปรแกรมเมอร์จะเขียนการทดสอบ (เอกพจน์) ก่อนจากนั้นมีเป้าหมายที่ชัดเจนในการติดตั้งโค้ด จากนั้นทดสอบต่อไปและอื่น ๆ

ฟังก์ชั่นของการทดสอบไม่ควรอยู่ในความสมบูรณ์ก่อนที่จะเขียนโค้ด

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

มันขัดขวางการเขียนหน่วยทดสอบล่วงหน้า - ก่อนดำเนินการ

ฉันไม่เห็นว่าข้อความนี้จะเป็นจริงได้อย่างไร แบบทดสอบการเขียนควรเป็นส่วนหนึ่งของการนำไปปฏิบัติ

ฉันทำอะไรบางอย่างหายไปหรือเปล่า เหตุใดองค์กรจึงคาดหวังว่าการทดสอบหน่วยทั้งหมดจะผ่าน?

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

นอกจากนี้ส่วนใหญ่ของการทดสอบคือ "การถดถอย" คุณต้องการที่จะพัฒนาหรือสร้างรหัสใหม่ด้วยความมั่นใจ การมีการทดสอบสีเขียวจำนวนมากช่วยให้คุณทำเช่นนั้นได้

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

นี่ไม่ใช่การใช้ชีวิตในโลกแห่งความฝันใช่ไหม

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

และมันไม่ขัดขวางความเข้าใจที่แท้จริงของรหัสจริงเหรอ?

ไม่แน่นอนทำไมถึงเป็นเช่นนั้น?

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

เห็นได้ชัดว่าการเขียนการทดสอบที่ไม่ดีนั้นไม่ดี แต่นั่นไม่เกี่ยวอะไรกับฟังก์ชั่นการทดสอบ


3

(จากความคิดเห็นเดิมของฉัน)

มีความแตกต่างระหว่างฟังก์ชันการทำงานที่จำเป็นและเป้าหมายในอนาคต การทดสอบสำหรับฟังก์ชั่นที่ต้องการ: มีความแม่นยำเป็นทางการใช้งานได้และหากการทดสอบล้มเหลวซอฟต์แวร์จะไม่ทำงาน เป้าหมายในอนาคตอาจไม่แม่นยำหรือเป็นทางการปล่อยให้อยู่คนเดียวดังนั้นพวกเขาจึงเหลือไว้ในภาษาธรรมชาติเช่นในปัญหา / ตัวติดตามบั๊กเอกสารความคิดเห็น ฯลฯ

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


2

วัตถุประสงค์ของการทดสอบแบบอัตโนมัติคือการบอกคุณเมื่อคุณมีเสียบางสิ่งบางอย่างเร็วที่สุดเท่าที่เป็นไปได้ เวิร์กโฟลว์มีลักษณะดังนี้:

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

หากการทดสอบของคุณล้มเหลวแล้วขั้นตอนที่ # 3 ไม่ทำงานอย่างมีประสิทธิภาพ - การทดสอบจะล้มเหลว แต่คุณไม่รู้ว่านั่นหมายความว่าคุณทำอะไรบางอย่างผิดปกติหรือไม่ตรวจสอบ บางทีคุณอาจนับจำนวนการทดสอบที่ล้มเหลว แต่จากนั้นการเปลี่ยนแปลงอาจแก้ไขข้อบกพร่องหนึ่งข้อและทำลายอีกข้อหนึ่งหรือการทดสอบอาจเริ่มล้มเหลวด้วยเหตุผลอื่น ซึ่งหมายความว่าคุณต้องรอระยะเวลาหนึ่งก่อนที่คุณจะรู้ว่ามีบางอย่างผิดปกติหรือไม่จนกว่าปัญหาทั้งหมดจะได้รับการแก้ไขหรือจนกว่าจะมีการตรวจสอบข้อผิดพลาดแต่ละครั้ง

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

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

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

มันขัดขวางการเขียนหน่วยทดสอบล่วงหน้า

ถ้ามันเหมาะกับคุณแล้วให้เขียนการทดสอบไว้ล่วงหน้าอย่าตรวจสอบสิ่งเหล่านั้นในต้นแบบ / หีบของคุณจนกว่าจะผ่าน

หาก ณ เวลาใดเวลาทุกหน่วยทดสอบผ่านแล้วไม่มีภาพใหญ่ของรัฐของซอฟต์แวร์ ณ เวลาใด ๆ ไม่มีแผนงาน / เป้าหมาย

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


2

คำตอบที่มีอยู่เป็นสิ่งที่ดีอย่างแน่นอน แต่ฉันไม่เคยเห็นใครเข้าใจความเข้าใจผิดพื้นฐานในคำถามนี้:

ณ เวลาใดก็ตามการทดสอบหน่วยทั้งหมดจะต้องผ่าน

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

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

สิ่งนี้จะดึงข้อมูลในหัวข้อของการสร้างการทดสอบใหม่: การทดสอบควรยืนยันตรรกะและพฤติกรรมของรหัส เงื่อนไขขอบเขตเงื่อนไขความผิด ฯลฯ เมื่อฉันเขียนการทดสอบใหม่ฉันพยายามระบุ "ฮอตสปอต" เหล่านี้ในรหัส

หน่วยทดสอบเอกสารว่าฉันคาดหวังว่ารหัสของฉันจะถูกเรียกว่า - เงื่อนไขเบื้องต้นผลผลิตที่คาดหวัง ฯลฯ

หากการทดสอบหยุดพักหลังจากการเปลี่ยนแปลงฉันต้องตัดสินใจว่ารหัสหรือการทดสอบนั้นมีข้อผิดพลาด


ในฐานะที่เป็นบันทึกย่อด้านการทดสอบหน่วยบางครั้งไปด้วยกันกับการพัฒนาทดสอบขับเคลื่อน หนึ่งในหลักการของ TDD คือการทดสอบที่เสียหายเป็นแนวทางของคุณ เมื่อการทดสอบล้มเหลวคุณต้องแก้ไขรหัสเพื่อให้การทดสอบผ่าน นี่คือตัวอย่างที่ชัดเจนจากสัปดาห์ก่อนหน้านี้:

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

แต่ห้องสมุดของฉันจะแยกวิเคราะห์แบบสอบถามโดยใช้ Antlr และ Oracle 12c ไวยากรณ์แล้วล้อมการยืนยันที่หลากหลายบนต้นไม้ไวยากรณ์เอง สิ่งที่ต้องการคือถูกต้อง (ไม่มีข้อผิดพลาดในการแยกวิเคราะห์) พารามิเตอร์ทั้งหมดเป็นที่พอใจจากการรวบรวมพารามิเตอร์คอลัมน์ทั้งหมดที่คาดหวังที่อ่านโดยตัวอ่านข้อมูลจะปรากฏในแบบสอบถาม ฯลฯ ทั้งหมดเหล่านี้เป็นรายการที่เลื่อนผ่านไปยัง การผลิตในเวลาต่างๆ

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

UPDATE my_table(
SET column_1 = 'MyValue'
WHERE id_column = 123;

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

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

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


0

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

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

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


ฉันคิดว่าสิ่งที่คุณอธิบายว่า "การทดสอบภายนอก" มักจะอธิบายไว้ที่อื่นว่าเป็นการทดสอบ "การรวม"
GalacticCowboy

ใช่ แต่ฉันเจอความแตกต่างในคำศัพท์ สำหรับบางคนการทดสอบการรวมเป็นเรื่องของการปรับใช้ซอฟต์แวร์ / ฮาร์ดแวร์ / เครือข่ายที่ปรับใช้ในขณะที่ฉันกำลังพูดถึงพฤติกรรมภายนอกของซอฟต์แวร์ที่คุณกำลังพัฒนา
Michael Kay

0

"แต่ ณ เวลาใด ๆ การทดสอบหน่วยทั้งหมดจะต้องผ่าน"

หากนั่นคือทัศนคติใน บริษัท ของคุณนั่นเป็นปัญหา ในเวลา CERTAIN กล่าวคือเมื่อเราประกาศว่ารหัสพร้อมที่จะย้ายไปยังสภาพแวดล้อมต่อไปการทดสอบหน่วยทั้งหมดจะต้องผ่าน แต่ในระหว่างการพัฒนาเราควรคาดหวังการทดสอบหลาย ๆ หน่วยเป็นประจำ

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

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

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

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


-7

นี่เป็นตัวอย่างที่เฉพาะเจาะจงของอคติยืนยันซึ่งผู้คนมักจะหาข้อมูลที่ยืนยันความเชื่อที่มีอยู่

ตัวอย่างที่มีชื่อเสียงเรื่องนี้เกิดขึ้นในเกมที่ 2,4,6

  • ฉันมีกฎอยู่ในหัวของฉันว่าชุดตัวเลขสามจำนวนใด ๆ จะผ่านหรือล้มเหลว
  • 2,4,6 เป็นบัตรผ่าน
  • คุณสามารถระบุชุดตัวเลขสามจำนวนและฉันจะบอกคุณว่าพวกเขาผ่านหรือไม่

คนส่วนใหญ่เลือกกฎพูดว่า "ช่องว่างระหว่างหมายเลขที่ 1 และที่ 2 นั้นเหมือนกับช่องว่างระหว่างที่ 2 และที่ 3"

พวกเขาจะทดสอบตัวเลขบางส่วน:

  • 4, 8, 12? ผ่าน
  • 20, 40, 60? ผ่าน
  • 2, 1004, 2006? ผ่าน

พวกเขาพูดว่า "ใช่ทุกการสังเกตยืนยันสมมติฐานของฉันมันต้องเป็นจริง" และประกาศกฎของพวกเขาแก่ผู้ให้ไขปริศนา

แต่พวกเขาไม่เคยได้รับ 'ความล้มเหลว' ชุดเดียวกับตัวเลขสามชุด กฎอาจเป็น 'ตัวเลขทั้งสามจำเป็นต้องเป็นตัวเลข' สำหรับข้อมูลทั้งหมดที่มี

กฎเป็นจริงเพียงว่าตัวเลขอยู่ในลำดับจากน้อยไปมาก โดยทั่วไปผู้คนจะได้รับแก้ปริศนานี้เท่านั้นหากพวกเขาทดสอบความล้มเหลว คนส่วนใหญ่เข้าใจผิดโดยเลือกกฎเฉพาะเจาะจงมากขึ้นและทดสอบเฉพาะตัวเลขที่ตรงตามกฎนี้เท่านั้น

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


2
มันเกี่ยวข้องกับคำถามอย่างไร การทดสอบหน่วยที่ล้มเหลวเป็นหลักฐานของปัญหาตามคำนิยาม
Frax

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