Chrome 확장 프로그램: 서비스 워커 정지 테스트를 위한 여정

Aga Czyżewska
Aga Czyżewska
Rowan Deysel
Rowan Deysel

이게 뭐야?

Manifest V2에서 Manifest V3로 전환하면 근본적인 변화가 발생합니다. Manifest V2에서는 확장 프로그램이 백그라운드 페이지에 있었습니다. 백그라운드 페이지는 확장 프로그램과 웹페이지 간의 통신을 관리했습니다. 매니페스트 V3에서는 대신 서비스 워커를 사용합니다.

이 게시물에서는 확장 프로그램 서비스 워커 테스트 문제를 자세히 살펴봅니다. 특히 서비스 워커가 정지된 경우 제품이 올바르게 작동하도록 하는 방법을 살펴봅니다.

Google 전문 서비스팀이란?

eyeo는 사용자, 브라우저, 광고주, 게시자를 위한 균형 잡힌 지속 가능한 온라인 가치 교환을 지원하는 데 전념하는 회사입니다. Google에는 광고가 허용되고 방해가 되지 않는지 판단하는 독립적으로 파생된 광고 표준인 'Acceptable Ads'(허용되는 광고)를 허용하는 전 세계 광고 필터링 사용자가 3억 명 이상 있습니다.

Google의 확장 프로그램 엔진팀은 전 세계 1억 1, 000만 명 이상의 사용자를 보유한 AdBlock 및 Adblock Plus와 같이 시장에서 가장 인기 있는 광고 차단 브라우저 확장 프로그램에 사용되는 광고 필터링 기술을 제공합니다. 또한 이 기술은 오픈소스 라이브러리로 제공되므로 다른 광고 필터링 브라우저 확장 프로그램에서 사용할 수 있습니다.

서비스 워커란 무엇인가요?

확장 프로그램 서비스 워커는 브라우저 확장 프로그램의 중앙 이벤트 핸들러입니다. 백그라운드에서 독립적으로 실행됩니다. 대체로 괜찮습니다. 새 서비스 워커의 백그라운드 페이지에서 해야 할 대부분의 작업을 실행할 수 있습니다. 하지만 배경 페이지와 비교하여 몇 가지 변경사항이 있습니다.

  • 서비스 워커는 사용하지 않을 때 종료됩니다. 이를 위해서는 전역 변수를 사용하는 대신 애플리케이션 상태를 유지해야 합니다. 즉, 시스템이 초기화되기 전에 시스템의 모든 진입점이 호출될 수 있도록 준비되어야 합니다.
  • 이벤트 리스너는 비동기 콜백을 기다리기 전에 연결해야 합니다. 일시중지된 서비스 워커는 구독한 이벤트를 계속 수신할 수 있습니다. 이벤트 리스너가 이벤트 루프의 첫 번째 턴에 등록되지 않은 경우, 해당 이벤트가 서비스 워커를 깨운 경우 이벤트를 수신하지 못합니다.
  • 유휴 종료는 타이머가 완료되기 전에 타이머를 중단할 수 있습니다.

서비스 워커는 언제 정지되나요?

Chrome 119에서는 서비스 워커가 정지되는 문제가 발생했습니다.

  • 30초 동안 이벤트를 수신하지 않거나 확장 프로그램 API를 호출하지 않은 후
  • 개발자 도구가 열려 있거나 ChromeDriver 기반 테스트 라이브러리를 사용하는 경우 (기능 요청 참고)에는 사용하지 마세요.
  • chrome://serviceworker-internals에서 중지를 클릭합니다.

최신 정보는 Service Worker 수명 주기를 참고하세요.

이 문제를 테스트하는 것이 왜 문제가 되나요?

