ค่าของการตรวจสอบในการทดสอบหน่วยที่ล้มเหลวคืออะไร?


13

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

ฉันจะใช้ตัวอย่างง่ายๆ: Case Sensitivity รหัสปัจจุบันคำนึงถึงขนาดตัวพิมพ์ อินพุตที่ถูกต้องลงในเมธอดคือ "Cat" และจะส่งคืน enum ของ Animal อย่างไรก็ตามฟังก์ชั่นที่ต้องการของวิธีการไม่ควรคำนึงถึงตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ ดังนั้นหากวิธีการที่อธิบายไว้ถูกส่งผ่าน "cat" มันอาจจะส่งคืนบางอย่างเช่น Animal.Null แทน Animal.Cat และการทดสอบหน่วยจะล้มเหลว แม้ว่าการเปลี่ยนรหัสอย่างง่ายจะทำให้งานนี้เกิดปัญหาที่ซับซ้อนมากขึ้นอาจใช้เวลาหลายสัปดาห์ในการแก้ไข แต่การระบุข้อบกพร่องด้วยการทดสอบหน่วยอาจเป็นงานที่ซับซ้อนน้อยกว่า

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

มูลค่าของการตรวจสอบในการทดสอบหน่วยที่ใช้บั๊กจนกว่าจะมีใครสามารถแก้ไขโค้ดได้

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

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


นั่นเป็นวิธีหนึ่งในการเพิ่มหมายเลขการทดสอบเหล่านั้น
JeffO

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

คำตอบ:


17

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

ฉันใช้แทน

  • [Ignore("Reason")]คุณลักษณะที่ทำให้ผลลัพธ์เป็นสีเหลืองหรือ
  • throw new NotImplementedException()ที่ทำให้ผลลัพธ์เป็นสีเทา

หมายเหตุ: ฉันกำลังใช้ NUnit สำหรับ. net ฉันไม่แน่ใจว่าคุณสมบัติ "สีเทา" นั้นมีอยู่ในกรอบการทำงานอื่น ๆ หรือไม่

ดังนั้นฉันจึงชอบความหมายของผลการทดสอบหน่วยต่อไปนี้

  • สีเขียว: เสร็จแล้วทั้งหมด
  • grey: คุณสมบัติใหม่ที่วางแผนไว้ซึ่งต้องทำ แต่มีลำดับความสำคัญต่ำ
  • สีเหลือง: ข้อบกพร่องยังไม่ได้รับการแก้ไข ควรได้รับการแก้ไขในไม่ช้า
  • สีแดง: ข้อบกพร่องใหม่ ควรแก้ไขทันที

สามารถตรวจสอบทุกอย่างยกเว้น "สีแดง"

ในการตอบคำถาม: มีอันตรายเกินกว่าค่าที่จะเช็คอิน "red-failed-testes" แต่การตรวจสอบใน "การทดสอบที่ไม่สนใจสีเหลือง" หรือ "gray-NotImplementedYet-test" สามารถใช้เป็นรายการสิ่งที่ต้องทำ


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

4
will probably never be fixedเป็นการตัดสินใจทางการเมืองหากคุณต้องการใช้ความบ้าคลั่งในการทดสอบอัตโนมัติหรือไม่ ด้วย "การทดสอบที่เพิกเฉย" คุณมีโอกาสที่จะแก้ไข ทิ้ง "การทดสอบที่ไม่สนใจ" หมายถึง "ละทิ้งการทดสอบอัตโนมัติไปเรื่อย ๆ จนกว่าจะไม่มีอีกต่อไป"
k3b

8

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

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


5
แต่คุณไม่ควรตรวจสอบการทดสอบที่ล้มเหลวเนื่องจากเซิร์ฟเวอร์การสร้างของคุณไม่ควรสร้างโครงการที่มีการทดสอบที่ใช้งานไม่ได้
CaffGeek

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

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

