[unit-testing] 크롬 확장 프로그램을 테스트하는 방법?

이를 수행하는 좋은 방법이 있습니까? 웹 사이트와 콘텐츠 스크립트로 상호 작용하고 로컬 저장소를 사용하여 데이터를 저장하는 확장 프로그램을 작성 중입니다. 이 동작을 테스트하는 데 사용할 수있는 도구, 프레임 워크 등이 있습니까? 자바 스크립트를 테스트하기위한 일반적인 도구가 있지만 확장을 테스트하는 데 충분한 힘이 있습니까? 단위 테스트가 가장 중요하지만 다른 유형의 테스트 (예 : 통합 테스트)에도 관심이 있습니다.



답변

예, 기존 프레임 워크는 매우 유용합니다.

최근에는 모든 테스트를 응용 프로그램에 포함되었지만 실제로 입력하지 않으면 도달 할 수없는 “테스트”페이지에 배치했습니다.

예를 들어, 페이지의 모든 테스트를 아래에서 액세스 할 수 있습니다. chrome-extension://asdasdasdasdad/unittests.html

테스트는 다음에 액세스 할 수 있습니다 localStorage. 컨텐츠 스크립트에 액세스하려면 이론적으로 테스트 페이지에 포함 된 IFRAME을 통해 테스트 할 수 있지만, 이는보다 통합 레벨 테스트이므로 단위 테스트는 실제 페이지에서 벗어나 추상화해야합니다. localStorage에 액세스 할 때와 마찬가지로 의존하지 마십시오.

