1 คะแนน โดย GN⁺ 2024-07-06 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • การทดสอบแบบ property-based เป็นตัวอย่างที่หาได้ยากของงานวิจัยเชิงวิชาการที่ก้าวขึ้นมาเป็นกระแสหลักภายในเวลาไม่ถึง 30 ปี
  • ภายใต้สโลแกน "อย่าเขียนเทสต์ แต่จงสร้างมันขึ้นมา" แนวคิดนี้ได้รับการสนับสนุนจากคอมมูนิตี้ของภาษาโปรแกรมหลากหลายภาษา
  • ในหน้า Wikipedia ของ QuickCheck ซึ่งเดิมเป็นไลบรารีของ Haskell มีการลิสต์การนำไปพัฒนาใหม่ในภาษาอื่นไว้ 57 รายการ

การสำรวจไลบรารีทดสอบแบบ property-based

  • มีการสำรวจไลบรารีทดสอบแบบ property-based ที่ใช้งานมากที่สุดในปัจจุบัน และเปรียบเทียบกับเทคโนโลยีล้ำสมัยเมื่อ 15 ปีก่อน (ปี 2009)
  • ไลบรารีส่วนใหญ่ยังไม่ได้ให้ความสามารถด้าน property-based testing ที่ก้าวหน้าที่สุด

ทำไมไลบรารีทดสอบแบบ property-based จึงอยู่ในสภาพที่น่าเศร้าเช่นนี้?

การทดสอบแบบอิงสถานะและแบบขนานไม่ได้มีประโยชน์เท่าการทดสอบแบบบริสุทธิ์

  • การสร้างแบบจำลองอิงสถานะต้องอาศัยการฝึกฝน
  • มีข้ออ้างว่าซอฟต์แวร์ปิดซอร์สช่วยให้ภาคอุตสาหกรรมนำไปใช้งานได้มากขึ้น

การสร้างแบบจำลองอิงสถานะต้องอาศัยการฝึกฝน

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

มีข้ออ้างว่าซอฟต์แวร์ปิดซอร์สช่วยให้ภาคอุตสาหกรรมนำไปใช้งานได้มากขึ้น

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

สิ่งที่เราทำได้

  • จัดทำ implementation แบบโอเพนซอร์สขนาดสั้นกระชับสำหรับการทดสอบ property-based แบบอิงสถานะและแบบขนาน
  • ทำให้ส่วนของ formal specification ใช้งานได้ง่ายขึ้น เพื่อลดความจำเป็นในการฝึกฝนนักพัฒนา

สรุปการทดสอบแบบ property-based แบบบริสุทธิ์

  • การทดสอบฟังก์ชันหรือฟีเจอร์ใหม่ถือเป็นแนวปฏิบัติที่ดี
  • ตัวอย่างเช่น หากเขียนฟังก์ชัน reverse สำหรับกลับลำดับ linked list ก็ควรทดสอบกับลิสต์บางแบบ เช่น ลิสต์ว่าง
  • การสร้างอินพุตแบบสุ่มคือความสามารถหลักของการทดสอบแบบ property-based
  • แนวคิดคืออินพุตแบบสุ่มจะสามารถค้นพบ corner case ได้ในที่สุด

การทดสอบ property-based แบบอิงสถานะ

  • เมื่อต้องทดสอบคอมโพเนนต์ที่มีสถานะ อินพุตเดียวกันจะไม่ได้ให้เอาต์พุตเดียวกันเสมอไป
  • ในการทดสอบแบบอิงสถานะ จะสร้างลำดับของอินพุตเพื่อทดสอบว่าระบบเปลี่ยนแปลงไปอย่างไรเมื่อเวลาผ่านไป
  • ใช้ reference implementation (โมเดล) ในหน่วยความจำเพื่ออธิบายสถานะอย่างชัดเจน

ตัวอย่าง: ตัวนับ

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