@Chad: ใช่แล้วฉันลืมเซิร์ฟเวอร์ CI โดยสิ้นเชิง นั่นเป็นจุดที่ต้องพิจารณาอย่างแน่นอน มันก็คุ้มค่าที่จะอธิบายสิ่งที่เราหมายถึงโดยการทดสอบ "แตก" พวกเขาเป็นเพียงแค่การทดสอบแบบ "ไม่ดี" หรือการทดสอบล้มเหลวเนื่องจาก API เปลี่ยนแปลงไปในทางใดทางหนึ่งหรือไม่
Tieson T.

คำถามควรชัดเจนขึ้น มันควรจะเป็นการทดสอบจะรวบรวม แต่ผลลัพธ์ที่คาดหวังจะล้มเหลว

6

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

กล่าวโดยย่อการทดสอบหน่วยที่ล้มเหลวทำให้ทีมมีรายการ "สิ่งที่ต้องทำ"

ด้วยเหตุนี้ความล้มเหลวในการทดสอบหน่วยอยู่ไกลดีกว่าไม่มีการทดสอบหน่วยที่ทุกคน. *
กรณีที่ไม่มีการทดสอบหน่วยใบทีมพัฒนาในที่มืด; รายละเอียดจะต้องได้รับการยืนยันซ้ำ ๆด้วยตนเอง

[* ให้ว่าหน่วยทดสอบจริงทดสอบสิ่งที่มีประโยชน์]


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

6

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

นี่คือย่อหน้าจากจุดเริ่มต้นของบทที่ 13 ของการทำงานอย่างมีประสิทธิภาพด้วยรหัสมรดก :

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


3

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

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


+1 แม้ว่าจะไม่มีคำตอบว่าจะเช็คอินหรือไม่มีข้อโต้แย้งที่สำคัญคือ: สร้างเซิร์ฟเวอร์
k3b

ฉันควรใช้คุณลักษณะเพื่อทำเครื่องหมายการทดสอบดังกล่าวแทนที่จะย้ายไปไว้ในโครงการอื่น
CodesInChaos

2

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

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

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


ว้าว ... "ประเด็นของการทดสอบหน่วยไม่ให้ประสบความสำเร็จ 100%" คุณกำลังบอกว่าพวกเขาไม่จำเป็นต้องผ่าน!
CaffGeek

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

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

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

4
@unholysampler, CI หรือไม่มี CI ประเด็นคือเมื่อคุณทำการทดสอบและเคยเห็นแสงสีแดงคุณจะคุ้นเคยกับมัน ดังนั้นเมื่อสิ่งที่เป็นสีเขียวเปลี่ยนเป็นสีแดง ... คุณจะรู้ได้อย่างไร!? มันเป็นวิธีปฏิบัติที่น่ากลัวและหนึ่งในเหตุผลที่การทดสอบไม่ได้รับการยอมรับในหลาย ๆ องค์กร
CaffGeek

1

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


-3

วิธีที่ฉันเห็น TDD ที่ทำด้วยการใช้การทดสอบสำหรับรหัสที่ยังไม่เสร็จคือเขียนการทดสอบครั้งแรกด้วยแอตทริบิวต์ [ExpectedException] หรือคล้ายกัน สิ่งนี้ควรผ่านในขั้นต้นเนื่องจากรหัสที่ไม่สมบูรณ์จะไม่มีตรรกะใด ๆ ในนั้นและเขียนรหัสการยกเว้นใหม่ () แม้ว่าการผ่านข้อยกเว้นจะผิด แต่อย่างน้อยก็จะทำให้การทดสอบผ่านในขั้นต้นและเหมาะสำหรับการเช็คอิน เราอาจลืมการทดสอบที่ไม่สนใจ แต่อาจเป็นระเบียบเรียบร้อยหรือเติมรหัสที่ไม่สมบูรณ์ เมื่อเราทำเช่นนั้นการทดสอบที่สอดคล้องกันโดยอัตโนมัติซึ่งคาดว่าจะมีการคัดออกจะเริ่มล้มเหลวและเตือนให้คุณแก้ไข สิ่งนี้อาจเกี่ยวข้องกับการเปลี่ยนแปลงเล็กน้อยของการทดสอบเพื่อกำจัด ExpectException และทำการยืนยันจริงแทน CI, Dev, ผู้ทดสอบและลูกค้าทุกคนมีความสุขและเป็นสถานการณ์ที่ชนะ?


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