Image

ข้าสามารถเรียกวิญญาณจากห้วงลึกอันกว้างใหญ่ได้
ข้าก็ทำได้ เช่นเดียวกับใคร ๆ แต่พวกมันจะมาเมื่อเราเรียกหรือ?
SHAKESPEARE, KING HENRY IV , Part I

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

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

Designing the Bugs Out (การออกแบบให้ปราศจากบั๊ก)

Bug-proofing the definition (การทําคําจํากัดความให้กันบั๊ก). บั๊กที่ร้ายกาจและซ่อนเร้นที่สุดคือบั๊กระบบที่เกิดจากสมมติฐานที่ไม่ตรงกันระหว่างผู้เขียน component ต่าง ๆ แนวทางเรื่องความสอดคล้องของแนวคิด (conceptual integrity) ที่กล่าวถึงใน Chapters 4 , 5 , และ 6 นั้นจัดการกับปัญหาเหล่านี้โดยตรง กล่าวโดยย่อคือ ความสอดคล้องของแนวคิดของผลิตภัณฑ์ไม่เพียงทําให้ใช้งานง่ายขึ้นเท่านั้น แต่ยังทําให้สร้างได้ง่ายขึ้นและมีบั๊กน้อยลงด้วย

เช่นเดียวกับความพยายามทางสถาปัตยกรรมที่ละเอียดถี่ถ้วนซึ่งเป็นผลมาจากแนวทางดังกล่าว V. A. Vyssotsky จาก Safeguard Project ของ Bell Telephone Laboratories กล่าวว่า "งานสําคัญคือการทําให้ผลิตภัณฑ์ถูกกําหนดให้ชัดเจน ความล้มเหลวหลายต่อหลายครั้งเกี่ยวข้องกับสิ่งที่ถูกกําหนดไม่ชัดเจน" [1] การกําหนดฟังก์ชันอย่างรอบคอบ การกําหนดข้อกําหนดอย่างละเอียด และการกําจัดฟังก์ชันที่ไม่จําเป็นและเทคนิคที่เกินความจําเป็นอย่างมีวินัย ล้วนช่วยลดจํานวนบั๊กระบบที่ต้องตามหาทีหลัง

Testing the specification (การทดสอบสเปก). ก่อนที่จะมีโค้ดใด ๆ เลย สเปกจะต้องถูกส่งให้ทีมทดสอบภายนอกเพื่อตรวจสอบความสมบูรณ์และความชัดเจน ดังที่ Vyssotsky กล่าวว่า นักพัฒนาเองไม่สามารถทําสิ่งนี้ได้: "พวกเขาจะไม่บอกคุณว่าพวกเขาไม่เข้าใจ พวกเขาจะหาทางผ่านช่องโหว่และความคลุมเครือไปได้อย่างมีความสุข"

Top-down design (การออกแบบจากบนลงล่าง). ในบทความที่ชัดเจนมากเมื่อปี 1971 Niklaus Wirth ได้ทําให้กระบวนการออกแบบที่โปรแกรมเมอร์ชั้นนําใช้กันมานานหลายปีเป็นทางการ [2] ยิ่งไปกว่านั้น แนวคิดของเขาแม้จะกล่าวถึงการออกแบบโปรแกรม แต่ก็ใช้ได้กับการออกแบบระบบที่ซับซ้อนของหลาย ๆ โปรแกรมโดยสมบูรณ์ การแบ่งการสร้างระบบออกเป็นสถาปัตยกรรม (architecture), การนําไปใช้งาน (implementation), และการทําให้เกิดขึ้นจริง (realization) เป็นการรวบรวมแนวคิดเหล่านี้ นอกจากนี้ แต่ละส่วนของสถาปัตยกรรม การนําไปใช้งาน และการทําให้เกิดขึ้นจริง สามารถทําได้ดีที่สุดด้วยวิธีการแบบบนลงล่าง

โดยย่อ กระบวนการของ Wirth คือการมองการออกแบบเป็นลําดับของ ขั้นตอนการปรับแต่ง (refinement steps) ขั้นแรก เราจะร่างคําจํากัดความคร่าว ๆ ของงานและวิธีการแก้ปัญหาแบบคร่าว ๆ ที่บรรลุผลลัพธ์หลัก จากนั้นเราจะพิจารณาคําจํากัดความให้ละเอียดขึ้นเพื่อดูว่าผลลัพธ์แตกต่างจากสิ่งที่ต้องการอย่างไร และแยกขั้นตอนใหญ่ของคําตอบออกเป็นขั้นตอนย่อย ๆ การปรับแต่งคําจํากัดความของงานแต่ละครั้งจะกลายเป็นการปรับแต่งอัลกอริทึมของคําตอบ และแต่ละครั้งอาจมาพร้อมกับการปรับแต่งการแสดงข้อมูล

