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

이게 뭐죠?

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

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

Google 전문 서비스팀이란?

eyeo는 사용자, 브라우저, 광고주, 게시자를 위해 균형 잡히고 지속 가능한 온라인 가치 교환을 지원하는 데 전념하는 회사입니다. Google은 전 세계적으로 3억 명이 넘는 광고 필터링 사용자를 보유하고 있으며, 광고 허용 및 방해가 되지 않는 독립적인 광고 표준인 '허용되는 광고'의 표시를 허용하고 있습니다.

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

서비스 워커란?

확장 프로그램 서비스 워커는 브라우저 확장 프로그램의 중앙 이벤트 핸들러입니다. 백그라운드에서 독립적으로 실행됩니다. 대체로 괜찮습니다. 새 서비스 워커의 백그라운드 페이지에서 해야 하는 대부분의 작업을 할 수 있습니다. 그러나 백그라운드 페이지와 비교하자면 다음과 같은 몇 가지 차이점이 있습니다.

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

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

Chrome 119에서는 서비스 워커가 정지되었습니다.

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

최신 정보는 서비스 워커 수명 주기를 참고하세요.

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

'효율적인 방법으로 서비스 워커를 테스트하는 방법'에 대한 공식 지침이나 작업 테스트의 사례가 있다면 도움이 될 것입니다. 서비스 워커를 테스트하는 과정에서 몇 가지 과제에 직면했습니다.

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

서비스 워커 정지 테스트

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

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

우리는 Selenium WebDriver가 chrome://serviceworker-internals/ 를 열고 서비스 워커에 대해 "중지" 버튼을 클릭하도록 하여 코드가 서비스 워커에 대해 어떻게 응답하는지 확인하는 테스트를 마쳤습니다.

지금까지는 최적의 옵션이지만 확장 프로그램 페이지에서 실행되는 Mocha 테스트 는 이 작업을 자체적으로 수행할 수 없으므로 WebDriver 노드 프로그램과 다시 통신해야 하므로 이상적이지 않습니다. 즉, 이러한 테스트는 확장 프로그램만 사용하여 실행할 수 없으며 Selenium WebDriver를 사용하여 트리거해야 합니다.

다음은 다양한 흐름을 통해 브라우저 API와 통신하는 방법과 '정지된 서비스 워커' 메커니즘을 추가하는 것이 미치는 영향을 보여주는 다이어그램입니다.

테스트 흐름을 보여주는 다이어그램
서비스 워커 정지를 사용한 테스트 흐름

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

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

이는 테스트 시 사용하는 접근 방식입니다. 버튼을 클릭하는 것은 안정적인 API가 아닐 수 있고 (이전 브라우저의 경우) DevTools를 열면 성능 비용이 발생할 수 있기 때문에 이상적이지는 않습니다.

전체 기능은 어떻게 처리되나요? 퍼징 테스트

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

샘플 퍼즈 테스트 실행 실행
현재 테스트 설정을 보여주는 이미지

서스펜션 메커니즘이 완전히 안정적이지 않아 결함을 야기하는 경우도 있기 때문에 Google에서는 대부분의 테스트를 실행하지는 않습니다. 또한 모든 테스트 모음을 퍼즈 모드에서 실행하는 데 시간이 많이 걸립니다. 따라서 '유사한' 모든 사례를 포괄하는 대신 퍼즈 모드에서 테스트하기 위한 가장 중요한 경로를 선택했습니다. '퍼즈' 모드에서 기능 테스트를 실행하면 테스트의 제한 시간을 늘려야 한다는 점을 언급할 필요가 있습니다. 서비스 워커를 정지하고 다시 시작하는 데 시간이 더 걸리기 때문입니다.

이러한 테스트는 코드가 실패한 많은 부분을 강조하는 대략적인 첫 번째 통과로서 유용하지만, 서비스 워커 정지로 인해 중단을 일으킬 수 있는 미묘한 방법을 모두 찾아내지는 않을 수도 있습니다.

내부적으로는 이러한 종류의 테스트를 '퍼즈 테스트'라고 합니다. 일반적으로 퍼즈 테스트는 프로그램에서 잘못된 입력을 발생시켜 프로그램이 적절하게 응답하거나 최소한 비정상 종료되지 않는지 확인하는 것입니다. 이 경우 '잘못된 입력'은 언제든지 정지되는 서비스 워커를 의미하며, 예상되는 '합리적인 동작'은 광고 필터링 기능이 전과 동일하게 계속 작동해야 한다는 것입니다. 이는 Manifest V3에서 예상되는 동작이므로 실제로 잘못된 입력은 아니지만, Manifest V2에서는 유효하지 않을 것이므로 합리적인 용어로 느껴집니다.

요약

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

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

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