페이지를 직접 테스트하려는 경우 확장 프로그램을 조정하여 새 탭 (chrome.tab.create ({ “url”: “someurl”})을 열 ​​수 있습니다. 새 탭마다 콘텐츠 스크립트가 실행되어 사용할 수 있습니다. 테스트 프레임 워크에서 코드가 수행 한 작업을 수행했는지 확인하십시오.

프레임 워크의 경우 JsUnit 또는 최신 Jasmine 이 잘 작동합니다.


답변

여러 크롬 확장에서 작업 내가 해낸 sinon-chrome사용하여 단위 테스트를 실행할 수 있습니다 프로젝트 mocha, nodejsphantomjs.

기본적으로 chrome.*사전 정의 된 json 응답을 넣을 수있는 모든 API 의 sinon mock을 만듭니다 .

다음으로, vm.runInNewContext백그라운드 페이지 및 phantomjs렌더 팝업 / 옵션 페이지에 노드를 사용하여 스크립트를로드합니다 .

마지막으로 크롬 API가 필요한 인수로 호출되었다고 주장합니다.

예를 들어 보겠습니다
. 버튼 배지에 열린 탭 수를 표시하는 간단한 크롬 확장 프로그램이 있다고 가정합니다.

배경 페이지 :

chrome.tabs.query({}, function(tabs) {
  chrome.browserAction.setBadgeText({text: String(tabs.length)});
});

그것을 테스트하려면 다음이 필요합니다.

  1. 조롱 chrome.tabs.query두 개의 탭 예, 미리 정의 된 응답을 반환 할 수 있습니다.
  2. 조롱 된 chrome.*API를 환경에 주입
  3. 이 환경에서 확장 코드를 실행하십시오.
  4. 버튼 배지가 ‘2’와 같다고 주장

코드 스 니펫은 다음과 같습니다.

const vm = require('vm');
const fs = require('fs');
const chrome = require('sinon-chrome');

// 1. mock `chrome.tabs.query` to return predefined response
chrome.tabs.query.yields([
  {id: 1, title: 'Tab 1'},
  {id: 2, title: 'Tab 2'}
]);

// 2. inject our mocked chrome.* api into some environment
const context = {
  chrome: chrome
};

// 3. run our extension code in this environment
const code = fs.readFileSync('src/background.js');
vm.runInNewContext(code, context);

// 4. assert that button badge equals to '2'
sinon.assert.calledOnce(chrome.browserAction.setBadgeText);
sinon.assert.calledWithMatch(chrome.browserAction.setBadgeText, {
  text: "2"
});

이제 우리는 그것을 mocha의 describe..it함수 로 감싸서 터미널에서 실행할 수 있습니다.

$ mocha

background page
  ✓ should display opened tabs count in button badge

1 passing (98ms)

여기에서 전체 예제를 찾을 수 있습니다 .

또한 sinon-chrome을 사용하면 사전 정의 된 응답 (예 :

chrome.tab.onCreated.trigger({url: 'http://google.com'});


답변

sinon.js잘 작동 하는 것처럼 보이지만 일반 Jasmine을 사용하고 필요한 Chrome 콜백을 조롱 할 수도 있습니다. 예:

모조품

chrome = {
  runtime: {
    onMessage : {
      addListener : function() {}
    }
  }
}

테스트

describe("JSGuardian", function() {

  describe("BlockCache", function() {

    beforeEach(function() {
      this.blockCache = new BlockCache();
    });

    it("should recognize added urls", function() {
      this.blockCache.add("http://some.url");
      expect(this.blockCache.allow("http://some.url")).toBe(false);
    });
} // ... etc

SpecRunner.html코드를 실행 하려면 기본값 을 수정하십시오 .


답변

Chrome의 기존 도구 정보 :

  1. 크롬 개발자 도구에는 로컬 저장소 관련 리소스 섹션이 있습니다.

    개발자 도구> 리소스> 로컬 스토리지

    로컬 저장소의 변경 사항을 참조하십시오.

  2. console.profile을 사용하여 성능을 테스트하고 런타임 호출 스택을 볼 수 있습니다.

  3. filesystem의 경우이 URL을 사용하여 파일이 업로드되었는지 여부를 확인할 수 있습니다. filesystem : chrome-extension : /// temporary /

백그라운드 페이지 / 스크립트없이 메시지 전달없이 컨텐츠 스크립트와 로컬 스토리지를 함께 사용하는 경우 해당 사이트에서만 로컬 스토리지에 액세스 할 수 있습니다. 따라서 해당 페이지를 테스트하려면 해당 탭에 테스트 스크립트를 삽입해야합니다.


답변

Selenium은 확장 기능의 “보기”를 구동 할 수 없기 때문에 사전 설치된 확장명과 pyautogui 를 사용 하여 새 브라우저 인스턴스를 시작 하는 데 Selenium 웹 드라이버 를 사용할 수 있음을 발견했습니다 . 클릭 후 스크린 샷을 만들고 ‘예상 된’스크린 샷과 비교할 수 있으며, 유사성의 95 %를 기대합니다 (다른 브라우저에서는 몇 픽셀까지 마크 업 이동이 허용됩니다).


답변

몇 가지 이전 답변을 확인하기 위해 Jasmine은 Chrome 확장 프로그램에서 잘 작동하는 것 같습니다. 버전 3.4.0을 사용하고 있습니다.

Jasmine 스파이 를 사용 하여 다양한 API에 대한 테스트 배가를 쉽게 만들 수 있습니다. 처음부터 직접 만들 필요가 없습니다. 예를 들면 다음과 같습니다.

describe("Test suite", function() {

  it("Test case", function() {

    // Set up spies and fake data.
    spyOn(chrome.browserAction, "setPopup");
    spyOn(chrome.identity, "removeCachedAuthToken");
    fakeToken = "faketoken-faketoken-faketoken";
    fakeWindow = jasmine.createSpyObj("window", ["close"]);

    // Call the function under test.
    logout(fakeWindow, fakeToken);

    // Perform assertions.
    expect(chrome.browserAction.setPopup).toHaveBeenCalledWith({popup: ""});
    expect(chrome.identity.removeCachedAuthToken).toHaveBeenCalledWith({token: fakeToken});
    expect(fakeWindow.close.calls.count()).toEqual(1);

  });

});

도움이되는 경우 자세한 내용은 다음과 같습니다.

다른 답변에서 언급했듯이 테스트를 실행하는 브라우저 확장의 일부로 HTML 페이지를 만들었습니다. HTML 페이지에는 Jasmine 라이브러리와 확장 프로그램의 JavaScript 코드 및 테스트 스위트가 포함되어 있습니다. 테스트가 자동으로 실행되고 결과 형식이 결정됩니다. 테스트 러너 또는 결과 포맷터를 구축 할 필요가 없습니다. 설치 지침을 따르고 거기에 문서화 된 HTML을 사용하여 테스트 러너 페이지를 작성하고 테스트 스위트도 페이지에 포함하십시오.

다른 호스트에서 Jasmine 프레임 워크를 동적으로 가져올 수 있다고 생각하지 않으므로 내 확장에 Jasmine 릴리스를 포함 시켰습니다. 물론 프로덕션 용 확장을 빌드 할 때는 테스트 케이스도 생략합니다.

커맨드 라인에서 테스트를 실행하는 방법을 보지 못했습니다. 자동화 된 배포 도구에 유용합니다.


답변