การทดสอบ property-based แบบขนาน

  • การทดสอบแบบขนานนำโมเดลของการทดสอบแบบอิงสถานะกลับมาใช้เพื่อตรวจจับ race condition
  • การทดสอบแบบขนานใช้โมเดล state machine แบบลำดับเพื่อทำการทดสอบแบบขนานผ่าน linearizability

บทสรุปและงานในอนาคต

  • เพื่อปรับปรุงสถานะของ property-based testing จำเป็นต้องมี implementation แบบโอเพนซอร์สและทำให้ formal specification ใช้งานได้ง่ายขึ้น

ความเห็นของ GN⁺

  • บทความนี้อธิบายประวัติและสถานะปัจจุบันของ property-based testing ได้อย่างดี
  • บทความเน้นย้ำความสำคัญของการทดสอบแบบอิงสถานะและแบบขนาน พร้อมเสนอความจำเป็นของ implementation แบบโอเพนซอร์ส
  • บทความเสนอวิธีทำให้ property-based testing เข้าถึงได้ง่ายขึ้น
  • โปรเจ็กต์อื่นที่มีความสามารถคล้ายกัน ได้แก่ Hypothesis (Python) และ PropEr (Erlang)
  • บทความย้ำว่าการนำเทคโนโลยีใหม่หรือโอเพนซอร์สมาใช้จำเป็นต้องมีการฝึกอบรมและการสนับสนุน

1 ความคิดเห็น

 
GN⁺ 2024-07-06
ความเห็นจาก Hacker News
  • มีประสบการณ์ที่ดีกับการใช้ clojure.spec.alpha และ test.check
    • เลิกใช้ hypothesis ของ Python เพราะจัดการชุดข้อมูลขนาดใหญ่ไม่ได้
  • ภาษา Go รองรับการทำ coverage-based fuzzing ได้ดี
    • สามารถได้ผลลัพธ์คล้ายการทดสอบแบบ property-based ผ่านการทดสอบแบบ fuzzing และการตรวจสอบ invariants
  • ข้อกำหนดให้งานวิจัยต้องทำซ้ำได้ด้วยเครื่องมือโอเพนซอร์สอาจทำให้ข้อมูลที่มีประโยชน์สูญหายไป
  • มักเขียนการทดสอบแบบ property-based ที่อิงสถานะด้วย proptest ของ Rust
    • การทดสอบแบบขนานมีประโยชน์ในบางครั้ง แต่การรันหลายเทสต์แบบขนานอาจง่ายกว่า
  • เคยอ่านงานวิจัยของ Quviq QuickCheck แต่การเขียนการทดสอบแบบอิงสถานะด้วยตัวเองอาจดีกว่า
    • StateModel ต้องใช้โค้ดเฟรมเวิร์กเพิ่มเติม จึงไม่มีประสิทธิภาพนัก
  • นอกจากด้าน state machine และความเป็นขนานแล้ว การทดสอบแบบ property-based ที่อิง coverage อาจสร้างผลกระทบได้มากกว่า
    • สิ่งสำคัญคือการคงความสามารถในการย่อเคสอัตโนมัติไว้ พร้อมกับรักษา invariants ทั้งหมดระหว่างการสร้างค่า
    • แนวทาง "internal shrinking" ของ Hypothesis มีประสิทธิภาพที่สุด
  • ใน Clojure ก็มีไลบรารี QuickCheck แบบอิงสถานะเช่นกัน
    • การทดสอบแบบขนานยังไม่ใช่ปัญหาใหญ่ในตอนนี้
  • หากสามารถเขียนการทดสอบที่เข้มงวดได้ การรวม property-based testing เข้ากับระบบชนิดข้อมูลอาจดีกว่า
    • "smoke test" แบบง่ายใช้ค่าป้อนเข้าแบบสุ่มจะทำได้ง่ายกว่า
  • ยังมี QuickCheck Mini ซึ่งเป็นเวอร์ชันฟรีของ QuviQ Erlang QuickCheck
  • สงสัยว่าใน JavaScript มีไลบรารี property-based testing ที่สามารถสร้างค่าสุ่มซึ่งไม่ตรงตามเงื่อนไขบางอย่างได้หรือไม่