เครื่องมือสร้างการทดสอบแบบใหม่ของ Meta ที่ใช้ LLM
(read.engineerscodex.com)เครื่องมือสร้างการทดสอบแบบใหม่ของ Meta ที่ใช้ LLM เปิดโอกาสให้เห็นอนาคตของการพัฒนา
- Meta เผยแพร่บทความวิจัยชื่อ "Automated Unit Test Improvement using Large Language Models at Meta"
- บทความนี้แสดงให้เห็นวิธีใช้ AI เพื่อเร่งความเร็วในการพัฒนาและลดบั๊กของซอฟต์แวร์
- ด้วยการผสาน LLM เข้ากับเวิร์กโฟลว์ของนักพัฒนา ระบบสามารถเสนอแนวทางปรับปรุงซอฟต์แวร์ที่แม่นยำและครบถ้วนเพื่อเพิ่ม code coverage ในปัจจุบัน
ประเด็นสำคัญ
- TestGen-LLM ใช้แนวทาง 'Assured LLM-based Software Engineering' (Assured LLMSE)
- ใช้วิธีแบบ ensemble โดยสร้างข้อเสนอการปรับปรุงโค้ดจาก LLM หลายตัว หลายพรอมป์ต์ และไฮเปอร์พารามิเตอร์หลายชุด แล้วคัดเลือกข้อเสนอที่ดีที่สุด
- TestGen-LLM ถูกออกแบบมาโดยเฉพาะเพื่อปรับปรุงการทดสอบที่มนุษย์เขียนไว้เดิม
สถิติ
- ในการประเมินผลิตภัณฑ์ Reels และ Stories ของ Instagram นั้น 75% ของ test case ที่ TestGen-LLM สร้างขึ้นสามารถ build ได้ตามปกติ, 57% ผ่านการทดสอบได้อย่างเชื่อถือได้ และ 25% เพิ่ม coverage ได้
- TestGen-LLM สามารถปรับปรุงได้ 10% ของทุกคลาสที่นำไปใช้ และนักพัฒนายอมรับข้อเสนอการปรับปรุงการทดสอบ 73% เพื่อนำไปใช้ใน production
- ใน "test-a-thon" ที่วิศวกรของ Meta ใช้สร้างการทดสอบเพื่อเพิ่ม test coverage ของ Instagram ค่ามัธยฐานของจำนวนบรรทัดโค้ดที่การทดสอบจาก TestGen-LLM เพิ่มเข้ามาคือ 2.5
อินไซต์ที่นำไปใช้ได้จริง
- นี่เป็นตัวอย่างที่ดีของการใช้ LLM เพื่อเพิ่มประสิทธิภาพการพัฒนาและความน่าเชื่อถือของซอฟต์แวร์อย่างมีประสิทธิผล
- คุณค่าที่แท้จริงของ LLM อยู่ที่การค้นหาและจับ edge case ที่คาดไม่ถึง
- การนำ LLM ไปใช้ใน production จำเป็นต้องมี orchestration, pipeline และการประมวลผล
วิธีการทำงานของ TestGen-LLM
- TestGen-LLM ใช้ชุด semantic filters กับโซลูชันตัวเลือกที่สร้างโดย LLM ภายในของ Meta เพื่อเก็บไว้เฉพาะการทดสอบที่มีคุณค่ามากที่สุด
- ตัวกรอง 1: ความสามารถในการ build, ตัวกรอง 2: การรัน (การผ่านการทดสอบหรือไม่), ตัวกรอง 3: ความไม่เสถียร, ตัวกรอง 4: การปรับปรุง coverage
- ตัวกรองในการประมวลผลเหล่านี้ช่วยรับประกันการปรับปรุงของ test suite
บทสรุป
- บทความวิจัยนี้เป็นวิธีที่ดีในการติดตามความก้าวหน้าของ LLM ในพื้นที่ด้าน software reliability ซึ่งนักพัฒนาจำนวนมากก็ใช้ LLM อยู่แล้ว
- LLM จะสามารถค้นหาบั๊กและทดสอบในระบบซอฟต์แวร์ที่ซับซ้อนมากขึ้นเรื่อย ๆ
ความเห็นของ GN⁺
- บทความนี้มอบมุมมองที่น่าสนใจเกี่ยวกับผลกระทบที่ปัญญาประดิษฐ์อาจมีต่ออนาคตของการพัฒนาซอฟต์แวร์
- เครื่องมืออย่าง TestGen-LLM สามารถช่วยอย่างมากในการทำงานของนักพัฒนาให้เป็นอัตโนมัติและเพิ่มประสิทธิภาพ
- ความก้าวหน้าของเทคโนโลยีลักษณะนี้กำลังมุ่งไปสู่การลดความซับซ้อนของการพัฒนาซอฟต์แวร์ ยกระดับคุณภาพ และประหยัดเวลาของนักพัฒนา
1 ความคิดเห็น
ความคิดเห็นบน Hacker News
กระแสที่อยากใช้ LLM กับการเขียนโค้ดทดสอบก่อนการลงมือ implement น่าสนใจดี
อาจเพราะทำ TDD มามากไปหน่อย แต่ผมมองว่าการทดสอบคือการอธิบายว่าระบบควรทำงานอย่างไร และส่วนนี้มนุษย์ควรเป็นคนกำหนด โค้ดควรถูกทำให้สอดคล้องกับราวกั้นที่การทดสอบสร้างไว้
แต่ LLM ก็อาจช่วยชี้พื้นที่ที่สเปกยังไม่พอได้ สิ่งที่เกิดขึ้นตรงนี้อาจเป็นการให้มันเสนอ unit test สำหรับส่วนที่ยังกำหนดสเปกไว้ไม่ชัด
ก่อนยุค LLM เอง ผมก็เคยคิดเล่น ๆ ว่าถ้าเขียนเทสต์ไว้ครบแล้ว ลิงพิมพ์ดีดก็น่าจะสร้างแอปพลิเคชันได้หรือเปล่า
นี่คือเทสต์ที่นิยามว่าโค้ดปัจจุบันทำงานอย่างไรจริง ๆ ไม่ใช่ว่ามนุษย์เชื่อว่ามันควรทำงานอย่างไร
วิธีนี้ทำให้ rewrite, refactor, redesign ได้โดยลด regression ให้เหลือน้อยที่สุด ปัญหาของ legacy code จำนวนมากคือไม่มีใครเข้าใจ intended behavior และบางครั้งแม้แต่ผู้ใช้ก็เชื่อว่ามันควรทำงานต่างจากที่มันทำจริง
เพราะงั้นถ้าไม่ใช่การเปลี่ยนแปลงที่ต้องการอย่างชัดเจน สิ่งสำคัญที่สุดคือ อย่าเปลี่ยนพฤติกรรม
ไอเดียหลักคือ แทนที่จะใช้ระบบพิสูจน์แบบปิดที่สมบูรณ์ ก็แสดงข้อความอ้างเกี่ยวกับพฤติกรรมของโค้ดที่อ่อนกว่าในรูปของ “property” แล้วตรวจสอบมันภายใต้ข้อจำกัดเชิงความน่าจะเป็นโดยเนื้อแท้
ตัวอย่างคลาสสิกคือการกลับสตริง ถ้ากลับสตริงสองครั้งก็ควรได้อินพุตเดิม โดยเขียนโค้ดแค่บรรทัดเดียวก็ไล่เช็กเคสขอบ Unicode แปลก ๆ ได้มากเท่าที่เวลาและไฟฟ้าจะอำนวย
ตัวอย่างอาจดูพื้น ๆ แต่ผมเคยเห็นเซียน CUDA ที่ทำงานกับ autodiff และ kernel ซึ่งต่อมากลายเป็น PyTorch ใช้วิธีนี้ได้ยอดเยี่ยมมาก จนเพิ่มความน่าเชื่อถือของโค้ดได้ประมาณ 5 เท่าโดยใช้แรงและต้นทุนแค่ครึ่งเดียว
มันไม่ได้เข้ากับทุกกรณีเสมอไป แต่ถ้าเข้าทางแล้วเยี่ยมมาก และ LLM ก็ดูเหมือนจะเข้าใกล้การสร้างเคสแบบ Hypothesis ได้พอตัว มากกว่าจะเริ่มจากศูนย์
ในทางกลับกัน เวลาเขียนเทสต์ เราต้องอธิบายว่าแอปควรทำอะไรด้วยภาษาที่เยิ่นเย้อและมีข้อจำกัดสูงมาก แล้วต้องเขียน setup เป็นสิบหรือเป็นร้อยบรรทัดเพื่อใส่ if/else ที่แต่งสวยไว้นิดหน่อย
ในภาษาอย่าง C++ หรือ Java unit test มักประกอบขึ้นจากความน่าเบื่อ จึงไม่น่าแปลกใจเลยที่คนจะมีสัญชาตญาณอยากโยนงานนั้นให้ LLM
ผมเห็นวิศวกรจำนวนมากที่เขียนโค้ดอยู่หลายวัน แล้วค่อยมาเขียนเทสต์ทีหลังแบบจำใจสักไม่กี่ตัวเพื่อ “พิสูจน์” ว่าระบบทำงานได้ ความครอบคลุมต่ำและมักเปราะแตกง่าย
สำหรับวิศวกรที่คิดและทำงานแบบนั้น ระบบแบบนี้คงดูเหมือนของขวัญจากพระเจ้า
ผมยังเคยมีผู้จัดการที่ห้ามเขียนเทสต์ก่อนเพราะบอกว่าช้าเกินไป โชคดีที่ตอนนั้นผมเป็นคนนอกเลยตอบได้ว่า “ไปคุยกับหัวหน้าผมเอาเอง” แล้วเมินไป แต่เขาก็คงคิดไม่ต่างจากวิศวกรข้างบน
มองอีกแบบ นักพัฒนาส่วนใหญ่เกลียดเอกสาร ถ้ามี AI ที่เขียนเอกสารชั้นดีจากโค้ดได้ พวกเขาก็คงชอบ และสำหรับนักพัฒนาแบบนั้น เอกสารที่ยอดเยี่ยมก็คือเอกสารที่ตัวเองไม่ต้องเขียน
เทสต์โค้ดมักถูกมองว่าเป็นโค้ดลำดับความสำคัญต่ำ เลยถูกโยนให้วิศวกรที่ junior กว่าทำ ซึ่งดูเหมือนจะตรงข้ามกับสิ่งที่ควรเป็นอย่างสิ้นเชิง
ผมไม่อยากไล่ตรวจทั้งหมด แต่มีอยู่ส่วนหนึ่งที่ดูพลาดหนักเป็นพิเศษ
ผมอ่านผ่าน ๆ ต้นฉบับตอนมันเพิ่งโพสต์ขึ้นมา และตอนนี้ก็กำลังเปิดดูอีกที ความจำเลยอาจไม่เป๊ะ
บล็อกเขียนว่าเทสต์ของ Meta TestGen-LLM ส่วนใหญ่เพิ่ม coverage แค่ 2.5 บรรทัด แต่มีเทสต์หนึ่งครอบคลุมได้ 1326 บรรทัด และคุณค่าของเทสต์นั้น “มากกว่าแบบยกกำลัง” อีกทั้งคุณค่าของ LLM คือการคิดนอกกรอบเชิงรุกเพื่อจับ edge case ที่คาดไม่ถึง
แต่คำว่า “มีค่ากว่าแบบยกกำลัง” นี่ควรทำให้สัญญาณจับคำพูดเหลวไหลดังขึ้นมาทันที พอไปดูในงานวิจัย ผู้เขียนอธิบาย coverage 1326 บรรทัดนี้ว่าเป็น เทสต์เดี่ยวที่ฟลุกแจ็กพอต และบอกว่าค่าเพิ่มเติมของ line coverage ที่คาดหวังได้จริงจากเทสต์ TestGen-LLM เดี่ยว ๆ มีค่ามัธยฐานแค่ 2.5 บรรทัด
ผู้เขียนไม่ได้พูดถึง “edge case ที่คาดไม่ถึง” หรือ “การคิดนอกกรอบ” เลย ตรงกันข้าม พวกเขานำเสนอว่ามันเป็น กรณีผิดปกติ ที่อาจแค่ไปแตะสาขาหนึ่งของ switch ที่เลวร้ายมาก หรือเป็นความบังเอิญของวิธีคำนวณ code coverage ก็ได้
ที่สะดุดตาคือแม้แต่ในส่วน “ผลลัพธ์เชิงคุณภาพ” ก็ไม่ได้ขุดเรื่องนี้ต่อ การอธิบายแบบไม่แม่นไม่ได้ช่วยใครเลย บนอินเทอร์เน็ตมีคนที่ทำเหมือนอ่านแล้วเข้าใจ ทั้งที่จริงไม่เข้าใจ มากเกินพออยู่แล้ว
ผมแก้บทความแล้วเพื่อให้ชัดขึ้นว่าส่วนหนึ่งของการตีความเป็นความเห็นของผมเอง
บทความนี้ใกล้เคียงกับการแสดงความคิดเห็นต่อความหมายของผลวิจัย มากกว่าจะเป็นการสรุปงานวิจัยตรง ๆ ยังไงก็ตาม Hacker News ก็เป็นพื้นที่สำหรับการถกเถียงอยู่แล้ว
ถึงอย่างนั้น ผมก็ยังคิดว่าส่วน “มีค่ากว่าแบบยกกำลัง” ยังถูกต้อง ประเด็นเรื่อง LLM อาจฟลุก “แจ็กพอต” ได้ในเชิง test coverage นี่แหละคือแก่นของคุณค่า
ถ้าลองจับคู่หรือผสมไปเรื่อย ๆ แล้วสุดท้ายได้แจ็กพอตสักตัวแบบในงานวิจัย มันก็มีค่ามากสำหรับทีม อาจเป็นเทสต์ที่มนุษย์ไม่ได้เขียนเองเพราะไม่ชัดพอหรือเพราะน่าเบื่อเกินไป
ในฐานะคนที่เคยใช้เวลามากเกินไปกับการหาว่า “จะเทสต์อย่างไร” ทั้งที่รู้อยู่แล้วว่าใน codebase ของ Big Tech (F/G) ควรเทสต์อะไร ผมมองว่ามันมีคุณค่ามาก
เห็นได้ชัดว่าทีมนี้ก็ถูกผลักด้วยจำนวนบรรทัดโค้ดและจำนวน diff เหมือนกัน สุดท้ายมันก็เป็นแค่ เครื่องมือสร้างโค้ด ที่เพิ่มกองโค้ดซึ่ง debug ยากขึ้นมาอีกกองเท่านั้น
การทดสอบที่ดีเป็นเรื่องยาก และ coverage ก็ไม่ได้แปลว่าดีเสมอไป
เขียนเทสต์มากเกินไปจนทำให้โปรแกรมแข็งทื่อ และสุดท้ายกลายเป็นโปรแกรมตรวจจับการเปลี่ยนแปลงโดยพฤตินัยได้ง่าย ๆ แนวประมาณว่า “มีอะไรเปลี่ยนไปนะ เทสต์พังหมดเลย ไม่เป็นไร เดี๋ยวให้ LLM สร้างใหม่อีกครั้ง! coverage 100%! น่าทึ่ง! ความก้าวหน้า!”
สำหรับฉัน นั่นคือโอกาสในการยืนยันว่าการเปลี่ยนแปลงนั้นตั้งใจหรือไม่ ถ้าไม่มีสิ่งนี้ แล้วจะรู้ได้อย่างไรว่าโปรแกรมทำในสิ่งที่ควรทำ?
นอกนั้นก็ต้องไปอ่านเทสต์ดี ๆ ที่คนอื่นอีกห้าคนคิดไว้ พวกเราไม่มีใครเขียนเทสต์เก่ง และแต่ละคนก็ทำกันไปคนละแบบ
หลังจากนั้นทุกครั้งที่มีการเปลี่ยนแปลง นักพัฒนาก็กดปุ่ม regenerate แล้ว commit ทุกอย่างไปตามธรรมชาติ diff เยอะมาก แต่สัญญาณที่ได้ก็น่าสงสัย
หลังจากเคยทำงานในอุตสาหกรรมเซมิคอนดักเตอร์ โดยเฉพาะด้าน computational lithography ที่การออกแบบแบบขับเคลื่อนด้วยการทดสอบเป็นมาตรฐาน ก็รู้สึกเห็นด้วยได้ยาก
ไม่ได้หมายความว่าต้องเขียนเทสต์ก่อนโค้ดโปรดักชันเสมอไป แต่เทสต์เป็นส่วนหนึ่งของโค้ดพอ ๆ กับส่วนอื่นของโค้ดเบส และต้องเขียนไปพร้อมกับโค้ดที่ถูกทดสอบ
ส่วนที่สำคัญที่สุดของเทสต์คือการแสดงเจตนาของนักพัฒนา test suite แสดงให้เห็นว่าโค้ดควรถูกใช้อย่างไร ทำอะไร ไม่ทำอะไร และถูกเขียนมาเพื่ออะไร
แบบนั้นนักพัฒนาคนอื่นเวลาจะใช้หรือแก้โค้ดนั้น ก็ไม่ต้องเล่นบท Sherlock Holmes คอยตามหาเบาะแสอยู่ทั่วโค้ดเบส
ถ้าเทสต์ไม่สามารถเล่าเรื่องได้ แปลว่าคุณกำลังเขียนเทสต์ผิด
จนกว่าคอมพิวเตอร์จะอ่านใจและเข้าใจเจตนาได้ดีกว่านี้ ตัวสร้างที่อิง AI/LLM ก็ยังทำหน้าที่นี้แทนไม่ได้
แน่นอน ถ้าเป้าหมายเดียวของ test suite คือได้เครื่องหมายถูกสีเขียวก่อน commit และมีตัวเลข coverage สวย ๆ AI ก็อาจเพิ่มผลิตภาพได้เป็นสองเท่า
ตัวสร้างโค้ดอัตโนมัติจะช่วยให้เราเขียนโค้ดแย่ ๆ ได้มากขึ้นด้วยความเร็วแสง ถ้าใครบ่นว่าโค้ดพองโตเพราะ boilerplate เยอะและเข้าใจยาก ก็แค่บอกให้ใช้ AI จัดการ เพราะกับคุณมันได้ผล
ถ้านั่นคืออนาคตของการพัฒนาซอฟต์แวร์จริง ๆ มันก็ไม่ใช่อนาคตที่ฉันหวังไว้
สิ่งที่อธิบายมาดูเหมือนเป็นการทดสอบ “แกนหลัก” ของโค้ด เป็นเทสต์ที่ทำหน้าที่ทั้งด้านเอกสาร การตรวจสอบ และความเสถียรบางส่วน
เทสต์แบบอื่นอย่าง fuzzing มอบคุณค่าในแบบที่ต่างออกไปโดยสิ้นเชิง ผมคิดว่าเทสต์ที่อิง AI สามารถเข้ามาอยู่ในพื้นที่ฝั่งหางของการกระจาย คือกลุ่มเทสต์จำนวนมากที่มูลค่าไม่สูงนักและมักถูกปล่อยทิ้งไว้ เพราะมนุษย์มีเวลาและพลังงานไม่พอ
ผมก็มองสถานะของเครื่องมือ AI ปัจจุบันแบบนั้นเหมือนกัน มันคือ เครื่องมือช่วยด้านการรับรู้
ถ้าทิศทางการวิจัยนี้จะไม่ออกดอกออกผลพอสมควรภายในไม่กี่ปีข้างหน้า ผมคงแปลกใจมากกว่า
ขอยกสิ่งที่เคยเขียนไว้ตอนตัวบทความขึ้นมาใหม่ โดยปรับแต่งเล็กน้อย คนกลุ่มนี้นำเสนอสถิติผิด
https://news.ycombinator.com/item?id=39406726
บทคัดย่อไม่ตรงกับเนื้อหาในงานวิจัยจริง สรุปของมันชวนให้อ่านเหมือนเป็นสัดส่วนในระดับ test case เช่น “75% build ได้ถูกต้อง, 57% ผ่านอย่างเสถียร, 25% เพิ่ม coverage”
แต่รายงานจริงพูดในระดับ test class และแต่ละคลาสมี test case ได้ตั้งแต่หนึ่งกรณีขึ้นไป
ความหมายคือ “75% ของ test class มี test case ใหม่อย่างน้อยหนึ่งกรณีที่ build ได้ถูกต้อง”, “57% ของ test class มี test case อย่างน้อยหนึ่งกรณีที่ build ได้ถูกต้องและผ่านอย่างเสถียร”, “25% ของ test class มี test case อย่างน้อยหนึ่งกรณีที่ build ได้ ผ่านได้ และเพิ่ม line coverage เมื่อเทียบกับ test class อื่นของ target การ build เดียวกัน”
สองแบบนี้เป็นคนละประโยคกันโดยสิ้นเชิง และยังมีเชิงอรรถด้วยว่า ในการพยายามขยายแต่ละ test class อาจมีการพยายามสร้าง test case หลายครั้ง ดังนั้นอัตราสำเร็จต่อ test case มักต่ำกว่าอัตราสำเร็จต่อ test class มาก
แต่ในบทสรุปก็กลับไปสื่อผลลัพธ์ผิดแบบในบทคัดย่ออีก โดยเขียนว่าเมื่อใช้ TestGen-LLM ในโหมดทดลอง อัตราสำเร็จต่อ test case อยู่ที่ 25% และถ้าผ่อนเงื่อนไขเรื่อง line coverage ให้ต้องแค่ build และผ่านได้ อัตราสำเร็จก็เพิ่มเป็น 57%
รู้สึกเห็นใจคนที่จะต้องมาบำรุงรักษา โค้ดมรดกจาก LLM ที่ย่ำแย่พวกนี้ในอนาคต
มันคงดูน่าเกลียดมาก
ที่จริงอาจดูคล้ายกันมากด้วยซ้ำ และคอมเมนต์กับเอกสารอาจครบกว่าพร้อมทั้งมีโอกาสผิดแบบมั่นใจน้อยกว่า
LLM จะไม่มีวันดีไปกว่าตอนนี้แน่ ๆ และตลอด 2 ปีที่ผ่านมาก็ไม่ได้พัฒนาอะไรเลย มันก็แค่ Markov chain ที่ดูหรูหรา
ใช้มันเขียนโค้ดได้ก็เฉพาะเวลาคนที่ไม่รู้การเขียนโปรแกรม commit โค้ดเข้าโปรดักชันแบบไม่ตรวจทานเท่านั้น
สำหรับคนที่รู้การเขียนโปรแกรม มันไม่มีทางมีประโยชน์หรือเพิ่มผลิตภาพได้
ผมจะเมินคำเพ้อเจ้อเรื่อง LLM ทั้งหมดนี้ที่ไม่ได้เปลี่ยนโลกเลย และคุณก็ควรทำแบบนั้นเหมือนกัน
ถ้าไม่แยกให้ดี ก็จะกลายเป็น สภาพแวดล้อมที่เป็นปฏิปักษ์ต่อนักพัฒนา ได้ง่าย เมื่อผู้จัดการที่ไม่เข้าใจเรียกร้อง coverage สูง ๆ และจูเนียร์ที่ไฟแรงแอบยัด AI tests เข้ามาจำนวนมาก
สุดท้ายก็จะกลายเป็นสถานการณ์ที่ทุกครั้งที่ส่งงาน ต้องไปขอประทับตราจากโค้ดทดสอบที่สร้างโดย LLM ซึ่งบำรุงรักษายาก
การเขียนเทสต์บางส่วนอาจเร็วขึ้น แต่ไม่ได้แปลว่าการบำรุงรักษาจะเร็วขึ้นด้วยเสมอไป เช่นเดียวกับการบำรุงรักษาโค้ดที่ถูกทดสอบ เพราะไม่มีอะไรรับประกันว่าจะได้เทสต์ที่ดี
กระบวนการที่ต้องลำบากกับการเขียนเทสต์มักช่วยให้นักพัฒนาตรวจสอบการออกแบบตั้งแต่เนิ่น ๆ ด้วย ถ้าทดสอบได้ยาก โดยมากก็แปลว่าไม่ได้เป็นการออกแบบที่ดี เช่น ในบริบทที่ต้องเขียนโค้ดร่วมกับคนอื่น สัญญาของคอมโพเนนต์มักยังไม่ได้ถูกทำให้นามธรรมเพียงพอ
สิ่งที่มองข้ามกันได้ง่ายคือ เทสต์เป็น โค้ดที่ยอมสละทิ้งได้ ส่วนใหญ่ตลอดอายุของมันอาจจับปัญหาอะไรไม่ได้เลย และก็ไม่เป็นไร เพราะมันให้ความมั่นใจแบบอัตโนมัติและช่วยลดเบาะแสที่ผิดพลาดเมื่อเกิดความล้มเหลว
แต่การทุ่มลงทุนสูงสุดกับมาตรการป้องกันแบบอาศัยความน่าจะเป็น ไม่ได้ให้ผลตอบแทนเสมอไป ยิ่ง coverage เข้าใกล้จุดสูงสุด ประโยชน์ส่วนเพิ่มก็ยิ่งลดลง เว้นแต่จะเป็นเส้นทางการทำงานที่มีทราฟฟิกสูงอย่าง standard library ไม่เช่นนั้นต่อให้มี coverage สูงก็มักไม่ได้ผลตอบแทนคุ้มค่า
นอกจากนี้ แทบจะตลอดเวลาที่ระบบทำงานได้ทั้งระบบ ก็ไม่ได้มีแค่ unit test แต่ต้องมี ระบบนิเวศของการทดสอบ อย่าง integration test, system test ฯลฯ ด้วย LLM จะไปนั่งในที่ประชุมออกแบบ เข้าใจสถาปัตยกรรม แล้วเขียนเทสต์พวกนั้นให้ด้วยหรือ? หรือสุดท้ายจะเป็นการพูดเกินจริงถึงสิ่งที่มันทำได้ จนไปเบียดบังสิ่งที่ควรทำจริง ๆ?
เวลาลงแรงกับการทดสอบ เราต้องมีเซนส์ในการตัดสินว่า “อะไรเกี่ยวข้อง” ไม่ใช่แค่ตอนเขียน แต่รวมถึงตอนออกแบบและตอนบำรุงรักษาด้วย มนุษย์ทำเรื่องนี้ได้ค่อนข้างดี แต่เครื่องมือ AI ยังไม่ใช่
จุดที่ LLM อาจช่วยประหยัดเวลาได้ คือการกดแป้นพิมพ์ของนักพัฒนามากประสบการณ์ที่พอรู้แล้วว่าอะไรควรทดสอบหรือไม่ควรทดสอบ ขณะเดียวกันมันก็อาจกลายเป็นตัวรบกวนด้วยการแอบพาเรื่องที่ไม่ค่อยเกี่ยวข้องเข้ามาในโค้ด และมันก็เป็นแบบนั้นมาแล้ว
เราไม่ได้ต้องการเศรษฐศาสตร์ของการผลิตการกดแป้นพิมพ์ เราต้องการชุดของการกดแป้นพิมพ์ที่ผ่านการคิดมาอย่างดีและมีความเกี่ยวข้องสูง และหวังว่าสิ่งหลังนี้จะแยกจากสิ่งแรกได้ชัดเจน เพื่อให้เมื่อเวลาผ่านไป ประโยชน์เชิงภววิสัยหรือการไม่มีประโยชน์ของมันจะปรากฏออกมา
ลองทำด้วย GPT-4 มาแล้ว
พอให้ดูโมดูล TypeScript แล้วบอกให้สร้าง unit test มันก็สร้างเทสต์ที่ใช้งานได้จริง ซึ่งครอบคลุมทั้งเส้นทางปกติและกรณีขอบบางอย่างด้วย
ChatGPT ทำได้เกินคาดในหลายด้าน เทสต์ก็ดูเหมือนเป็นงานที่ง่ายเมื่อเทียบกับความสามารถของ GPT
เมื่อสัปดาห์ก่อนผมให้มันเขียนโค้ด Python ที่เดิน AST เพื่อสร้างกราฟและคอมโพเนนต์ของ React Flow ผมไม่ได้แก้อะไรเลย แค่ทำ prompt feedback วนไปไม่กี่รอบ มันก็ทำงานได้ดีมาก ผมเห็นความสามารถน่าสนใจคล้าย ๆ กันจาก GPT มาเยอะแล้ว
AI รู้ได้อย่างไรว่าควรเขียนเทสต์แบบไหน?
เป็นการทดลองที่น่าสนใจ แต่ก็ยังค่อนข้างน่าสงสัย ผมคิดว่าวิธีที่ AI ช่วยงานพัฒนาซอฟต์แวร์ได้ดีที่สุด คือเวลาที่โปรแกรมเมอร์ถามเกี่ยวกับโค้ดของตัวเองหรือของคนอื่น แล้ว AI ตอบกลับ บางครั้งอาจมีข้อเสนอแนะเป็นโค้ดรวมอยู่ด้วย แต่ไม่จำเป็นต้องมีเสมอไป
มันควรตอบคำถามอย่าง “มีวิธีทำให้โค้ดนี้ง่ายขึ้นไหม?” หรือ “อินพุตแบบไหนที่อาจทำให้เกิดข้อผิดพลาดได้?”
AI ควรช่วยให้เราเข้าใจโค้ด และเข้าใจวิธีปรับปรุงมัน ถ้าเราไม่ได้บอกว่าต้องการให้ทำอะไร AI ก็ไม่มีทางรู้ว่าเราต้องการอะไร ดังนั้นไม่ควรปล่อยให้มันเขียนทุกอย่างเองทั้งหมด
เทสต์เป็นตัวอย่างที่ดี เราต้องการทดสอบอะไร?
ในที่สุดก็มี AI code generation ที่ฟังขึ้น