จากกระบวนการนี้ เราจะระบุ โมดูล ของคําตอบหรือข้อมูล ซึ่งการปรับแต่งต่อไปสามารถดําเนินการได้โดยอิสระจากงานอื่น ๆ ระดับของ modularity นี้จะเป็นตัวกําหนดความสามารถในการปรับตัวและการเปลี่ยนแปลงของโปรแกรม

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

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

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

ผมเชื่อว่าการออกแบบจากบนลงล่าง (top-down design) คือการทําให้การเขียนโปรแกรมเป็นทางการที่สําคัญที่สุดในทศวรรษนี้

Structured programming (การเขียนโปรแกรมแบบมีโครงสร้าง). ชุดแนวคิดใหม่อีกชุดหนึ่งสําหรับการออกแบบให้ปราศจากบั๊กส่วนใหญ่มาจาก Dijkstra [3] และสร้างขึ้นบนพื้นฐานทางทฤษฎีโดย Böhm และ Jacopini [4]

โดยพื้นฐานแล้วแนวทางนี้คือการออกแบบโปรแกรมที่มีโครงสร้างควบคุมประกอบด้วยลูปที่กําหนดโดยคําสั่งเช่น DO WHILE และส่วนของเงื่อนไขที่แบ่งเป็นกลุ่มคําสั่งที่คร่อมด้วยวงเล็บและมีเงื่อนไขด้วย IF . . . THEN . . . ELSE Böhm และ Jacopini แสดงให้เห็นว่าโครงสร้างเหล่านี้เพียงพอในทางทฤษฎี Dijkstra โต้แย้งว่าทางเลือกอื่นคือการแตกกิ่งแบบไม่มีข้อจํากัดผ่าน GO TO ซึ่งสร้างโครงสร้างที่เอื้อต่อข้อผิดพลาดทางตรรกะ

แนวคิดพื้นฐานนั้นถูกต้องอย่างแน่นอน มีการวิพากษ์วิจารณ์มากมาย และโครงสร้างควบคุมเพิ่มเติม เช่น การแตกกิ่งแบบ n-way (CASE statement ที่เรียกกัน) สําหรับแยกแยะเงื่อนไขหลายอย่าง และการขัดข้องฉุกเฉิน (GO TO ABNORMAL END) ก็มีประโยชน์มาก นอกจากนี้ บางคนก็กลายเป็นพวกเคร่งครัดในการหลีกเลี่ยง GO TO ทั้งหมด ซึ่งดูจะมากเกินไป

จุดสําคัญ และเป็นจุดที่สําคัญยิ่งต่อการสร้างโปรแกรมที่ปราศจากบั๊ก คือการที่เราต้องคิดถึงโครงสร้างควบคุมของระบบในฐานะโครงสร้างควบคุม ไม่ใช่เป็นคําสั่ง branch แต่ละคําสั่ง วิธีคิดแบบนี้คือก้าวสําคัญไปข้างหน้า

Component Debugging (การดีบัก Component)

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

On-machine debugging (การดีบักบนเครื่อง). เครื่องรุ่นแรกมีอุปกรณ์รับเข้า-ส่งออกที่ค่อนข้างแย่ และมีความหน่วงในการรับเข้า-ส่งออกนาน โดยปกติ เครื่องจะอ่านและเขียนเทปกระดาษหรือเทปแม่เหล็ก และใช้สิ่งอํานวยความสะดวกแบบ off-line สําหรับการเตรียมเทปและการพิมพ์ ทําให้การรับเข้า-ส่งออกแบบเทปไม่สะดวกอย่างยิ่งสําหรับการดีบัก ดังนั้นจึงใช้คอนโซลแทน การดีบักจึงถูกออกแบบให้ทําการทดลองได้มากที่สุดเท่าที่เป็นไปได้ในแต่ละ session บนเครื่อง

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

