การครอบคลุมการทดสอบเป็นการวัดคุณภาพของรหัสที่เพียงพอหรือไม่


20

หากฉันมีรหัสบางส่วนที่มีการทดสอบครอบคลุม 80% (การทดสอบทั้งหมดผ่าน) เป็นไปได้ไหมที่จะบอกว่ามันมีคุณภาพสูงกว่ารหัสที่ไม่มีการครอบคลุมการทดสอบหรือไม่

หรือมันยุติธรรมที่จะพูดว่ามันบำรุงรักษาได้มากขึ้น?


2
ความคุ้มครอง 100% ไม่ได้หมายความว่าได้รับการทดสอบอย่างดี แต่ 0% หมายความว่ายังไม่ได้ทำการทดสอบเลย
mouviciel

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

@JoeRounceville ฉันไม่แน่ใจ ... ฉันสามารถบรรลุความครอบคลุมการทดสอบสูงในขณะที่การทดสอบไม่มีประโยชน์อย่างแท้จริง ความครอบคลุมเพียงแค่บอกคุณว่ามีการสัมผัสโค้ดในชุดทดสอบมากน้อยแค่ไหนไม่ว่าการทดสอบนั้นจะมีความหมายหรือไม่
Andres F.

1
@AndresF นั่นเป็นเหตุผลที่ฉันพูดว่า "ไม่มีทางเทคนิคใช่จริง" คนไม่ใช่คนโง่ (โดยทั่วไป) พวกเขาไม่ได้ (โดยทั่วไป) ทดสอบเฉพาะกรณีที่ไม่มีเกมง่ายๆ ตามประสบการณ์ร้านค้าจำนวนมากหยุดอยู่ที่ประมาณ 80% ของความครอบคลุมทำให้สมมติฐาน (ปลอดภัยพอสมควร) ที่คนของพวกเขาไม่ใช่คนปัญญาอ่อน
Calphool

คำตอบ:


24

ในความเข้มงวดมันไม่ยุติธรรมที่จะทำการเรียกร้องใด ๆ จนกว่าคุณภาพของชุดทดสอบจะถูกจัดตั้งขึ้น การผ่านการทดสอบ 100% นั้นไม่มีความหมายหากการทดสอบส่วนใหญ่นั้นไม่สำคัญหรือซ้ำ ๆ กัน

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

เพื่อปรับปรุงการออกแบบการทดสอบคุณสามารถใช้ (1) เทคนิค whitebox (2) เทคนิค blackbox และ (3) การทดสอบการกลายพันธุ์

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

  • ทุกฟังก์ชั่นถูกเรียกหรือไม่? [ฟังก์ชั่นครอบคลุม]
  • ทุกคำสั่งดำเนินการหรือไม่ [การรายงานข่าว - ทั้งการรายงานข่าวการทำงานและการรายงานข่าวนั้นเรียบง่าย แต่ไม่มีอะไรดีกว่า]
  • สำหรับการตัดสินใจทุกครั้ง (เช่นifหรือwhile) คุณมีการทดสอบที่บังคับให้มันเป็นจริงและอื่น ๆ ที่บังคับให้มันเป็นเท็จหรือไม่? [ความครอบคลุมการตัดสินใจ]
  • สำหรับทุกเงื่อนไขที่เป็นการรวม (ใช้&&) หรือแยก (ใช้||) แต่ละ subexpression มีการทดสอบว่ามันเป็นจริง / เท็จ? [ความคุ้มครองสภาพ]
  • การครอบคลุมแบบวนซ้ำ: คุณมีการทดสอบที่บังคับให้ทำซ้ำ 0 ซ้ำ 1 ซ้ำ 1 ซ้ำ 2 ครั้งหรือไม่?
  • แต่ละอันbreakมาจากการวนซ้ำหรือไม่?

