มีทฤษฎีทางคณิตศาสตร์ / การทดสอบซอฟต์แวร์อย่างเป็นทางการหรือไม่?


12

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

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

UPDATE: นอกจากนี้ฉันไม่แน่ใจอย่างสังหรณ์ใจเกี่ยวกับการเชื่อมต่อระหว่างการยืนยันอย่างเป็นทางการกับสิ่งที่ฉันถาม แต่มีการเชื่อมต่อบางอย่างชัดเจน


1
การทดสอบซอฟต์แวร์มีค่ามาก (เช่นการทดสอบหน่วยสู่การปฏิบัติ) แต่ทฤษฎีของมันจะมีช่องโหว่อยู่เสมอ ลองพิจารณาตัวอย่างคลาสสิกนี้double pihole(double value) { return (value - Math.PI) / (value - Math.PI); }ซึ่งฉันได้เรียนรู้จากครูคณิตศาสตร์ของฉัน รหัสนี้มีรูเดียวซึ่งไม่สามารถค้นพบได้โดยอัตโนมัติจากการทดสอบกล่องดำเพียงอย่างเดียว ในวิชาคณิตศาสตร์ไม่มีหลุมดังกล่าว ในแคลคูลัสคุณจะได้รับอนุญาตให้ปิดหลุมหากขีด จำกัด ด้านเดียวเท่ากัน

4
นี่อาจเป็นส่วนหนึ่งของสิ่งที่คุณกำลังมองหา - en.wikipedia.org/wiki/Formal_verification
enderland

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

ฉันคุ้นเคยกับดินแดนแห่งการยืนยันอย่างเป็นทางการผ่านประเภทที่ต้องพึ่งพาและฉันสามารถเห็นด้วยอย่างสมบูรณ์กับ @Dal และ enderland
Erik Kaplun

1
@rwong ฉันคิดว่าคุณพูดถึงความเป็นไปได้ของตัวเศษและส่วนที่เท่ากับศูนย์ ปัญหาส่วนหนึ่งเกิดจากการออกแบบที่ไม่ดีของฟังก์ชั่นนี้ เมื่อพูดถึงการตรวจสอบอย่างเป็นทางการทางคณิตศาสตร์คุณต้องเขียนฟังก์ชั่นของคุณโดยไม่ได้ตั้งใจ แต่ทำตามกฎอย่างเป็นทางการโดยยึดตามชนิดข้อมูลที่ถูกต้อง ในตัวอย่างนี้คุณจะต้องใช้ฟังก์ชั่นการหาร(a,b)=>a/bซึ่งจะต้องมีการขยายด้วยค่าล้นเพื่อให้สามารถแต่งได้อย่างถูกต้อง
Dmitri Zaitsev

คำตอบ:


8

สำหรับหนังสือสำรวจคณิตศาสตร์ที่อยู่เบื้องหลังการทดสอบซอฟต์แวร์ ... หนังสือที่ได้รับคือศิลปะแห่งการวิเคราะห์ประสิทธิภาพของระบบคอมพิวเตอร์: เทคนิคสำหรับการออกแบบการทดลองการวัดการจำลองและการสร้างแบบจำลอง

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


5

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

โหมดการทดสอบ

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

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

การทดสอบสามารถพิสูจน์การมีอยู่ของบั๊กไม่เคยไม่มีบั๊กทั้งหมด การทดสอบจะเพิ่มขอบเขตความถูกต้องของโปรแกรม

รหัสครอบคลุม

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

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

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

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

เมื่อสร้างอินพุตทดสอบโดยใช้ความครอบคลุมของเงื่อนไขควรคำนึงถึงการลัดวงจร ตัวอย่างเช่น,

function foo(A, B) {
  if (A && B) x()
  else        y()
}

จะต้องมีการทดสอบกับfoo(false, whatever), foo(true, false)และfoo(true, true)เต็มน้อยที่สุดเงื่อนไขความคุ้มครองหลาย