บาปร้ายแรงที่สุดคือการกด START อย่างองอาจโดยไม่แบ่งโปรแกรมออกเป็นส่วนทดสอบที่มีการวางแผนจุดหยุดไว้

Memory dumps (การถ่ายหน่วยความจํา). การดีบักบนเครื่องมีประสิทธิภาพมาก ใน session สองชั่วโมง เราอาจได้ทดลองประมาณสิบครั้ง แต่คอมพิวเตอร์หายากมากและมีราคาแพงมาก และความคิดที่ว่าเวลาเครื่องจะต้องสูญเปล่าก็เป็นเรื่องน่าหวาดหวั่น

ดังนั้นเมื่อมีเครื่องพิมพ์ความเร็วสูงเชื่อมต่อแบบ on-line เทคนิคก็เปลี่ยนไป เราจะรันโปรแกรมจนกว่าการตรวจสอบจะล้มเหลว จากนั้นก็ถ่ายหน่วยความจําทั้งหมดออกมา แล้วเริ่มงานโต๊ะที่เหน็ดเหนื่อย ตรวจสอบเนื้อหาในแต่ละตําแหน่งหน่วยความจํา เวลาที่ใช้บนโต๊ะก็ไม่ต่างจากการดีบักบนเครื่องมากนัก แต่มันเกิดขึ้นหลังจากการทดสอบรัน ในการถอดรหัส แทนที่จะเกิดขึ้นก่อนหน้าในการวางแผน การดีบักสําหรับผู้ใช้แต่ละคนใช้เวลานานกว่ามาก เพราะการทดสอบแต่ละครั้งขึ้นอยู่กับรอบเวลาของ batch turnaround อย่างไรก็ตาม กระบวนการทั้งหมดถูกออกแบบมาเพื่อลดการใช้เวลาเครื่องและให้บริการโปรแกรมเมอร์ให้ได้มากที่สุด

Snapshots (การถ่ายภาพนิ่ง). เครื่องที่ใช้เทคนิคการถ่ายหน่วยความจํามีหน่วยความจํา 2000–4000 คํา หรือ 8K ถึง 16K ไบต์ แต่ขนาดหน่วยความจําเพิ่มขึ้นอย่างก้าวกระโดด และการถ่ายหน่วยความจําทั้งหมดก็ทําไม่ได้ในทางปฏิบัติ ดังนั้นผู้คนจึงพัฒนาเทคนิคสําหรับการถ่ายแบบเลือกสรร การติดตามแบบเลือกสรร และการแทรก snapshot ลงในโปรแกรม OS/360 TESTRAN เป็นเครื่องมือปลายทางในทิศทางนี้ ที่ให้เราแทรก snapshot ลงในโปรแกรมโดยไม่ต้อง reassembly หรือ recompilation

Interactive debugging (การดีบักแบบโต้ตอบ). ในปี 1959 Codd และเพื่อนร่วมงานของเขา [5] และ Strachey [6] ต่างก็รายงานงานที่มุ่งสู่การดีบักแบบ time-shared ซึ่งเป็นวิธีที่ให้ทั้งการตอบสนองทันทีของการดีบักบนเครื่องและการใช้เครื่องอย่างมีประสิทธิภาพของการดีบักแบบ batch คอมพิวเตอร์จะมีหลายโปรแกรมในหน่วยความจําพร้อมสําหรับการเรียกใช้ terminal ที่ควบคุมโดยโปรแกรมเท่านั้นจะเชื่อมโยงกับแต่ละโปรแกรมที่กําลังดีบัก การดีบักจะอยู่ภายใต้การควบคุมของ supervisory program เมื่อโปรแกรมเมอร์ที่ terminal หยุดโปรแกรมเพื่อตรวจสอบความคืบหน้าหรือเปลี่ยนแปลง ตัว supervisor จะรันโปรแกรมอื่น ทําให้เครื่องไม่ว่าง

ระบบ multiprogramming ของ Codd ได้รับการพัฒนา แต่เน้นที่การเพิ่มปริมาณงานโดยการใช้ input-output อย่างมีประสิทธิภาพ และการดีบักแบบโต้ตอบก็ไม่ได้ถูกนํามาใช้ แนวคิดของ Strachey ได้รับการปรับปรุงและนํามาใช้ในปี 1963 ในระบบทดลองสําหรับ 7090 โดย Corbatò และเพื่อนร่วมงานที่ MIT [7] การพัฒนานี้นําไปสู่ MULTICS, TSS และระบบ time-sharing อื่น ๆ ในปัจจุบัน

