Front-End 테스트 환경 2) 멀티 브라우저 테스트 환경 구축하기


로컬 테스트 환경의 한계

이전 글에서는 단일 PC에서 테스트 환경을 구축하고 테스트를 실행하는 과정을 설명했다. 로컬 PC 내에서 브라우저 자동화 테스트를 수행하는 테스트의 경우 karma-chrome-launcher가 현재 karma 실행 환경에 설치된 Chrome 브라우저를 실행한다. 로컬 PC 내에서 다른 브라우저들을 동시에 테스트하려면 Firefox, OSX인 경우 Safari, Windows의 경우 Internet Explorer 나 Edge의 karma launcher를 추가로 등록하여 테스트를 수행할 수 있다. 하지만 이런 경우 OSX에서 Internet Explorer 테스트, Windows에서 Safari 테스트는 수행할 수 없다는 한계가 있다.

그래서 이번에는 로컬 PC에서 테스트가 수행되는 것이 아닌 다양한 OS, 브라우저 환경에서 브라우저 자동화 테스트를 수행하는 방법을 알아볼 것이다.

멀티 브라우저 테스트 환경

이 글에서는 FE개발랩에서 실제 사용하는 테스트 환경인 Internet Explorer 8 ~ 11, Microsoft Edge, Chrome, Firefox, Safari가 포함된 브라우저 자동화 테스트 환경을 설명할 예정이다.

우선, 테스트 환경 구축에 사용할 karma-webdriver-launcher, Selenium-WebDriver 와 Selenium Standalone Server를 간단하게 소개하고자 한다.

karma-webdriver-launcher

karma가 WebDriver를 통해 각 브라우저에 자동화 테스트를 실행할 수 있게 해주는 모듈이다. 이후 설명할 Selenium Standalone Server (Hub)(이하 Hub)에게 테스트를 수행하도록 정보를 전달한다.

FE개발랩은 개발자의 PC에 Hub를 두는 것이 아닌, 별개의 PC로 따로 분리해서 관리하고 있다. 기존 karma-webdriver-launcher는 Hub의 로컬에 있는 karma와 연결만을 지원하므로 fork 하여 확장한 github.com/nhn/karma-webdriver-launcher를 이용한다.

Selenium-WebDriver

W3C WebDriver 표준을 준수하는 브라우저 원격 테스트를 위해 브라우저를 실행해주는 binary이다. Internet Explorer를 위한 WebDriver는 selenium에서 개발하여 제공하며 Firefox, Chrome, Safari 등은 벤더사가 직접 구현한 WebDriver binary나, 원격 테스트를 위한 방법을 제공한다. 다운로드 링크

Selenium Standalone Server

브라우저 자동화 테스트를 위한 Java로 구현된 서버이다. 이 서버에 Hub, Node 둘 중 한가지 역할을 부여하여 사용할 수 있다. 예를 들어 브라우저 자동화 테스트가 수행될 PC 들에는 Node 역할을, 각 Node에 테스트 수행 명령을 내릴 PC에서는 Hub로 역할을 부여하면 된다.

원격 브라우저 자동화 테스트 수행 절차

테스트는 다음과 같은 절차로 수행된다.

  1. 개발자의 로컬 pc에서 karma 명령어를 통해 브라우저 자동화 테스트 수행.
  2. karma-webdriver-launcher가 Selenium Standalone Server(Hub) (이하 Hub)로 자동화 테스트를 시작.
  3. Hub는 들어온 테스트 요청의 브라우저 요구 조건에 맞는 Selenium Standalone Server(Node) (이하 Node)를 찾아서 각 Node 들에 테스트를 수행.
  4. 테스트가 수행되는 Node는 WebDriver를 이용해서 브라우저를 실행하고 테스트가 개시된 개발자의 karma 서버로 접속하여 테스트를 수행 후 종료.
  5. 테스트 수행 결과 보고.

멀티 브라우저 테스트 환경 구축

이제 본격적으로 테스트 환경 구축에 들어갈 것이다.

Architecture

1. Hub 준비

Selenium Standalone Server를 다운받아 원하는 경로에 위치시킨다. 다운로드 링크 Server의 Hub와 Node의 역할을 부여하는 방법은 Java 명령어로 수행시 -role 옵션에 각 역할의 이름을 넘기면 된다.

ex) 서버의 역할을 Hub로 설정하기

java -jar selenium-server-standalone-3.6.0.jar -role hub -hubConfig hubConfig.json
  • hubConfig.json
{
  "port": 4444,
  "newSessionWaitTimeout": -1,
  "servlets": [],
  "withoutServlets": [],
  "custom": {},
  "capabilityMatcher": "org.openqa.grid.internal.utils.DefaultCapabilityMatcher",
  "throwOnCapabilityNotPresent": true,
  "cleanUpCycle": 36000,
  "debug": false,
  "browserTimeout": 0,
  "timeout": 1800
}

Hub서버가 실행될 포트를 변경하는 등 설정은 커맨드라인 옵션 혹은 JSON 파일로 정의한다. 참고