หากคุณมีวัตถุที่สามารถอยู่ในหลายสถานะแล้วการทดสอบการเปลี่ยนสถานะทั้งหมดที่คล้ายคลึงกับการควบคุมกระแสดูเหมือนสมเหตุสมผล

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

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

การทดสอบการทำงาน

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

หนึ่งควรทดสอบเพิ่มเติม

  • กรณีขอบlength(""), foo("x"), length(longer_than_INT_MAX),
  • ค่าที่ได้รับอนุญาตโดยภาษา แต่ไม่ได้ตามสัญญาของฟังก์ชั่นlength(null)และ
  • ข้อมูลขยะที่เป็นไปได้length("null byte in \x00 the middle")...

ด้วยตัวเลขนี่หมายถึงการทดสอบ0, ±1, ±x, MAX, MIN, ±∞, NaNและด้วยการเปรียบเทียบจุดลอยตัวทดสอบการลอยตัวสองตัวใกล้เคียง นอกจากนี้ยังสามารถเลือกค่าการทดสอบแบบสุ่มจากคลาสการเทียบเท่า เพื่อความสะดวกในการดีบั๊กมันคุ้มค่าที่จะบันทึกเมล็ดพันธุ์ที่ใช้ ...

การทดสอบที่ใช้งานไม่ได้: การทดสอบโหลดการทดสอบความเครียด

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

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

วิธีการที่ไม่ใช่การทดสอบ

ความคิดเห็น

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

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

การตรวจสอบอย่างเป็นทางการ

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

ค่าคงที่บางอย่างสามารถตรวจสอบได้อย่างชัดเจนโดยใช้assertคำสั่ง


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

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


2
ฉันขอขอบคุณคำตอบที่ซับซ้อน แต่ฉันเกรงว่ามันแทบจะไม่มีส่วนเกี่ยวข้องกับสิ่งที่ฉันถาม :) แต่โชคดีที่โปรแกรมเมอร์เขียนคำว่าstexexchange.com/questions/78675/ … เล็งไปที่.
Erik Kaplun

นี่คือสิ่งที่ดี คุณสามารถแนะนำหนังสือหรือสิ่งต่าง ๆ ได้ไหม?
Marcin

4

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

Test :: Lectrotest

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


2

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

ระบบ AETG: วิธีการทดสอบตามแบบ combinatorial

(มีการอ้างอิงอื่น ๆ อีกมากมาย)


2

มีสมการทางคณิตศาสตร์ที่ใช้อยู่ แต่ขึ้นอยู่กับประเภทของการทดสอบซอฟต์แวร์ที่คุณใช้ ยกตัวอย่างเช่นCritical Fault Assumptionสันนิษฐานว่าความล้มเหลวนั้นเป็นผลิตภัณฑ์ที่มีความผิดพลาดพร้อมกัน 2 ตัวหรือมากกว่า สมการต่อไปนี้คือ: f = 4n + 1 f = ฟังก์ชั่นที่คำนวณจำนวนกรณีทดสอบสำหรับจำนวนตัวแปรที่กำหนด ( n) + 1คือการเพิ่มค่าคงที่ซึ่งตัวแปรทั้งหมดถือว่าค่าเล็กน้อย

การทดสอบอีกประเภทที่ต้องใช้สมการทางคณิตศาสตร์คือการทดสอบความทนทานคือการทดสอบความทนทานหรือความถูกต้องของกรณีทดสอบในกระบวนการทดสอบ ในการทดสอบนี้คุณจะป้อนตัวแปรภายในช่วงอินพุตที่ถูกต้อง (เคสทดสอบแบบคลีน) และตัวแปรอินพุตนอกช่วงอินพุต (เคสทดสอบสกปรก) คุณจะใช้สมการติดตามคณิตศาสตร์: f = 6n + 1 6nบ่งชี้ว่าแต่ละตัวแปรจะต้องสมมติค่าที่แตกต่าง 6 ค่าในขณะที่ค่าอื่นถือว่าค่าที่ระบุ * + 1 * หมายถึงการเพิ่มค่าคงที่ 1

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