ความแตกต่างหลักที่ผู้ใช้รับรู้ระหว่างการดีบักบนเครื่องในยุคแรกกับการดีบักแบบโต้ตอบในปัจจุบันคือสิ่งอํานวยความสะดวกที่เกิดจากการมี supervisory program และตัวแปลภาษาที่เกี่ยวข้อง เราสามารถโปรแกรมและดีบักในภาษาระดับสูงได้ สิ่งอํานวยความสะดวกในการแก้ไขที่มีประสิทธิภาพทําให้การเปลี่ยนแปลงและการถ่าย snapshot ทําได้ง่าย

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

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

ผมพบว่าการใช้ระบบ terminal ที่ดีต้องใช้เวลาสองชั่วโมงที่โต๊ะสําหรับทุก ๆ สองชั่วโมงบน terminal ครึ่งหนึ่งของเวลานี้ใช้ไปกับการเก็บกวาดหลัง session ที่แล้ว: อัปเดตบันทึกการดีบัก จัดเก็บรายการโปรแกรมที่อัปเดตแล้วในสมุดบันทึกของระบบ อธิบายปรากฏการณ์แปลก ๆ อีกครึ่งหนึ่งใช้ไปกับการเตรียม: วางแผนการเปลี่ยนแปลงและการปรับปรุง และออกแบบการทดสอบโดยละเอียดสําหรับครั้งถัดไป หากไม่มีการวางแผนเช่นนี้ ก็ยากที่จะรักษาประสิทธิภาพการทํางานไว้นานถึงสองชั่วโมง หากไม่มีการเก็บกวาดหลัง session ก็ยากที่จะรักษาลําดับของ session บน terminal ให้เป็นระบบและก้าวไปข้างหน้า

Test cases (กรณีทดสอบ). สําหรับการออกแบบขั้นตอนการดีบักและกรณีทดสอบที่แท้จริงนั้น Gruenberger มีบทความที่ดีเป็นพิเศษ [9] และยังมีบทความสั้นกว่าในตํารามาตรฐานอื่น ๆ [10] , [11]

System Debugging (การดีบักระบบ)

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

Use debugged components (ใช้ component ที่ดีบักแล้ว). สามัญสํานึก ถ้าไม่ใช่แนวปฏิบัติทั่วไป กําหนดว่าเราควรเริ่มดีบักระบบต่อเมื่อแต่ละส่วนดูเหมือนจะทํางานได้แล้ว

แนวปฏิบัติทั่วไปเบี่ยงเบนไปจากนี้ในสองทาง ทางแรกคือแนวทาง "ประกอบเข้าด้วยกันแล้วลอง" ดูเหมือนจะตั้งอยู่บนแนวคิดที่ว่าจะมีบั๊กระบบ (เช่น บั๊ก interface) เพิ่มเติมจากบั๊กของ component ยิ่งประกอบชิ้นส่วนเร็วเท่าไหร่ บั๊กระบบก็จะปรากฏเร็วเท่านั้น แนวคิดที่ละเอียดน้อยกว่าคือการใช้ชิ้นส่วนทดสอบซึ่งกันและกัน จะได้หลีกเลี่ยงการสร้าง test scaffolding มากมาย ทั้งสองอย่างนี้เห็นได้ชัดว่าจริง แต่ประสบการณ์แสดงว่ามันไม่ใช่ความจริงทั้งหมด การใช้ component ที่สะอาดและดีบักแล้วจะช่วยประหยัดเวลาในการทดสอบระบบได้มากกว่าที่เสียไปกับการทํา scaffolding และการทดสอบ component อย่างละเอียด

ที่ละเอียดอ่อนกว่าเล็กน้อยคือแนวทาง "documented bug" (บั๊กที่บันทึกไว้) แนวทางนี้บอกว่า component พร้อมเข้าสู่การทดสอบระบบเมื่อข้อบกพร่องทั้งหมดถูก ค้นพบ ก่อนเวลาที่ทั้งหมดจะถูก แก้ไข เสียอีก จากนั้นในการทดสอบระบบ ตามทฤษฎีแล้ว เราจะรู้ถึงผลกระทบที่คาดไว้ของบั๊กเหล่านี้และสามารถละเว้นผลกระทบเหล่านั้น โดยมุ่งเน้นที่ปรากฏการณ์ใหม่

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

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