위 설정을 이용하면 Hub를 4444 포트를 이용해서 실행한다.

2. 테스트를 수행할 PC에 브라우저 설치

테스트 환경에 필요한 PC의 운영체제로는 Internet Explorer, Edge를 위한 Windows, Safari를 위한 OSX가 필요하다. Firefox와 Chrome은 두 운영체제 모두 지원하므로 편의를 위해 Windows에 설치하여 진행하도록 하겠다.

Internet Explorer 각 버전과 Edge를 수행하려면 Windows 장비는 여러 대가 필요하다. (VM을 사용하는 경우 물리장비의 수는 1대일 수 있다) 각 장비에는 Chrome, Firefox도 설치 되도록 조합하고, Safari를 테스트하는 OSX도 준비한다. Internet Explorer 8은 karma 지원 브라우저에서 제외되어 테스트 수행에 폴리필이 필요하므로 이 글의 설명에서는 제외하도록 하겠다.

이렇게 준비한 PC 환경은 아래와 같다.

운영체제 보유 브라우저
Windows 7 Internet Explorer 9, Firefox
Windows 7 Internet Explorer 10, Chrome
Windows 10 Internet Explorer 11, Edge
OSX Sierra Safari 10

3. 테스트를 실행시킬 node들

이제 각 PC에서 구동될 브라우저의 WebDriver를 설치한다. WebDriver 설치는 실행할 Node와 같은 경로에 바이너리를 위치시키면 된다. Safari의 경우 Safari의 자동화 테스트를 참고하면 된다.

Hub와는 다르게 -role node 옵션과 -nodeConfig nodeConfig.json 옵션으로 역할 및 기타 옵션을 설정한다. 각 OS 및 브라우저를 가진 PC에서 실제 사용하는 설정 파일들은 아래와 같다.

(실제 Hub의 주소는 별도의 ipv4주소를 사용한다. 설정파일 예시를 위해 임의의 도메인인 multi.test.com으로 설명한다.)

  • nodeConfig.json (Windows 7 | Internet Explorer 9, Firefox)
{
  "capabilities": [
    {
      "browserName": "firefox",
      "platform": "WINDOWS",
      "maxInstances": 5,
      "seleniumProtocol": "WebDriver"
    },
    {
      "browserName": "internet explorer",
      "version": "9",
      "platform": "WINDOWS",
      "maxInstances": 5,
      "seleniumProtocol": "WebDriver"
    }
  ],
  "port": 5555,
  "maxSession": 5,
  "register": true,
  "registerCycle": 5000,
  "hub": "http://multi.test.com:4444",
  "hubPort": 4444,
  "hubHost": "multi.test.com"
}
  • nodeConfig.json (Windows 7 | Internet Explorer 10, Chrome)
{
  "capabilities": [
    {
      "browserName": "chrome",
      "platform": "WINDOWS",
      "maxInstances": 5,
      "seleniumProtocol": "WebDriver"
    },
    {
      "browserName": "internet explorer",
      "version": "10",
      "platform": "WINDOWS",
      "maxInstances": 5,
      "seleniumProtocol": "WebDriver"
    }
  ],
  "port": 5555,
  "maxSession": 5,
  "register": true,
  "registerCycle": 5000,
  "hub": "http://fe.test.com:4444",
  "hubPort": 4444,
  "hubHost": "fe.test.com"
}
  • nodeConfig.json (Windows 10 | Internet Explorer 11, Edge)
{
  "capabilities": [
    {
      "browserName": "internet explorer",
      "platform": "WINDOWS",
      "version": "11",
      "maxInstances": 5,
      "seleniumProtocol": "WebDriver"
    },
    {
      "browserName": "MicrosoftEdge",
      "maxInstances": 5,
      "platform": "WINDOWS",
      "seleniumProtocol": "WebDriver"
    }
  ],
  "port": 5555,
  "maxSession": 5,
  "register": true,
  "registerCycle": 5000,
  "hub": "http://multi.test.com:4444",
  "hubPort": 4444,
  "hubHost": "multi.test.com"
}
  • nodeConfig.json (OSX Sierra | Safari 10)
{
  "capabilities": [
    {
      "browserName": "safari",
      "maxInstances": 10
    }
  ],
  "port": 5555,
  "maxSession": 10,
  "hub": "http://multi.test.com:4444",
  "register": true,
  "registerCycle": 5000,
  "hubPort": 4444,
  "hubHost": "multi.test.com",
  "Dwebdriver.safari.driver=/usr/bin/safaridriver": ""
}

위 설정파일들을 보면 capabilities 배열이 있는데, 이 Node에 어떤 브라우저가 사용 가능한지 Hub에 등록하는데 사용된다.

설정 파일이 모두 준비가 되었다면, 각각의 PC에서 Node 역할의 Selenium Standalone Server를 실행한다.

Safari 브라우저는 Hub와 동일한 PC에서 5555 포트로 실행한다.

java -jar selenium-server-standalone-3.6.0.jar -role node -nodeConfig nodeConfig.json

karma.config.json 설정