'효율적인 방법으로 서비스 워커를 테스트하는 방법'에 관한 공식 안내나 작동하는 테스트의 예가 있으면 좋았을 것입니다. 서비스 워커를 테스트하는 과정에서 몇 가지 문제가 발생했습니다.

  • 테스트 확장 프로그램에 상태가 있습니다. 서비스 워커가 중지되면 상태와 등록된 이벤트가 손실됩니다. 테스트 흐름에서 데이터를 유지하려면 어떻게 해야 하나요?
  • 서비스 워커가 언제든지 일시중지될 수 있는 경우 중단될 때 모든 기능이 작동하는지 테스트해야 합니다.
  • 테스트에 서비스 워커를 무작위로 일시중지하는 메커니즘을 도입하더라도 브라우저에는 이를 쉽게 일시중지할 수 있는 API가 없습니다. 이 기능을 추가해 달라고 W3C팀에 요청했지만 아직 논의가 진행 중입니다.

서비스 워커 정지 테스트

테스트 중에 서비스 워커 정지를 트리거하는 여러 가지 접근 방식을 시도했습니다.

접근 방법 접근 방식에 문제가 있음
임의의 시간 (예: 30초) 기다리기 따라서 특히 여러 테스트를 실행할 때 테스트가 느리고 신뢰할 수 없게 됩니다. WebDriver를 사용하는 경우에는 작동하지 않습니다. WebDriver는 Chrome의 DevTools API를 사용하며 DevTools가 열려 있을 때 서비스 워커가 일시중지되지 않기 때문입니다. 우회할 수 있더라도 서비스 워커가 정지되었는지 확인해야 하며 이를 확인할 방법이 없습니다.
서비스 워커에서 무한 루프 실행 사양에 따라 브라우저에서 이 기능을 구현하는 방식에 따라 연결이 끊어질 수 있습니다. 이 경우 Chrome은 서비스 워커를 종료하지 않으므로 서비스 워커가 정지되는 시나리오를 테스트할 수 없습니다.
서비스 워커에 정지되었는지 확인하는 메시지가 있음 메시지를 전송하면 서비스 워커가 깨어납니다. 이를 사용하여 서비스 워커가 절전 모드인지 확인할 수 있지만, 서비스 워커를 일시중지한 직후에 확인을 실행해야 하는 테스트의 결과가 중단됩니다.
chrome.processes.terminate()를 사용하여 서비스 워커 프로세스 종료 확장 프로그램의 서비스 워커는 확장 프로그램의 다른 부분과 프로세스를 공유하므로 chrome.process.terminate() 또는 Chrome의 프로세스 관리자 GUI를 사용하여 이 프로세스를 종료하면 서비스 워커뿐만 아니라 모든 확장 프로그램 페이지도 종료됩니다.

Selenium WebDriver가 chrome://serviceworker-internals/ 를 열고 서비스 워커의 '중지' 버튼을 클릭하도록 하여 서비스 워커가 일시중지될 때 코드가 어떻게 응답하는지 확인하는 테스트를 완료했습니다.

지금까지는 이 방법이 가장 좋지만 확장 프로그램 페이지에서 실행되는 Mocha 테스트 는 이를 직접 실행할 수 없으므로 WebDriver 노드 프로그램에 다시 통신해야 하므로 이상적이지는 않습니다. 즉, 이러한 테스트는 확장 프로그램만 사용하여 실행할 수 없으며 Selenium WebDriver를 사용하여 트리거해야 합니다.

다음은 다양한 흐름을 통해 브라우저 API와 통신하는 방법과 '서비스 워커 일시중지' 메커니즘을 추가하면 어떻게 영향을 받는지를 보여주는 다이어그램입니다.

테스트 흐름을 보여주는 다이어그램
서비스 워커 정지와 관련된 테스트 흐름

서비스 워커를 일시중지하는 새 흐름 (파란색)에서 UI를 통해 일시중지를 '클릭'하여 브라우저 API에서 작업을 트리거하는 Selenium WebDriver를 추가했습니다.

Selenium WebDriver로 이 작업을 수행하면 서비스 워커를 다시 시작할 수 없는 Chrome 버그가 있었습니다. 이 문제는 Chrome 116에서 수정되었으며 다행히 해결 방법도 있습니다. 모든 탭에서 DevTools가 자동으로 열리도록 Chrome을 설정하면 서비스 워커가 올바르게 시작됩니다.