รูปแบบหนึ่งของ scaffolding คือ dummy component ซึ่งประกอบด้วยเฉพาะ interface และอาจมีข้อมูลปลอมหรือกรณีทดสอบเล็ก ๆ ยกตัวอย่างเช่น ระบบอาจมีโปรแกรมเรียงลําดับที่ยังไม่เสร็จ ส่วนอื่น ๆ ที่ต้องต่อกับมันสามารถทดสอบได้โดยใช้ dummy program ที่เพียงแค่อ่านและตรวจสอบรูปแบบของข้อมูลนําเข้า แล้วพ่นข้อมูลที่ไม่มีความหมายแต่เรียงลําดับแล้วออกมา

อีกรูปแบบหนึ่งคือ miniature file บั๊กระบบที่พบบ่อยมากคือการเข้าใจผิดเกี่ยวกับรูปแบบของไฟล์เทปและดิสก์ ดังนั้นจึงคุ้มค่าที่จะสร้างไฟล์เล็ก ๆ ที่มีเพียงไม่กี่ record ทั่วไป แต่มีคําอธิบาย pointer ฯลฯ ครบถ้วน

กรณีจํากัดของ miniature file คือ dummy file ซึ่งจริง ๆ แล้วไม่มีอยู่จริงเลย OS/360’s Job Control Language มีสิ่งอํานวยความสะดวกดังกล่าว และมีประโยชน์อย่างยิ่งสําหรับการดีบัก component

scaffolding อีกรูปแบบหนึ่งคือ auxiliary programs เครื่องกําเนิดข้อมูลทดสอบ รายงานการวิเคราะห์พิเศษ ตัววิเคราะห์ตาราง cross-reference ล้วนเป็นตัวอย่างของเครื่องมือเฉพาะทางที่เราอาจต้องการสร้าง [13]

Control changes (ควบคุมการเปลี่ยนแปลง). การควบคุมอย่างเข้มงวดระหว่างการทดสอบเป็นหนึ่งในเทคนิคที่น่าประทับใจของการดีบักฮาร์ดแวร์ และมันใช้ได้กับระบบซอฟต์แวร์เช่นกัน

อย่างแรก ต้องมีคนรับผิดชอบ เขาเท่านั้นที่ต้องอนุญาตให้เปลี่ยน component หรือเปลี่ยนเวอร์ชันหนึ่งเป็นอีกเวอร์ชันหนึ่ง

จากนั้น ดังที่ได้กล่าวไว้แล้ว ต้องมีสําเนาที่ถูกควบคุมของระบบ: สําเนาที่ล็อกไว้หนึ่งชุดของเวอร์ชันล่าสุด ใช้สําหรับการทดสอบ component สําเนาที่อยู่ระหว่างการทดสอบหนึ่งชุดซึ่งกําลังติดตั้งการแก้ไข และ playpen copy ที่แต่ละคนสามารถทํางานกับ component ของตนเองได้ ทั้งการแก้ไขและการขยาย

ใน System/360 engineering models เราจะเห็นสายลวดสีม่วงเป็นครั้งคราวปะปนกับสายลวดสีเหลืองทั่วไป เมื่อพบบั๊ก จะทําสองอย่าง การแก้ไขด่วนถูกคิดค้นและติดตั้งบนระบบเพื่อให้การทดสอบดําเนินต่อไปได้ การเปลี่ยนแปลงนี้ถูกใส่ด้วยลวดสีม่วง เพื่อให้เห็นเด่นชัด และถูกบันทึกใน log ในขณะเดียวกัน ก็เตรียมเอกสารการเปลี่ยนแปลงอย่างเป็นทางการและส่งเข้าสู่ระบบ design automation ในที่สุดก็นําไปสู่แบบและรายการลวดที่อัปเดต และแผงหลังใหม่ที่การเปลี่ยนแปลงถูกนําไปใช้ในวงจรพิมพ์หรือลวดสีเหลือง ตอนนี้แบบจําลองทางกายภาพและเอกสารก็กลับมาตรงกันอีกครั้ง และลวดสีม่วงก็หายไป