(2) เทคนิค Blackbox ใช้เมื่อมีความต้องการ แต่ตัวรหัสนั้นไม่ได้ สิ่งเหล่านี้สามารถนำไปสู่การทดสอบคุณภาพสูง:

  • การทดสอบ blackbox ของคุณครอบคลุมถึงเป้าหมายการทดสอบหลายอย่างหรือไม่ คุณจะต้องการให้การทดสอบของคุณเป็น "อ้วน": พวกเขาทดสอบฟีเจอร์ X เท่านั้น แต่ยังทดสอบ Y และ Z ด้วยการทำงานร่วมกันของคุณสมบัติที่แตกต่างกันเป็นวิธีที่ดีในการค้นหาข้อบกพร่อง
  • กรณีเดียวที่คุณไม่ต้องการให้การทดสอบ "อ้วน" คือเมื่อคุณกำลังทดสอบเงื่อนไขข้อผิดพลาด ตัวอย่างเช่นการทดสอบการป้อนข้อมูลของผู้ใช้ที่ไม่ถูกต้อง หากคุณพยายามบรรลุเป้าหมายการทดสอบการป้อนข้อมูลที่ไม่ถูกต้องหลายครั้ง (ตัวอย่างเช่นรหัสไปรษณีย์ที่ไม่ถูกต้องและที่อยู่ที่ไม่ถูกต้อง) เป็นไปได้ว่ากรณีหนึ่งกำลังหลอกลวงอีกกรณีหนึ่ง
  • พิจารณาประเภทอินพุตและสร้าง "คลาสเทียบเท่า" สำหรับประเภทอินพุต ตัวอย่างเช่นหากรหัสของคุณทดสอบเพื่อดูว่ารูปสามเหลี่ยมเป็นรูปสามเหลี่ยมด้านเท่าการทดสอบที่ใช้รูปสามเหลี่ยมที่มีด้าน (1, 1, 1) อาจจะพบข้อผิดพลาดชนิดเดียวกันกับที่ข้อมูลทดสอบ (2, 2, 2) และ (3, 3, 3) จะพบ เป็นการดีกว่าถ้าคุณใช้เวลาคิดถึงคลาสอื่นของอินพุต ตัวอย่างเช่นหากโปรแกรมของคุณจัดการภาษีคุณจะต้องการทดสอบวงเล็บภาษีแต่ละอัน [สิ่งนี้เรียกว่าการแบ่งพาร์ติชันแบบสมดุล]
  • กรณีพิเศษมักจะเกี่ยวข้องกับข้อบกพร่อง ข้อมูลการทดสอบของคุณควรมีค่าขอบเขตเช่นค่าที่ด้านบนหรือด้านล่างของขอบของงานที่เท่ากัน ตัวอย่างเช่นในการทดสอบอัลกอริทึมการเรียงลำดับคุณจะต้องทดสอบกับอาเรย์ว่างอาเรย์องค์ประกอบเดียวอาเรย์ที่มีสององค์ประกอบจากนั้นจึงเป็นอาเรย์ที่มีขนาดใหญ่มาก คุณควรพิจารณากรณีขอบเขตไม่เพียง แต่สำหรับการป้อนข้อมูล แต่สำหรับการส่งออกเช่นกัน [นี่คือการวิเคราะห์ค่าขอบเขตการโทร]
  • เทคนิคอื่นคือ "การคาดเดาข้อผิดพลาด" คุณมีความรู้สึกไหมถ้าคุณลองชุดค่าผสมพิเศษที่คุณสามารถทำให้โปรแกรมของคุณพังได้ จากนั้นลอง! โปรดจำไว้ว่าเป้าหมายของคุณคือการหาข้อบกพร่องไม่ได้ที่จะยืนยันว่าโปรแกรมที่ถูกต้อง บางคนมีความสามารถพิเศษในการคาดเดาข้อผิดพลาด

(3) ท้ายที่สุดสมมติว่าคุณมีการทดสอบที่ดีมากมายสำหรับการครอบคลุม whitebox และเทคนิคการใช้ blackbox คุณทำอะไรได้อีก? ได้เวลาทดสอบการทดสอบของคุณแล้ว เทคนิคหนึ่งที่คุณสามารถใช้ได้คือการทดสอบการกลายพันธุ์

