Nội dung này nói về gì?
Việc chuyển đổi từ tệp kê khai Manifest V2 sang tệp kê khai Manifest V3 sẽ có một thay đổi cơ bản. Trong Manifest V2, các tiện ích nằm trong một trang ở chế độ nền. Trang nền quản lý hoạt động giao tiếp giữa các tiện ích và trang web. Tệp kê khai V3 sử dụng trình chạy dịch vụ.
Trong bài đăng này, chúng ta sẽ tìm hiểu sâu về vấn đề kiểm thử trình chạy dịch vụ tiện ích. Cụ thể, chúng ta sẽ xem xét cách đảm bảo sản phẩm hoạt động chính xác trong trường hợp một worker dịch vụ bị tạm ngưng.
Chúng tôi là ai?
eyeo là một công ty chuyên hỗ trợ việc trao đổi giá trị trực tuyến một cách cân bằng và bền vững cho người dùng, trình duyệt, nhà quảng cáo và nhà xuất bản. Chúng tôi có hơn 300 triệu người dùng trên toàn cầu sử dụng tính năng lọc quảng cáo và cho phép hiển thị Quảng cáo được chấp nhận. Đây là một tiêu chuẩn quảng cáo được xây dựng độc lập để xác định xem một quảng cáo có được chấp nhận và không gây phiền toái hay không.
Nhóm công cụ tiện ích của chúng tôi cung cấp công nghệ lọc quảng cáo hỗ trợ một số tiện ích trình duyệt chặn quảng cáo phổ biến nhất trên thị trường, chẳng hạn như AdBlock và Adblock Plus với hơn 110 triệu người dùng trên toàn thế giới. Ngoài ra, chúng tôi cung cấp công nghệ này dưới dạng thư viện nguồn mở để các tiện ích trình duyệt lọc quảng cáo khác có thể sử dụng.
Worker dịch vụ là gì?
Trình chạy dịch vụ tiện ích là trình xử lý sự kiện trung tâm của tiện ích trình duyệt. Các dịch vụ này chạy độc lập ở chế độ nền. Nhìn chung, điều này là ổn. Chúng ta có thể làm hầu hết những việc cần làm trên trang nền trong worker dịch vụ mới. Tuy nhiên, có một vài thay đổi so với các trang ở chế độ nền:
- Worker dịch vụ kết thúc khi không sử dụng. Điều này đòi hỏi chúng ta phải duy trì trạng thái ứng dụng thay vì dựa vào các biến toàn cục. Điều này có nghĩa là mọi điểm truy cập vào hệ thống của chúng ta phải được chuẩn bị để được gọi trước khi hệ thống được khởi tạo.
- Bạn phải đính kèm trình nghe sự kiện trước khi chờ bất kỳ lệnh gọi lại không đồng bộ nào. Worker dịch vụ bị tạm ngưng vẫn có thể nhận được các sự kiện mà worker đó đã đăng ký. Nếu trình nghe cho sự kiện không được đăng ký trong vòng lặp sự kiện đầu tiên, thì trình nghe đó sẽ không nhận được sự kiện nếu sự kiện đó đánh thức worker dịch vụ.
- Việc chấm dứt trạng thái rảnh có thể làm gián đoạn bộ hẹn giờ trước khi bộ hẹn giờ hoàn tất.
Khi nào trình chạy dịch vụ bị tạm ngưng?
Đối với Chrome 119, chúng tôi nhận thấy rằng các worker dịch vụ bị tạm ngưng:
- Sau khi không nhận được sự kiện hoặc gọi API tiện ích trong 30 giây.
- Không bao giờ nếu công cụ cho nhà phát triển đang mở hoặc bạn đang sử dụng thư viện kiểm thử dựa trên ChromeDriver (xem yêu cầu tính năng).
- Nếu bạn nhấp vào Stop (Dừng) trong chrome://serviceworker-internals.
Để biết thêm thông tin mới đây, hãy tham khảo bài viết Vòng đời của trình chạy dịch vụ.
Tại sao việc kiểm thử điều này lại là vấn đề?
Lý tưởng nhất là bạn nên có hướng dẫn chính thức về "cách kiểm thử worker dịch vụ một cách hiệu quả" hoặc ví dụ về các kiểm thử đang hoạt động. Trong quá trình thử nghiệm worker dịch vụ, chúng tôi gặp phải một số thách thức:
- Chúng ta có trạng thái trong tiện ích kiểm thử. Khi worker dịch vụ dừng, chúng ta sẽ mất trạng thái và các sự kiện đã đăng ký của worker đó. Làm cách nào để duy trì dữ liệu trong quy trình kiểm thử?
- Nếu worker dịch vụ có thể bị tạm ngưng bất cứ lúc nào, chúng ta cần kiểm thử để đảm bảo tất cả tính năng đều hoạt động nếu bị gián đoạn.
- Ngay cả khi chúng ta giới thiệu một cơ chế trong các bài kiểm thử để ngẫu nhiên tạm ngưng worker dịch vụ, thì trình duyệt vẫn không có API nào để dễ dàng tạm ngưng worker dịch vụ. Chúng tôi đã yêu cầu nhóm W3C thêm tính năng này, nhưng đó là một cuộc trò chuyện đang diễn ra.
Kiểm thử việc tạm ngưng Trình thực thi dịch vụ
Chúng tôi đã thử một số phương pháp để kích hoạt việc tạm ngưng worker dịch vụ trong quá trình kiểm thử:
Phương pháp | Vấn đề với phương pháp này |
Chờ một khoảng thời gian tuỳ ý (ví dụ: 30 giây) | Điều này khiến quá trình kiểm thử diễn ra chậm và không đáng tin cậy, đặc biệt là khi chạy nhiều kiểm thử. Phương thức này không hoạt động khi sử dụng WebDriver, vì WebDriver sử dụng API DevTools của Chrome và worker dịch vụ không bị tạm ngưng khi DevTools đang mở. Ngay cả khi có thể bỏ qua, chúng ta vẫn phải kiểm tra xem trình chạy dịch vụ có bị tạm ngưng hay không và chúng ta không có cách nào để làm việc đó. |
Chạy một vòng lặp vô hạn trong trình chạy dịch vụ | Theo thông số kỹ thuật, điều này có thể dẫn đến việc chấm dứt tuỳ thuộc vào cách trình duyệt triển khai chức năng này. Trong trường hợp này, Chrome không chấm dứt trình chạy dịch vụ nên chúng ta không thể kiểm thử trường hợp khi trình chạy dịch vụ bị tạm ngưng. |
Có thông báo trong worker dịch vụ để kiểm tra xem worker đó có bị tạm ngưng hay không | Việc gửi thông báo sẽ đánh thức worker dịch vụ. Bạn có thể dùng phương thức này để kiểm tra xem worker dịch vụ có ở trạng thái ngủ hay không, nhưng phương thức này sẽ làm hỏng kết quả cho các kiểm thử cần kiểm tra ngay sau khi tạm ngưng worker dịch vụ. |
Tắt quy trình worker dịch vụ bằng chrome.processes.terminate() | Trình chạy dịch vụ của tiện ích chia sẻ một quy trình với các phần khác của tiện ích, vì vậy, việc chấm dứt quy trình này bằng chrome.process.terminate() hoặc GUI của trình quản lý quy trình của Chrome không chỉ chấm dứt trình chạy dịch vụ mà còn chấm dứt mọi trang tiện ích. |
Cuối cùng, chúng ta đã có một kiểm thử để kiểm tra cách mã của chúng ta phản hồi khi worker dịch vụ bị tạm ngưng bằng cách yêu cầu Selenium WebDriver mở chrome://serviceworker-internals/ và nhấp vào nút "dừng" cho worker dịch vụ.
Đây là lựa chọn tốt nhất cho đến thời điểm hiện tại, nhưng không phải là lựa chọn lý tưởng vì các chương trình kiểm thử Mocha (chạy trên một trang tiện ích) không thể tự thực hiện việc này, vì vậy, chúng cần giao tiếp lại với chương trình nút WebDriver. Điều này có nghĩa là bạn không thể chạy các chương trình kiểm thử này chỉ bằng tiện ích; bạn phải kích hoạt các chương trình kiểm thử này bằng Selenium WebDriver.
Dưới đây là sơ đồ về cách chúng ta giao tiếp với API trình duyệt thông qua nhiều luồng và mức độ ảnh hưởng của việc thêm cơ chế "tạm ngưng worker dịch vụ".
Trong một luồng mới tạm ngưng worker dịch vụ (màu xanh dương), chúng tôi đã thêm Selenium WebDriver để "nhấp" vào nút tạm ngưng thông qua giao diện người dùng. Thao tác này sẽ kích hoạt một hành động trong API trình duyệt.
Xin lưu ý rằng có một lỗi Chrome khi thực hiện việc này với Selenium WebDriver khiến worker dịch vụ không thể khởi động lại. Lỗi này đã được khắc phục trong Chrome 116 và may mắn là cũng có một giải pháp: thiết lập Chrome để tự động mở DevTools trên mọi thẻ giúp worker dịch vụ khởi động chính xác.
Đây là phương pháp chúng tôi đang sử dụng khi kiểm thử mặc dù không phải là phương pháp lý tưởng vì việc nhấp vào nút có thể không phải là API ổn định và việc mở DevTools (đối với các trình duyệt cũ) có vẻ như sẽ gây hao tổn hiệu suất.
Làm cách nào để chúng ta bao quát toàn bộ chức năng? Kiểm thử mờ
Sau khi có cơ chế kiểm thử việc tạm ngưng, chúng tôi phải quyết định cách đưa cơ chế đó vào bộ kiểm thử tự động. Chúng tôi đã chạy các chương trình kiểm thử tiêu chuẩn trong môi trường mà trước mỗi lần tương tác với trang ở chế độ nền, trình chạy dịch vụ bị tạm ngưng bằng cách WebDriver nhấp vào Stop (Dừng) trên trang chrome://serviceworker-internals/.
Chúng tôi chạy hầu hết chứ không phải tất cả các bài kiểm thử vì cơ chế tạm ngưng chưa hoàn toàn ổn định và đôi khi gây ra sự cố. Ngoài ra, việc chạy tất cả các bộ kiểm thử ở chế độ tìm lỗi mã nguồn mất nhiều thời gian. Vì vậy, thay vì xem xét tất cả các trường hợp "tương tự", chúng tôi đã chọn những đường dẫn quan trọng nhất để kiểm thử ở chế độ tìm lỗi mã nguồn. Xin lưu ý rằng việc chạy kiểm thử chức năng ở chế độ "fuzz" (gây nhiễu) có nghĩa là chúng ta phải tăng thời gian chờ của các kiểm thử vì việc tạm ngưng và khởi động lại worker dịch vụ sẽ mất thêm thời gian.
Những kiểm thử này rất có giá trị như một lượt kiểm thử đầu tiên ở cấp độ tổng quát, giúp làm nổi bật nhiều vị trí mã không đạt, nhưng không nhất thiết phải phát hiện tất cả các cách tinh vi mà việc tạm ngưng worker dịch vụ có thể gây ra sự cố.
Trong nội bộ, chúng tôi gọi những loại kiểm thử này là "Kiểm thử tìm lỗi mã nguồn". Theo truyền thống, kiểm thử tìm lỗi mã nguồn là khi bạn đưa dữ liệu đầu vào không hợp lệ vào chương trình và đảm bảo rằng chương trình phản hồi một cách hợp lý hoặc ít nhất là không gặp sự cố. Trong trường hợp của chúng ta, "dữ liệu đầu vào không hợp lệ" là worker dịch vụ bị tạm ngưng bất cứ lúc nào và "hành vi hợp lý" mà chúng ta mong đợi là chức năng lọc quảng cáo phải tiếp tục hoạt động như trước. Đây không thực sự là dữ liệu đầu vào không hợp lệ vì đây là hành vi dự kiến trong Tệp kê khai V3, nhưng sẽ không hợp lệ trong Tệp kê khai V2, vì vậy, đây là thuật ngữ hợp lý.
Tóm tắt
Trình chạy dịch vụ là một trong những thay đổi lớn nhất trong Tệp kê khai V3 (ngoài các quy tắc declarativeNetRequest). Việc di chuyển sang Manifest V3 có thể yêu cầu nhiều thay đổi về mã trong tiện ích trình duyệt và các phương pháp kiểm thử mới. API này cũng yêu cầu nhà phát triển của các tiện ích có trạng thái ổn định phải chuẩn bị các tiện ích của họ để xử lý việc tạm ngưng worker dịch vụ ngoài dự kiến một cách linh hoạt.
Rất tiếc, không có API nào để xử lý việc tạm ngưng theo cách dễ dàng phù hợp với trường hợp sử dụng của chúng ta. Vì muốn kiểm thử độ mạnh mẽ của cơ sở mã của tiện ích so với các cơ chế tạm ngưng ở giai đoạn đầu, nên chúng tôi đã phải giải quyết vấn đề này. Các nhà phát triển tiện ích khác gặp phải những thách thức tương tự có thể sử dụng giải pháp này. Mặc dù mất nhiều thời gian trong giai đoạn phát triển và bảo trì, nhưng giải pháp này rất đáng để chúng ta đảm bảo rằng các tiện ích của mình có thể hoạt động thành công trong môi trường mà trình chạy dịch vụ thường xuyên bị tạm ngưng.
Mặc dù đã có hỗ trợ cơ bản để kiểm thử việc tạm ngưng worker dịch vụ, nhưng chúng tôi thực sự muốn thấy nền tảng hỗ trợ tốt hơn để kiểm thử worker dịch vụ từ trong các tiện ích trong tương lai, vì điều này có thể giúp giảm đáng kể thời gian thực thi kiểm thử và nỗ lực bảo trì.