ซอฟต์แวร์ต้องการเทคนิคลวดสีม่วง (purple-wire technique) และมันต้องการการควบคุมที่เข้มงวดและความเคารพอย่างลึกซึ้งต่อเอกสารซึ่งท้ายที่สุดแล้วคือผลผลิต ส่วนผสมที่สําคัญของเทคนิคดังกล่าวคือการบันทึกการเปลี่ยนแปลงทั้งหมดในสมุดบันทึก และความแตกต่างที่ปรากฏชัดในซอร์สโค้ดระหว่างแผ่นแปะด่วน (quick patches) กับการแก้ไขที่คิดอย่างถี่ถ้วน ทดสอบแล้ว และมีเอกสารประกอบ

Add one component at a time (เพิ่ม component ทีละตัว). หลักการนี้ก็ชัดเจนเช่นกัน แต่การมองโลกในแง่ดีและความเกียจคร้านยั่วยวนให้เราละเมิดมัน การทําเช่นนี้ต้องใช้ dummy และ scaffolding อื่น ๆ และนั่นต้องทํางานหนัก และบางที งานทั้งหมดนั้นอาจไม่จําเป็น? บางทีอาจไม่มีบั๊ก?

ไม่! จงต่อต้านการล่อลวง! นั่นคือสิ่งที่การทดสอบระบบอย่างเป็นระบบเป็นเรื่องเกี่ยวกับ เราต้องสมมติว่าจะมีบั๊กมากมาย และวางแผนกระบวนการที่เป็นระเบียบเพื่อกําจัดมันออกมา

สังเกตว่าเราต้องมีกรณีทดสอบที่ละเอียดถี่ถ้วน โดยทดสอบระบบย่อยหลังจากเพิ่มชิ้นส่วนใหม่แต่ละชิ้น และกรณีทดสอบเก่าที่รันสําเร็จบนผลรวมย่อยครั้งก่อน ต้องนํามารันใหม่บนระบบใหม่เพื่อทดสอบการถดถอยของระบบ (system regression)

Quantize updates (ทําให้การอัปเดตเป็นควอนตัม). เมื่อระบบเริ่มทํางาน ผู้สร้าง component จะปรากฏตัวเป็นครั้งคราว พร้อมกับเวอร์ชันใหม่ล่าสุดของชิ้นงานของพวกเขา—ที่เร็วกว่า เล็กกว่า สมบูรณ์กว่า หรือคาดว่ามีบั๊กน้อยกว่า การแทนที่ component ที่ทํางานได้ด้วยเวอร์ชันใหม่ต้องใช้ขั้นตอนการทดสอบอย่างเป็นระบบเช่นเดียวกับการเพิ่ม component ใหม่ แม้ว่าควรใช้เวลาน้อยกว่า เพราะมักจะมีกรณีทดสอบที่สมบูรณ์และมีประสิทธิภาพกว่าพร้อมใช้

แต่ละทีมที่สร้าง component อื่นได้ใช้เวอร์ชันที่ทดสอบล่าสุดของระบบรวมเป็น test bed สําหรับดีบักชิ้นงานของพวกเขา งานของพวกเขาจะถูกขัดจังหวะเมื่อ test bed นั้นเปลี่ยนไปภายใต้พวกเขา แน่นอนว่ามันต้องเปลี่ยน แต่มันต้องเปลี่ยนแบบ quantized (เป็นควอนตัม) จากนั้นผู้ใช้แต่ละคนจะมีช่วงเวลาของความมั่นคงที่ productive สลับกับช่วงเวลาของการเปลี่ยนแปลง test bed วิธีนี้ดูเหมือนจะรบกวนน้อยกว่าการเปลี่ยนแปลงที่เกิดขึ้นอย่างต่อเนื่อง

Lehman และ Belady นําเสนอหลักฐานว่าควอนตัมควรมีขนาดใหญ่มากและห่างกันมาก หรือไม่ก็เล็กมากและถี่มาก [14] กลยุทธ์หลังมีความเสี่ยงต่อความไม่เสถียรมากกว่า ตามแบบจําลองของพวกเขา ประสบการณ์ของผมยืนยันสิ่งนี้: ผมจะไม่เสี่ยงใช้กลยุทธ์นั้นในทางปฏิบัติ

การเปลี่ยนแปลงแบบ quantized รองรับเทคนิคลวดสีม่วงได้อย่างลงตัว แผ่นแปะด่วนจะคงอยู่จนกว่าจะมีการปล่อย component เวอร์ชันปกติครั้งถัดไป ซึ่งควรรวมการแก้ไขในรูปแบบที่ทดสอบแล้วและมีเอกสารประกอบ