การทดสอบการกลายพันธุ์คืออะไร? (ตัวอย่าง)
⚡ สรุปอย่างชาญฉลาด
การทดสอบการกลายพันธุ์ (Mutation Testing) จงใจใส่ข้อผิดพลาดเล็กๆ เข้าไปในซอร์สโค้ด จากนั้นจึงนำชุดทดสอบที่มีอยู่ไปใช้กับทุกเวอร์ชันที่มีข้อผิดพลาด เพื่อวัดว่าการทดสอบเหล่านั้นมีประสิทธิภาพเพียงพอที่จะตรวจจับการเปลี่ยนแปลงได้หรือไม่
การทดสอบการกลายพันธุ์คืออะไร?
การทดสอบการกลายพันธุ์ การทดสอบแบบ Mutation Testing คือการทดสอบซอฟต์แวร์ประเภทหนึ่งที่ทำการเปลี่ยนแปลงหรือดัดแปลงคำสั่งบางส่วนในโค้ดต้นฉบับ เพื่อตรวจสอบว่ากรณีทดสอบสามารถค้นหาข้อผิดพลาดในโค้ดต้นฉบับได้หรือไม่ เป้าหมายของการทดสอบแบบ Mutation Testing คือการรับรองคุณภาพของกรณีทดสอบในแง่ของความแข็งแกร่ง เพื่อให้กรณีทดสอบล้มเหลวเมื่อเผชิญกับโค้ดต้นฉบับที่ถูกดัดแปลง
การเปลี่ยนแปลงที่เกิดขึ้นในโปรแกรมกลายพันธุ์จะต้องมีขนาดเล็กมาก เพื่อไม่ให้ส่งผลกระทบต่อเป้าหมายโดยรวมของโปรแกรม การทดสอบการกลายพันธุ์ (Mutation Testing) เรียกอีกอย่างว่ากลยุทธ์การทดสอบแบบอิงข้อผิดพลาด (fault-based testing strategy) เพราะเกี่ยวข้องกับการสร้างข้อผิดพลาดในโปรแกรมโดยเจตนา มันเป็นรูปแบบหนึ่งของ สีขาว Box การทดสอบ ซึ่งส่วนใหญ่ใช้ในระหว่าง การทดสอบหน่วย.
การทดสอบการกลายพันธุ์ (Mutation Testing) ถูกเสนอขึ้นครั้งแรกในปี 1971 ในบทความของนักศึกษาโดย Richard Lipton และได้รับการกำหนดอย่างเป็นทางการในบทความปี 1978 เรื่อง “Hints on Test Data Selection” โดย DeMillo, Lipton และ Sayward อย่างไรก็ตาม การทดสอบนี้เริ่มซบเซาลงเนื่องจากต้นทุนการคำนวณที่สูงในสมัยนั้น แต่ก็กลับมาได้รับความนิยมอีกครั้งในภาษาโปรแกรมต่างๆ เช่น... Java, C#, Python, Javaสคริปต์ และ XML
จะทำการทดสอบการกลายพันธุ์ได้อย่างไร?
ต่อไปนี้คือขั้นตอนในการดำเนินการทดสอบการกลายพันธุ์ หรือที่เรียกว่าการวิเคราะห์การกลายพันธุ์:
ขั้นตอนที่ 1: มีการเพิ่มข้อผิดพลาดเข้าไปในซอร์สโค้ดของโปรแกรมโดยการสร้างเวอร์ชันต่างๆ ที่เรียกว่ามิวแทนต์ แต่ละมิวแทนต์ควรมีข้อผิดพลาดเพียงข้อเดียว และเป้าหมายคือการทำให้เวอร์ชันมิวแทนต์นั้นล้มเหลว ซึ่งเป็นการแสดงให้เห็นถึงประสิทธิภาพของกรณีทดสอบ
ขั้นตอนที่ 2: มีการนำกรณีทดสอบไปใช้กับโปรแกรมต้นฉบับและโปรแกรมที่ได้รับการแก้ไขแล้ว กรณีทดสอบ ควรจะเพียงพอและมีการปรับแต่งเพื่อตรวจจับข้อผิดพลาดในโปรแกรม
ขั้นตอนที่ 3: เปรียบเทียบผลลัพธ์ของโปรแกรมต้นฉบับและโปรแกรมที่ได้รับการแก้ไข
ขั้นตอนที่ 4: หากโปรแกรมต้นฉบับและโปรแกรมที่กลายพันธุ์สร้างผลลัพธ์ที่แตกต่างกัน แสดงว่าโปรแกรมที่กลายพันธุ์นั้นถูกกำจัดโดยชุดทดสอบ ดังนั้นชุดทดสอบนี้จึงดีพอที่จะตรวจจับการเปลี่ยนแปลงระหว่างโปรแกรมต้นฉบับและโปรแกรมที่กลายพันธุ์ได้
ขั้นตอนที่ 5: หากโปรแกรมต้นฉบับและโปรแกรมที่กลายพันธุ์สร้างผลลัพธ์เหมือนกัน โปรแกรมที่กลายพันธุ์จะยังคงทำงานอยู่ ในกรณีเช่นนี้ จำเป็นต้องสร้างกรณีทดสอบที่มีประสิทธิภาพมากขึ้นเพื่อกำจัดโปรแกรมที่กลายพันธุ์ทั้งหมด
แผนภาพด้านล่าง tracมีขั้นตอนห้าขั้นตอนเหมือนเดิม ตั้งแต่โปรแกรมดั้งเดิม การสร้างตัวกลายพันธุ์ ไปจนถึงคำตัดสินว่าตายหรือรอดชีวิต
จะสร้างโปรแกรมกลายพันธุ์ได้อย่างไร?
การกลายพันธุ์คือการเปลี่ยนแปลงทางไวยากรณ์เพียงครั้งเดียวในคำสั่งโปรแกรม โปรแกรมที่กลายพันธุ์แต่ละโปรแกรมจะต้องแตกต่างจากโปรแกรมเดิมด้วยการกลายพันธุ์เพียงหนึ่งเดียวเท่านั้น
| โปรแกรมต้นฉบับ | โปรแกรมกลายพันธุ์ |
| ถ้า (x>y) พิมพ์ “สวัสดี” อื่น พิมพ์ “สวัสดี” |
ถ้า (x พิมพ์ “สวัสดี” อื่น พิมพ์ “สวัสดี” |
ในตัวอย่างข้างต้น มีเพียงตัวดำเนินการเปรียบเทียบเท่านั้นที่เปลี่ยนแปลงไป แต่ในกรณีทดสอบที่ x มากกว่า y จะแสดงผลเป็น “Hi” แทนที่จะเป็น “Hello” ภาพประกอบแสดงให้เห็นถึงการแก้ไขทางไวยากรณ์เพียงจุดเดียวนี้
จะต้องเปลี่ยนแปลงอะไรในโปรแกรมกลายพันธุ์?
มีเทคนิคหลายอย่างที่สามารถใช้สร้างโปรแกรมกลายพันธุ์ได้ สามกลุ่มด้านล่างนี้ครอบคลุมตัวดำเนินการกลายพันธุ์ส่วนใหญ่ที่มาพร้อมกับเครื่องมือต่างๆ
| Operaและผู้ประกอบการทดแทน | ตัวดำเนินการแก้ไขนิพจน์ | ตัวดำเนินการแก้ไขคำสั่ง |
| แทนที่ตัวถูกดำเนินการด้วยตัวถูกดำเนินการอื่น (เช่น แทนที่ x ด้วย y หรือแทนที่ y ด้วย x) หรือแทนที่ด้วยค่าคงที่ | แทนที่ตัวดำเนินการ หรือแทรกตัวดำเนินการใหม่ในคำสั่งโปรแกรม | คำสั่งทางโปรแกรมได้รับการแก้ไขเพื่อสร้างโปรแกรมกลายพันธุ์ |
| ตัวอย่าง: ถ้า(x>y) แทนที่ค่า x และ y ถ้า(5>y) แทนที่ x ด้วยค่าคงที่ 5 |
ตัวอย่าง: ถ้า(x==y) เราสามารถแทนที่ == ด้วย >= แล้วจะได้โปรแกรมกลายพันธุ์ดังนี้ If(x>=y) และใส่ ++ ในคำสั่ง ถ้า(x==++y) |
ตัวอย่าง: ลบส่วน else ในคำสั่ง if-else ลบคำสั่ง if-else ทั้งหมดเพื่อตรวจสอบการทำงานของโปรแกรม |
ตัวอย่างตัวดำเนินการกลายพันธุ์บางส่วน:
- การเปลี่ยนฉลาก GOTO
- การแทนที่คำสั่งส่งคืน
- การลบใบแจ้งยอด
- การแทรกตัวดำเนินการเอกภาค (เช่น – และ ++)
- การเปลี่ยนตัวเชื่อมต่อแบบลอจิคัล
- การแทนที่ชื่ออาร์เรย์ที่เปรียบเทียบได้
- การลบส่วน else ออกจากคำสั่ง if-else
- การเพิ่มหรือเปลี่ยนตัวดำเนินการ
- การแทนที่คำสั่งโดยการเปลี่ยนข้อมูล
- การปรับเปลี่ยนข้อมูลสำหรับตัวแปร
- การปรับเปลี่ยนชนิดข้อมูลในโปรแกรม
Operaทอร์ที่สัมผัสกับเงื่อนไขขอบเขตมักจะอยู่รอดได้บ่อยที่สุด ดังนั้นผลลัพธ์ของการกลายพันธุ์จึงมักชี้กลับไปยังช่องว่างในเงื่อนไขขอบเขต การวิเคราะห์ค่าขอบเขต.
ประเภทของการทดสอบการกลายพันธุ์
In วิศวกรรมซอฟต์แวร์โดยพื้นฐานแล้ว การทดสอบการกลายพันธุ์แบ่งออกเป็นสามประเภท ได้แก่ การกลายพันธุ์ของคำสั่ง การกลายพันธุ์ของค่า และการกลายพันธุ์ของการตัดสินใจ
- การเปลี่ยนแปลงคำสั่ง - ข้อความถูกตัด วาง หรือลบ ส่งผลให้โค้ดบางบรรทัดหายไป
- การเปลี่ยนแปลงค่า – ค่าของพารามิเตอร์หลักและค่าคงที่ต่างๆ จะถูกปรับเปลี่ยน เช่น การเปลี่ยนขอบเขตของลูปหรือค่าเกณฑ์
- การเปลี่ยนแปลงการตัดสินใจ – คำสั่งควบคุมมีการเปลี่ยนแปลง ตัวอย่างเช่น การพลิกกลับping ตัวดำเนินการเชิงสัมพันธ์หรือการปฏิเสธเงื่อนไข
เครื่องมือต่างๆ จัดกลุ่มตัวดำเนินการไว้ภายใต้หัวข้อทั้งสามนี้ ดังนั้นตระกูลที่สร้างตัวกลายพันธุ์ที่รอดชีวิตจะบอกผู้ทดสอบว่าการยืนยันประเภทใดหายไป ตัวกลายพันธุ์การตัดสินใจที่รอดชีวิตมักจะบ่งชี้ถึงสาขาที่ยังไม่ได้ทดสอบ ซึ่งทับซ้อนกับ การทดสอบลูป.
ระบบอัตโนมัติของการทดสอบการกลายพันธุ์
การทดสอบการกลายพันธุ์นั้นใช้เวลานานและซับซ้อนมากหากดำเนินการด้วยตนเอง ดังนั้นจึงควรใช้เครื่องมืออัตโนมัติซึ่งจะช่วยลดต้นทุนได้ด้วย เครื่องมือทดสอบการกลายพันธุ์จะรวบรวมตัวกลายพันธุ์ กำหนดเวลาการทำงาน บันทึกว่าตัวกลายพันธุ์ใดที่ถูกกำจัดในการทดสอบที่ล้มเหลวแต่ละครั้ง และรายงานคะแนน
รายการเครื่องมือที่มีให้ใช้งาน:
- สไตรเกอร์ — เฟรมเวิร์กทดสอบการกลายพันธุ์แบบโอเพนซอร์ส พร้อมเวอร์ชันต่างๆ สำหรับ Javaสคริปต์และ TypeScript (StrykerJS), C# และ .NET (Stryker.NET) และ Scala (Stryker4s)
- PITหรือเขียนอีกแบบว่า PITest — ระบบทดสอบการกลายพันธุ์สำหรับ Java และ JVM ที่เปลี่ยนแปลงไบต์โค้ดที่คอมไพล์แล้วและเชื่อมต่อเข้ากับ Maven และ Gradle สร้างไปพร้อมกัน JUnit.
ทั้งสองอย่างทำงานเป็นขั้นตอนการสร้าง ดังนั้นจึงควรอยู่ในกลุ่มเดียวกัน บูรณาการอย่างต่อเนื่อง ท่อส่งเช่นเดียวกับส่วนอื่นๆ การทดสอบอัตโนมัติ บน
คะแนนการกลายพันธุ์
คะแนนการกลายพันธุ์ถูกกำหนดให้เป็นเปอร์เซ็นต์ของตัวกลายพันธุ์ที่ตายไปจากจำนวนตัวกลายพันธุ์ทั้งหมด
คะแนนการกลายพันธุ์ = (สายพันธุ์กลายพันธุ์ที่ถูกฆ่า / จำนวนสายพันธุ์กลายทั้งหมด) * 100
สูตรคำนวณแสดงอยู่ด้านล่างในรูปแบบที่เครื่องมือส่วนใหญ่รายงาน
กรณีทดสอบจะถือว่ามีการกลายพันธุ์ที่เพียงพอเมื่อคะแนนถึง 100 เปอร์เซ็นต์ ในทางปฏิบัติ ตัวหารจะต้องไม่รวม กลายพันธุ์ที่เทียบเท่า — ตัวกลายพันธุ์ที่มีไวยากรณ์เปลี่ยนแปลงไปซึ่งทำงานเหมือนกับตัวเดิมทุกประการ ดังนั้นจึงไม่มีการทดสอบใดสามารถกำจัดพวกมันได้ เครื่องมือจึงรายงานจำนวนตัวกลายพันธุ์ที่ถูกกำจัดหารด้วยจำนวนตัวกลายพันธุ์ที่ไม่เทียบเท่าที่ถูกกำจัดบวกกับจำนวนตัวกลายพันธุ์ที่ไม่เทียบเท่าที่ยังคงอยู่รอด และปล่อยให้ผู้ทดสอบระบุตัวกลายพันธุ์ที่เทียบเท่ากัน
ผลการทดลองแสดงให้เห็นว่า การทดสอบการกลายพันธุ์เป็นวิธีที่มีประสิทธิภาพในการวัดความเหมาะสมของกรณีทดสอบ ข้อเสียหลักคือ ค่าใช้จ่ายในการสร้างตัวกลายพันธุ์และการดำเนินการทดสอบแต่ละกรณีกับตัวกลายพันธุ์แต่ละตัว
การทดสอบการกลายพันธุ์เทียบกับ Code คุ้มครอง
จุดสูง ครอบคลุมการทดสอบ การทดสอบแบบนี้ไม่สามารถพิสูจน์ได้ว่าการทดสอบนั้นครอบคลุมอย่างมีประสิทธิภาพ การครอบคลุมบรรทัดและการครอบคลุมสาขาจะบันทึกว่าคำสั่งใดทำงาน ไม่ใช่ว่ามีการตรวจสอบอะไรหลังจากนั้น ดังนั้นการทดสอบที่เรียกใช้เมธอดและไม่ตรวจสอบอะไรเลยก็ยังนับว่าครอบคลุมแล้ว การทดสอบแบบ Mutation Testing ช่วยอุดช่องว่างนั้นได้ เพราะตัวกลายพันธุ์จะตายก็ต่อเมื่อการตรวจสอบล้มเหลวจริงๆ เท่านั้น
| แง่มุม | Code ความคุ้มครอง | คะแนนการกลายพันธุ์ |
| มันวัดอะไร | การทดสอบดำเนินการในบรรทัดหรือสาขาใดบ้าง | การทดสอบตรวจพบข้อผิดพลาดที่เกิดจากการฉีดข้อมูลเข้าไป |
| ไวต่อการยืนยัน | ไม่ — การทดสอบที่ไม่มีการยืนยันใดๆ เลยก็ยังเพิ่มความครอบคลุมได้ | ใช่ — สิ่งมีชีวิตกลายพันธุ์จะอยู่รอดได้เมื่อไม่มีข้ออ้างใดล้มเหลว |
| ค่าใช้จ่ายในการวิ่ง | การทดสอบด้วยเครื่องมือวัดหนึ่งครั้ง | ทดสอบหนึ่งครั้งต่อตัวกลายพันธุ์ที่รอดชีวิตแต่ละตัว ซึ่งจนถึงตอนนี้ยังช้าอยู่ |
| การใช้งานทั่วไป | มีการตรวจสอบอย่างรวดเร็วในทุกการคอมมิต | การตรวจสอบเชิงลึกเป็นระยะสำหรับโมดูลที่สำคัญ |
| โหมดความล้มเหลว | ครอบคลุม 100 เปอร์เซ็นต์โดยไม่ต้องมีการตรวจสอบอย่างแท้จริง | สิ่งมีชีวิตกลายพันธุ์ที่เทียบเท่ากันซึ่งไม่มีวันถูกฆ่าได้ |
ตัวชี้วัดทั้งสองนี้เป็นส่วนเสริมซึ่งกันและกัน Coverage ระบุโค้ดที่ไม่เคยถูกเรียกใช้ ส่วน Mutation Score ระบุโค้ดที่ถูกเรียกใช้แต่ไม่เคยถูกตรวจสอบ ทั้งสองอย่างนำไปสู่ข้อมูลเดียวกัน กระบวนการจัดการข้อบกพร่องควบคู่ไปกับมาตรการต่างๆ เช่น ความหนาแน่นของข้อบกพร่อง.
ข้อดีของการทดสอบการกลายพันธุ์
ต่อไปนี้เป็นข้อดีของการทดสอบการกลายพันธุ์:
- นี่เป็นแนวทางที่มีประสิทธิภาพสูงในการครอบคลุมโปรแกรมต้นฉบับได้อย่างครอบคลุม
- เป็นการทดสอบชุดทดสอบเอง ซึ่งไม่มีการทดสอบอื่นใด เทคนิคการทดสอบซอฟต์แวร์ ทำโดยตรง
- การทดสอบการกลายพันธุ์ช่วยให้นักพัฒนาซอฟต์แวร์สามารถตรวจจับข้อผิดพลาดได้อย่างมีประสิทธิภาพ
- วิธีการนี้ช่วยเปิดเผยความกำกวมในซอร์สโค้ด และมีศักยภาพในการเปิดเผยข้อผิดพลาดที่การทำงานแบบปกติไม่สามารถพบได้
- มัลแวร์ที่ยังคงอยู่รอดนั้นสามารถนำไปปฏิบัติได้: แต่ละตัวจะระบุบรรทัดเฉพาะและการเปลี่ยนแปลงเฉพาะที่ชุดโปรแกรมตรวจไม่พบ
- ลูกค้าจะได้รับประโยชน์จากการทดสอบนี้ โดยจะได้รับระบบที่มีความน่าเชื่อถือและเสถียรยิ่งขึ้น
ข้อเสียของการทดสอบการกลายพันธุ์
ในทางกลับกัน การทดสอบการกลายพันธุ์มีข้อเสียดังต่อไปนี้:
- การทดสอบการกลายพันธุ์มีค่าใช้จ่ายสูงและใช้เวลานานมาก เนื่องจากต้องสร้างและคอมไพล์โปรแกรมที่กลายพันธุ์จำนวนมาก
- เนื่องจากเป็นกระบวนการที่ใช้เวลานาน จึงกล่าวได้ว่าการทดสอบนี้ไม่สามารถทำได้หากปราศจากเครื่องมืออัตโนมัติ
- โปรแกรมกลายพันธุ์แต่ละตัวจะได้รับการทดสอบด้วยจำนวนชุดทดสอบเท่ากับโปรแกรมต้นฉบับ ดังนั้นประชากรโปรแกรมกลายพันธุ์จำนวนมากจึงต้องได้รับการทดสอบกับชุดทดสอบทั้งหมด
- สิ่งมีชีวิตกลายพันธุ์ที่เทียบเท่ากันไม่สามารถถูกฆ่าได้ด้วยวิธีการทดสอบใดๆ และการแยกแยะพวกมันออกจากผู้รอดชีวิตที่แท้จริงมักต้องอาศัยการตรวจสอบด้วยตนเอง
- เนื่องจากวิธีการนี้แก้ไขซอร์สโค้ด จึงไม่สามารถนำไปใช้ได้กับ สีดำ Box การทดสอบ.
ควรใช้การทดสอบการกลายพันธุ์เมื่อใด
โครงสร้างต้นทุนข้างต้นแสดงให้เห็นว่า การทดสอบการกลายพันธุ์ (Mutation Testing) แทบจะไม่ถูกนำมาใช้กับโค้ดเบสทั้งหมดในทุกๆ การคอมมิต การทดสอบนี้คุ้มค่าในกรณีที่ข้อผิดพลาดที่ตรวจไม่พบนั้นมีค่าใช้จ่ายสูง และโค้ดที่ทดสอบมีขนาดเล็กพอที่จะเปลี่ยนแปลงได้อย่างรวดเร็ว
- ตรรกะที่สำคัญด้านความปลอดภัยหรือด้านการเงิน — การคำนวณการชำระเงิน กฎระเบียบด้านภาษี และการตรวจสอบการอนุมัติ ซึ่งคำตอบที่ผิดพลาดโดยไม่แจ้งให้ทราบนั้นร้ายแรงกว่าการล่มของระบบเสียอีก
- ห้องสวีทที่มีสัญญาณครอบคลุมสูงผิดปกติ — เมื่ออัตราการครอบคลุมใกล้เคียง 100 เปอร์เซ็นต์ แต่ข้อบกพร่องยังคงหลุดรอดไปได้
- โค้ดเก่ากำลังได้รับการปรับปรุงใหม่ — ผลการกลายพันธุ์จะแสดงให้เห็นว่าการทดสอบที่มีอยู่จะสามารถตรวจจับการถดถอยได้หรือไม่
- ไลบรารีและส่วนประกอบที่ใช้ร่วมกัน — ข้อผิดพลาดในการนำกลับมาใช้ใหม่ ส่วนประกอบ คูณทวีคูณกับผู้โทรทุกราย
- ทีมที่กำลังฝึกซ้อม การพัฒนาที่ขับเคลื่อนด้วยการทดสอบ — คะแนนจะตรวจสอบว่าแบบทดสอบที่เขียนไว้ก่อนหน้านี้ใช้งานได้จริงหรือไม่
โดยทั่วไปแล้ว การทดลองกับต้นแบบที่ใช้แล้วทิ้ง โค้ดที่เชื่อมต่อกันอย่างหลวมๆ หรือโค้ดที่สร้างขึ้นโดยอัตโนมัติโดยไม่มีตรรกะการแยกสาขา หรือชุดทดสอบที่ส่วนใหญ่ทำงานช้า มักไม่คุ้มค่า การทดสอบบูรณาการ ซึ่งใช้เวลาหลายชั่วโมงสำหรับการผ่านเพียงครั้งเดียวอยู่แล้ว
ดังนั้น ทีมส่วนใหญ่จึงกำหนดขอบเขตการทำงานให้เฉพาะไฟล์ที่มีการเปลี่ยนแปลง ตั้งค่าเกณฑ์สำหรับโมดูลที่สำคัญ และปล่อยให้ส่วนที่เหลือดำเนินการต่อไป การทดสอบการถดถอย ห้องสวีทบรรทุกส่วนที่เหลือ วงจรชีวิตการทดสอบซอฟต์แวร์.