기존의 설정 파일을 복사해서 몇군데만 손보면 원격 브라우저 테스트용 karma 설정 파일을 만들 수 있다.

  • karma.config.multi.js
// Karma configuration
// Generated on  ~~~

// WebDriver 설정
var webdriverConfig = {
  hostname: "multi.test.com",
  port: 4444,
  remoteHost: true
};

module.exports = function(config) {
  config.set({
    basePath: "",
    frameworks: ["jasmine"],
    files: ["js/*.js"],
    exclude: [],
    preprocessors: {},
    reporters: ["spec"],
    port: 9876,
    colors: true,
    logLevel: config.LOG_INFO,

    // 변경된 부분 - 시작
    customLaunchers: {
      IE9: {
        base: "WebDriver",
        config: webdriverConfig,
        browserName: "internet explorer",
        version: "9"
      },
      IE10: {
        base: "WebDriver",
        config: webdriverConfig,
        browserName: "internet explorer",
        version: "10"
      },
      IE11: {
        base: "WebDriver",
        config: webdriverConfig,
        browserName: "internet explorer",
        version: "11"
      },
      Edge: {
        base: "WebDriver",
        config: webdriverConfig,
        browserName: "MicrosoftEdge"
      },
      "Chrome-WebDriver": {
        base: "WebDriver",
        config: webdriverConfig,
        browserName: "chrome"
      },
      "Firefox-WebDriver": {
        base: "WebDriver",
        config: webdriverConfig,
        browserName: "firefox"
      },
      "Safari-WebDriver": {
        base: "WebDriver",
        config: webdriverConfig,
        browserName: "safari"
      }
    },
    browsers: [
      "IE9",
      "IE10",
      "IE11",
      "Edge",
      "Chrome-WebDriver",
      "Firefox-WebDriver",
      "Safari-WebDriver"
    ],
    plugins: [
      "karma-jasmine",
      "karma-webdriver-launcher",
      "karma-spec-reporter"
    ],
    specReporter: {
      suppressPassed: true,
      suppressSkipped: true
    },
    // 변경된 부분  - 끝

    singleRun: true,
    concurrency: Infinity
  });
};

수정된 설정 파일을 확인해 보면 autoWatch가 제거되었으며, customLaunchers, browsers, plugins가 추가되었다.

customLaunchers는 사용자가 정의하는 launcher 들이다. 앞서 설정한 Internet Explorer 8~11, Edge, Chrome, Firefox, Safari를 정의한다. browserskarma start 명령어가 실행될 때 테스트를 수행할 브라우저들을 나열하는 배열이다. customLaunchers에서 테스트를 수행할 브라우저의 키 값들이 적혀있다. 그리고 plugins 배열에는 위에서 설명한 karma-webdriver-launcher'karma-jasmine', 'karma-spec-reporter'가 적혀있다. 이 디펜던시들은 package.json 파일에 아래와 같이 추가한 뒤 npm install 명령어를 실행해서 설치한다.

  • package.json
{
  "name": "test",
  "repository": "http://github.com",
  "scripts": {
    "test": "karma start",
    "test:multi": "karma start karma.config.multi.js"
  },
  "devDependencies": {
    "jasmine-core": "^2.8.0",
    "karma": "^1.7.0",
    "karma-jasmine": "^1.1.0",
    "karma-chrome-launcher": "^2.2.0",
    "karma-spec-reporter": "^0.0.31",
    "karma-webdriver-launcher": "git+https://github.com/nhn/karma-webdriver-launcher.git#v1.1.0"
  }
}

그리고 npm script도 test:multi가 추가 되었는데 karma start 명령어 뒤에 새로 만든 config파일을 적어 넣었다.

테스트 실행해보기

자 이제 테스트를 실행해볼 준비가 끝났다. 아래 npm script로 멀티 브라우저 테스트를 실행해보자.

npm run test:multi

Test result

테스트를 수행한 브라우저들에서 테스트가 정상적으로 수행된 것을 확인할 수 있다.

마무리

이번 글은 Selenium을 이용한 다중 브라우저 자동화 테스트 환경 구축의 한가지 예시이다. 브라우저 자동화 테스트를 위한 다른 방법으로는 BrowserStack, Sauce Labs 등의 서비스를 이용하는 방법도 있다. 하지만 우리 FE개발랩은 소규모로 비용이 들지 않는 자동화 테스트 환경을 구축할 수 있고, 외부와 망 분리된 환경에서도 테스트가 가능한 점, Hub와 Node 모두 개발자와 같은 망 내에 있으므로 테스트 실행을 위해 소요되는 지연 시간도 짧다는 장점이 있어서 Selenium을 이용하고 있다.

이상으로 간단한 소스 코드와 테스트를 로컬 PC가 아닌 별도의 다양한 환경에서 테스트할 수 있게 되었다. 위에서 살펴본 기본적인 내용을 바탕으로 새로운 reporter를 추가하거나 Webpack 과 함께 사용하는 등 개발에 필요한 여러 가지 모듈을 추가하여 테스트 및 생산성을 높이는데 도움이 되었으면 한다.

참고


박정환, FE Development Lab2017.10.20Back to list