ภายใต้การทดสอบการกลายพันธุ์คุณทำการปรับเปลี่ยน (สำเนา) โปรแกรมของคุณเพื่อสร้างข้อบกพร่อง การกลายพันธุ์อาจเป็น:

เปลี่ยนการอ้างอิงของตัวแปรหนึ่งเป็นตัวแปรอื่น แทรกฟังก์ชัน abs (); เปลี่ยนน้อยกว่าเป็นมากกว่า ลบคำสั่ง; แทนที่ตัวแปรด้วยค่าคงที่ ลบวิธีการเอาชนะ ลบการอ้างอิงไปยังวิธีการ super; เปลี่ยนลำดับการโต้แย้ง

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


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

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


7

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

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

ฉันรู้ว่าฉันต้องการบำรุงรักษาและขยายรหัสใด


7

รหัสที่ไม่มีการทดสอบอย่างแน่นอนจะมีคุณภาพสูงมากอ่านได้สวยงามและมีประสิทธิภาพ (หรือขยะทั้งหมด) ดังนั้นไม่มันไม่ยุติธรรมที่จะกล่าวว่ารหัสที่มีการทดสอบครอบคลุม 80% นั้นมีคุณภาพสูงกว่ารหัสที่ไม่มีการทดสอบครอบคลุม

อาจเป็นไปได้ที่จะบอกว่ารหัส 80% ที่ครอบคลุมกับการทดสอบที่ดีน่าจะมีคุณภาพที่ยอมรับได้และอาจรักษาได้ค่อนข้างดี แต่รับประกันน้อยจริงๆ


3

ฉันจะเรียกมันว่า refactorable มากขึ้น การปรับโครงสร้างใหม่นั้นง่ายมากหากรหัสถูกคลุมด้วยการทดสอบจำนวนมาก

มันจะยุติธรรมที่จะเรียกมันว่าบำรุงรักษาได้มากขึ้น


2

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

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


-2

ฉันได้ถามคำถามนี้กับตัวเองมาระยะหนึ่งแล้วเกี่ยวกับ "การครอบคลุมของเงื่อนไข" ดังนั้นเกี่ยวกับหน้านี้จาก atollic.com "ทำไมต้องมีการวิเคราะห์ความครอบคลุมของรหัส"

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

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

ในมุมมองการเปลี่ยนแปลงของNecker Cube ที่น่าสนใจตอนนี้รหัสทดสอบกำลังถูกทดสอบโดยรหัสที่อยู่ระหว่างการทดสอบ!


-3

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

การทดสอบเป็นหนึ่ง หลีกเลี่ยงการกลายพันธุ์ของข้อมูลเป็นอีกหนึ่ง ดังนั้นระบบประเภท หรือการตรวจสอบอย่างเป็นทางการ

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


นี่เป็นเพียงความคิดเห็นของคุณหรือคุณสามารถสำรองข้อมูลได้
ริ้น

2
การทดสอบไม่ใช่วิธีที่จะรับประกันว่าโปรแกรมจะทำในสิ่งที่คุณต้องการ
Andres F.

1
จากนั้นฉันก็ถูกทิ้งให้สงสัยว่าการทดสอบคืออะไร
Andrea

@gnat นี้แน่นอนความคิดเห็นของฉัน ถึงกระนั้นมันก็บอกว่าสิ่งที่พูด ฉันใช้ Haskell เป็นตัวอย่างของภาษาที่คอมไพเลอร์เข้มงวดมากและให้การรับประกันมากมายเกี่ยวกับรูปแบบการป้อนข้อมูลที่ดีรูปแบบผลข้างเคียงการกลายพันธุ์ของข้อมูล ฉันใช้ PHP เป็นตัวอย่างของภาษาที่ล่ามนั้นสุภาพมากและไม่มีสเปค แม้ในกรณีที่ไม่มีการทดสอบการมีอยู่ของการรับรองทั้งหมดจากประเภทและระบบเอฟเฟกต์มักให้ความน่าเชื่อถือในระดับที่เหมาะสม เพื่อชดเชยว่าด้วยการทดสอบคุณจะต้องมีชุดที่ครอบคลุมมาก
Andrea

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