เรื่องนี้เกี่ยวกับอะไร
การเปลี่ยนจาก Manifest V2 เป็น Manifest V3 มาพร้อมกับการเปลี่ยนแปลงพื้นฐาน ใน Manifest V2 ส่วนขยายจะอยู่ในหน้าเบื้องหลัง หน้าพื้นหลังจัดการการสื่อสารระหว่างส่วนขยายกับหน้าเว็บ Manifest V3 ใช้ Service Worker แทน
ในโพสต์นี้ เราจะเจาะลึกปัญหาการทดสอบเจ้าหน้าที่ฝ่ายสนับสนุนทางเทคนิค โดยเฉพาะอย่างยิ่ง เราจะดูวิธีตรวจสอบว่าผลิตภัณฑ์ทำงานได้อย่างถูกต้องในกรณีที่ Service Worker ถูกระงับ
เราคือใคร
eyeo เป็นบริษัทที่มุ่งมั่นที่จะส่งเสริมให้เกิดการเปลี่ยนมูลค่าออนไลน์ที่สมดุลและยั่งยืนสำหรับผู้ใช้ เบราว์เซอร์ ผู้ลงโฆษณา และผู้เผยแพร่โฆษณา เรามีผู้ใช้ทั่วโลกที่กรองโฆษณามากกว่า 300 ล้านคนที่อนุญาตให้แสดงโฆษณาที่ยอมรับได้ ซึ่งเป็นมาตรฐานโฆษณาที่พัฒนาขึ้นโดยอิสระซึ่งจะกำหนดว่าโฆษณานั้นยอมรับได้และไม่เป็นการรบกวนหรือไม่
ทีมเครื่องมือส่วนขยายของเราให้บริการเทคโนโลยีการกรองโฆษณาที่ขับเคลื่อนส่วนขยายเบราว์เซอร์ที่บล็อกโฆษณาซึ่งได้รับความนิยมมากที่สุดบางรายการในตลาด เช่น AdBlock และ Adblock Plus ซึ่งมีผู้ใช้มากกว่า 110 ล้านคนทั่วโลก นอกจากนี้ เรายังนำเสนอเทคโนโลยีนี้เป็นคลังโอเพนซอร์สเพื่อให้ส่วนขยายเบราว์เซอร์อื่นๆ ที่กรองโฆษณาใช้งานได้
เวิร์กเกอร์บริการคืออะไร
เวิร์กเกอร์บริการส่วนขยายคือตัวแฮนเดิลเหตุการณ์ส่วนกลางของส่วนขยายเบราว์เซอร์ โดยทำงานอิสระในเบื้องหลัง โดยทั่วไปแล้ว ไม่เป็นไร เราทําสิ่งต่างๆ ส่วนใหญ่ที่ต้องทำในหน้าเบื้องหลังได้ใน Service Worker ใหม่ แต่มีการเปลี่ยนแปลงบางอย่างเมื่อเทียบกับหน้าเบื้องหลัง ดังนี้
- Service Worker จะหยุดทำงานเมื่อไม่ได้ใช้งาน ซึ่งทำให้เราต้องเก็บสถานะแอปพลิเคชันไว้แทนที่จะใช้ตัวแปรส่วนกลาง ซึ่งหมายความว่าต้องเตรียมจุดแรกเข้าระบบของเราให้พร้อมเรียกใช้ก่อนที่จะเริ่มต้นระบบ
- ต้องแนบ Listener เหตุการณ์ก่อนรอการเรียกกลับแบบแอสซิงค์ Service Worker ที่ถูกระงับจะยังคงรับเหตุการณ์ที่สมัครรับข้อมูลไว้ได้ หากไม่ได้ลงทะเบียนตัวรับฟังเหตุการณ์ในรอบแรกของลูปเหตุการณ์ ตัวรับฟังจะไม่ได้รับการแจ้งเตือนหากเหตุการณ์ดังกล่าวปลุก Service Worker
- การสิ้นสุดการทำงานที่ไม่ได้ใช้งานอาจขัดจังหวะตัวจับเวลาก่อนที่ตัวจับเวลาจะทำงานเสร็จ
กรณีใดบ้างที่ Service Worker จะถูกระงับ
สำหรับ Chrome 119 สิ่งที่เราพบคือ Service Worker ถูกระงับในกรณีต่อไปนี้
- หลังจากไม่ได้รับเหตุการณ์หรือการเรียก API ของส่วนขยายเป็นเวลา 30 วินาที
- ไม่เคย หากเครื่องมือสําหรับนักพัฒนาซอฟต์แวร์เปิดอยู่หรือคุณใช้คลังการทดสอบที่อิงตาม ChromeDriver (ดูคําขอฟีเจอร์)
- หากคุณคลิกหยุดใน chrome://serviceworker-internals
ดูข้อมูลล่าสุดได้ที่วงจรชีวิตของ Service Worker
เหตุใดการทดสอบจึงมีปัญหา
การมีคําแนะนําอย่างเป็นทางการเกี่ยวกับ "วิธีทดสอบ Service Worker อย่างมีประสิทธิภาพ" หรือตัวอย่างการทดสอบที่ใช้งานได้จะเป็นประโยชน์อย่างยิ่ง ในระหว่างการทดสอบผู้ให้บริการ เราพบปัญหาบางอย่างดังนี้
- เรามีสถานะในส่วนขยายทดสอบ เมื่อ Service Worker หยุดทำงาน เราจะสูญเสียสถานะและเหตุการณ์ที่ลงทะเบียนไว้ เราจะเก็บข้อมูลในขั้นตอนการทดสอบได้อย่างไร
- หาก Service Worker ถูกระงับได้ทุกเมื่อ เราจะต้องทดสอบว่าฟีเจอร์ทั้งหมดทำงานได้หากถูกขัดจังหวะ
- แม้ว่าเราจะแนะนำกลไกในการทดสอบที่ระงับ Service Worker แบบสุ่ม แต่เบราว์เซอร์ก็ไม่มี API ที่จะระงับ Service Worker ได้อย่างง่ายดาย เราได้ขอให้ทีม W3C เพิ่มฟีเจอร์นี้ แต่เรายังอยู่ระหว่างการพูดคุยกัน
การทดสอบการระงับ Service Worker
เราได้ลองใช้แนวทางต่างๆ เพื่อทริกเกอร์การระงับ Service Worker ในระหว่างการทดสอบ ดังนี้
แนวทาง | ปัญหาเกี่ยวกับแนวทาง |
รอตามระยะเวลาที่ต้องการ (เช่น 30 วินาที) | ซึ่งทําให้การทดสอบช้าและไม่น่าเชื่อถือ โดยเฉพาะอย่างยิ่งเมื่อทำการทดสอบหลายรายการ การดำเนินการนี้จะไม่ทำงานเมื่อใช้ WebDriver เนื่องจาก WebDriver ใช้ DevTools API ของ Chrome และระบบจะไม่ระงับ Service Worker เมื่อ DevTools เปิดอยู่ แม้ว่าจะข้ามได้ แต่เราก็ยังต้องตรวจสอบว่า Service Worker ถูกระงับหรือไม่ และเราไม่มีวิธีตรวจสอบ |
เรียกใช้ลูปแบบไม่รู้จบใน Service Worker | ข้อมูลจำเพาะระบุว่าการดำเนินการนี้อาจนำไปสู่การสิ้นสุดการใช้งาน ทั้งนี้ขึ้นอยู่กับวิธีที่เบราว์เซอร์ใช้ฟังก์ชันการทำงานนี้ Chrome จะไม่สิ้นสุดการทำงานของ Service Worker ในกรณีนี้ เราจึงทดสอบสถานการณ์เมื่อ Service Worker ถูกระงับไม่ได้ |
มีข้อความใน Service Worker เพื่อตรวจสอบว่าถูกระงับหรือไม่ | การส่งข้อความจะปลุก Service Worker ข้อมูลนี้สามารถใช้เพื่อตรวจสอบว่า Service Worker อยู่ในสถานะ "หยุดทำงาน" หรือไม่ แต่จะทำให้ผลการทดสอบที่จำเป็นต้องตรวจสอบทันทีหลังจากระงับ Service Worker ใช้งานไม่ได้ |
หยุดกระบวนการของ Service Worker โดยใช้ chrome.processes.terminate() | Service Worker ของส่วนขยายจะแชร์กระบวนการกับส่วนอื่นๆ ของส่วนขยาย ดังนั้นการสิ้นสุดกระบวนการนี้โดยใช้ chrome.process.terminate() หรือ GUI ของตัวจัดการกระบวนการของ Chrome จะไม่เพียงแต่สิ้นสุด Service Worker เท่านั้น แต่ยังสิ้นสุดหน้าส่วนขยายด้วย |
สุดท้ายเราทำการทดสอบเพื่อตรวจสอบว่าโค้ดของเราตอบสนองอย่างไรเมื่อ Service Worker ถูกระงับโดยให้ Selenium WebDriver เปิด chrome://serviceworker-internals/ แล้วคลิกปุ่ม "หยุด" สำหรับ Service Worker
นี่เป็นตัวเลือกที่ดีที่สุดเท่าที่มีมา แต่ก็ยังไม่ใช่ตัวเลือกที่ดีที่สุด เนื่องจากการทดสอบ Mocha (ซึ่งทำงานในหน้าส่วนขยาย) ทําเช่นนี้ด้วยตนเองไม่ได้ จึงต้องสื่อสารกลับไปที่โปรแกรมโหนด WebDriver ซึ่งหมายความว่าการทดสอบเหล่านี้จะทํางานโดยใช้เพียงส่วนขยายไม่ได้ แต่จะต้องมีการเรียกให้แสดงโดยใช้ Selenium WebDriver
แผนภาพต่อไปนี้แสดงวิธีที่เราสื่อสารกับเบราว์เซอร์ API ผ่านขั้นตอนต่างๆ และผลกระทบที่การเพิ่มกลไก "การระงับ Service Worker" มีต่อ API
![แผนภาพแสดงขั้นตอนการทดสอบ](https://developer.chrome.google.cn/static/blog/eyeos-journey-to-testing-mv3-service worker-suspension/image/testing-flow.png?authuser=19&hl=th)
ในขั้นตอนใหม่ที่ระงับ Service Worker (สีน้ำเงิน) เราได้เพิ่ม Selenium WebDriver เพื่อ "คลิก" ระงับผ่าน UI ซึ่งจะทริกเกอร์การดำเนินการในเบราว์เซอร์ API
โปรดทราบว่ามีข้อบกพร่องของ Chrome ที่ทำให้การดําเนินการนี้กับ Selenium WebDriver ทําให้ Service Worker เริ่มทํางานอีกครั้งไม่ได้ ปัญหานี้ได้รับการแก้ไขแล้วใน Chrome 116 และโชคดีที่มีวิธีแก้ปัญหาชั่วคราวด้วย โดยการตั้งค่าให้ Chrome เปิดเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์โดยอัตโนมัติในทุกแท็บจะทำให้ Service Worker เริ่มทำงานอย่างถูกต้อง
นี่เป็นแนวทางที่เราใช้เมื่อทำการทดสอบ แม้ว่าจะไม่ใช่แนวทางที่ดีที่สุดเนื่องจากการคลิกปุ่มอาจไม่ใช่ API ที่เสถียร และการเปิดเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ (สําหรับเบราว์เซอร์รุ่นเก่า) ดูเหมือนว่าจะมีต้นทุนด้านประสิทธิภาพ
เราจะครอบคลุมฟังก์ชันการทำงานทั้งหมดได้อย่างไร การทดสอบ Fuzz
เมื่อเรามีกลไกในการทดสอบการระงับแล้ว เราจะต้องตัดสินใจว่าจะนำไปใช้กับชุดทดสอบการทำงานอัตโนมัติอย่างไร เราทำการทดสอบมาตรฐานในสภาพแวดล้อมที่ก่อนการโต้ตอบกับหน้าเบื้องหลังแต่ละครั้ง Service Worker ถูกระงับโดย WebDriver คลิกหยุดในหน้า chrome://serviceworker-internals/
![ตัวอย่างการเรียกใช้การดำเนินการทดสอบแบบ Fuzz](https://developer.chrome.google.cn/static/blog/eyeos-journey-to-testing-mv3-service worker-suspension/image/test-run.png?authuser=19&hl=th)
เราทำการทดสอบส่วนใหญ่แต่ไม่ได้ทำการทดสอบทั้งหมด เนื่องจากกลไกการระงับยังไม่เสถียรมากนักและบางครั้งอาจทำให้เกิดความผิดพลาด นอกจากนี้ การรันชุดทดสอบทั้งหมดในโหมด Fuzz ยังใช้เวลานานมาก ดังนั้น เราจึงเลือกเส้นทางที่สำคัญที่สุดมาทดสอบในโหมด Fuzz แทนที่จะครอบคลุมกรณี "คล้ายกัน" ทั้งหมด โปรดทราบว่าการเรียกใช้การทดสอบฟังก์ชันการทำงานในโหมด "Fuzz" หมายความว่าเราต้องเพิ่มการหมดเวลาของการทดสอบเนื่องจากการระงับและเริ่ม Service Worker อีกครั้งจะใช้เวลาเพิ่มเติม
การทดสอบเหล่านี้มีประโยชน์ในการเรียกใช้ครั้งแรกแบบหยาบๆ ซึ่งจะไฮไลต์ตำแหน่งต่างๆ ที่โค้ดทำงานไม่สำเร็จ แต่อาจไม่พบวิธีทั้งหมดที่ละเอียดอ่อนซึ่งการระงับ Service Worker อาจทําให้ระบบขัดข้อง
เรียกการทดสอบประเภทนี้ว่า "การทดสอบ Fuzz" โดยทั่วไปแล้ว การทดสอบแบบ Fuzz คือการนำอินพุตที่ไม่ถูกต้องไปป้อนโปรแกรมและตรวจสอบว่าโปรแกรมตอบสนองอย่างสมเหตุสมผล หรืออย่างน้อยก็ไม่ขัดข้อง ในกรณีของเรา "อินพุตที่ไม่ถูกต้อง" คือ Service Worker ถูกระงับได้ทุกเมื่อ และ "ลักษณะการทำงานที่สมเหตุสมผล" ที่เราคาดหวังคือฟังก์ชันการกรองโฆษณาต้องทํางานต่อไปได้เหมือนเดิม อินพุตนี้ไม่ใช่อินพุตที่ไม่ถูกต้องเนื่องจากเป็นลักษณะการทำงานปกติใน Manifest V3 แต่จะเป็นอินพุตที่ไม่ถูกต้องใน Manifest V2 จึงดูเหมือนเป็นคำศัพท์ที่เหมาะสม
สรุป
Service Worker เป็นหนึ่งในการเปลี่ยนแปลงที่สำคัญที่สุดในไฟล์ Manifest V3 (นอกเหนือจากกฎ declarativeNetRequest) การย้ายข้อมูลไปยัง Manifest V3 อาจต้องมีการเปลี่ยนโค้ดหลายรายการในส่วนขยายเบราว์เซอร์และแนวทางใหม่ในการทดสอบ นอกจากนี้ ยังกำหนดให้นักพัฒนาส่วนขยายที่มีสถานะถาวรต้องเตรียมส่วนขยายให้รับมือกับการระงับ Service Worker ที่ไม่คาดคิดอย่างราบรื่น
ขออภัย ไม่มี API สำหรับจัดการการระงับด้วยวิธีที่ง่ายและเหมาะกับ Use Case ของเรา เนื่องจากเราต้องการทดสอบความเสถียรของโค้ดเบสของส่วนขยายกับกลไกการระงับในระยะแรก เราจึงต้องหาวิธีแก้ปัญหา นักพัฒนาส่วนขยายรายอื่นๆ ที่พบปัญหาคล้ายกันสามารถใช้วิธีแก้ปัญหานี้ได้ แม้ว่าจะใช้เวลานานในขั้นตอนการพัฒนาและการบำรุงรักษา แต่เราก็มั่นใจว่าส่วนขยายจะทํางานได้อย่างสําเร็จในสภาพแวดล้อมที่มีการระงับ Service Worker เป็นประจํา
แม้ว่าจะมีการสนับสนุนขั้นพื้นฐานสำหรับการทดสอบการระงับ Service Worker อยู่แล้ว แต่เราต้องการเห็นการรองรับแพลตฟอร์มที่ดีขึ้นสำหรับการทดสอบ Service Worker จากภายในส่วนขยายในอนาคต เนื่องจากอาจช่วยลดเวลาในการทดสอบและความพยายามในการบำรุงรักษาได้อย่างมาก