버튼을 클릭하는 것이 안정적인 API가 아닐 수 있고 DevTools를 여는 것이 (이전 브라우저의 경우) 성능 비용이 들 수 있으므로 이상적이지는 않지만 테스트할 때는 이 접근 방식을 사용합니다.

전체 기능을 어떻게 다루나요? 퍼징 테스트

정지 테스트 메커니즘을 마련한 후에는 이를 자동화 테스트 모음에 연결하는 방법을 결정해야 했습니다. 백그라운드 페이지와의 각 상호작용 전에 WebDriver가 chrome://serviceworker-internals/ 페이지에서 중지를 클릭하여 서비스 워커가 일시중지되는 환경에서 표준 테스트를 실행했습니다.

샘플 퍼징 테스트 실행
현재 테스트 설정을 보여주는 이미지입니다.

정지 메커니즘이 완전히 안정적이지 않고 불안정성을 일으키는 경우가 있기 때문에 모든 테스트가 아닌 대부분의 테스트를 실행합니다. 또한 모든 테스트 모음을 퍼징 모드에서 실행하는 데 시간이 많이 걸립니다. 따라서 모든 '유사한' 사례를 다루는 대신 퍼징 모드에서 테스트할 가장 중요한 경로를 선택했습니다. '퍼징' 모드에서 기능 테스트를 실행하면 서비스 워커를 일시중지하고 다시 시작하는 데 추가 시간이 걸리므로 테스트의 제한 시간을 늘려야 했습니다.

이러한 테스트는 코드가 실패하는 많은 위치를 강조 표시하는 대략적인 첫 번째 패스로 유용하지만 서비스 워커 정지 시 문제가 발생할 수 있는 미묘한 모든 방법을 반드시 파악하지는 못할 수 있습니다.

Google에서는 이러한 유형의 테스트를 '퍼징 테스트'라고 합니다. 기존에는 프로그램에 잘못된 입력을 던지고 프로그램이 적절하게 응답하는지 또는 적어도 비정상 종료되지 않는지 확인하는 것이 퍼징 테스트였습니다. 이 경우 '잘못된 입력'은 언제든지 서비스 워커가 정지되는 것이고, '합리적인 동작'은 광고 필터링 기능이 이전과 같이 계속 작동해야 한다는 것입니다. 이는 Manifest V3에서 예상되는 동작이므로 잘못된 입력이 아닙니다. 하지만 Manifest V2에서는 잘못된 입력이므로 적절한 용어라고 생각됩니다.

요약

서비스 워커는 declarativeNetRequest 규칙 외에 Manifest V3의 가장 큰 변화 중 하나입니다. Manifest V3로 이전하려면 브라우저 확장 프로그램의 많은 코드를 변경하고 테스트에 새로운 접근 방식을 적용해야 할 수 있습니다. 또한 영구 상태가 있는 확장 프로그램의 개발자는 예상치 못한 서비스 워커 정지를 적절한 방식으로 처리할 수 있도록 확장 프로그램을 준비해야 합니다.

안타깝게도 YouTube의 사용 사례에 맞게 정지를 간편하게 처리할 수 있는 API는 없습니다. 초기 단계에서 정지 메커니즘에 대한 확장 프로그램의 코드베이스의 견고성을 테스트하려고 했으므로 이 문제를 해결해야 했습니다. 유사한 문제에 직면한 다른 확장 프로그램 개발자는 이 해결 방법을 사용할 수 있습니다. 이 방법은 개발 및 유지보수 단계에서 시간이 많이 걸리지만 서비스 워커가 정기적으로 일시중지되는 환경에서 확장 프로그램이 제대로 작동할 수 있도록 하기 위해 그만한 가치가 있습니다.

이미 서비스 워커 정지 테스트를 위한 기본 지원이 있지만, 확장 프로그램 내에서 서비스 워커 테스트를 위한 플랫폼 지원을 개선하면 테스트 실행 시간과 유지보수 작업이 크게 줄어들 수 있으므로 향후 이러한 지원이 제공되기를 바랍니다.