블로그 이미지
윤영식
Full Stacker, Application Architecter, KnowHow Dispenser and Bike Rider

Publication

Category

Recent Post

2014. 6. 3. 15:23 AngularJS/Start MEAN Stack

Angular Team에서 End-To-End 테스트를 위하여 별도로 개발한 프레임워크가 Protractor 이다. protractor는 WebDriverJs기반으로 만들어 졌다. 





Protractor 설정

  - Chrome 최신 버전 사용

  - protractor 설치 및 Chrome에서 selenium standalone server로 구동하기 위한 driver도 설치한다 

$ npm install -g protractor

$ webdriver-manager update 


  - selenium server를 기동하는 방법 : 4444 port로 listen한다 ( 호출 :  http://localhost:4444/wd/hub )

$ webdriver-manager start

seleniumProcess.pid: 55938

6월 02, 2014 5:08:16 오후 org.openqa.grid.selenium.GridLauncher main

정보: Launching a standalone server

Setting system property webdriver.chrome.driver to /usr/local/lib/node_modules/protractor/selenium/chromedriver

17:08:16.913 INFO - Java: Oracle Corporation 24.51-b03

17:08:16.915 INFO - OS: Mac OS X 10.9.3 x86_64

17:08:16.935 INFO - v2.41.0, with Core v2.41.0. Built from revision 3192d8a

17:08:17.079 INFO - Default driver org.openqa.selenium.ie.InternetExplorerDriver registration is skipped: registration capabilities Capabilities [{platform=WINDOWS, ensureCleanSession=true, browserName=internet explorer, version=}] does not match with current platform: MAC

17:08:17.145 INFO - RemoteWebDriver instances should connect to: http://127.0.0.1:4444/wd/hub

17:08:17.146 INFO - Version Jetty/5.1.x

17:08:17.148 INFO - Started HttpContext[/selenium-server/driver,/selenium-server/driver]

17:08:17.149 INFO - Started HttpContext[/selenium-server,/selenium-server]

17:08:17.149 INFO - Started HttpContext[/,/]

17:08:17.510 INFO - Started org.openqa.jetty.jetty.servlet.ServletHandler@4b8e282c

17:08:17.510 INFO - Started HttpContext[/wd,/wd]

17:08:17.517 INFO - Started SocketListener on 0.0.0.0:4444

17:08:17.517 INFO - Started org.openqa.jetty.jetty.Server@3e578b06


  - 잘 동작하지 않는다면 Path에 JAVA_HOME을 설정한다. 



Protractor 환경 설정

  - 루트에 protractor-e2e.conf.js 파일 생성

  - 설정 : baseUrl은 grunt serve 시에 기동되는 port 번호

exports.config = {

  seleniumAddress: 'http://localhost:4444/wd/hub',

  capabilities: {'browserName': 'chrome'},

  specs: ['test/client/e2e/**/*.js'],

  baseUrl: 'http://localhost:9000',

  jasmineNodeOpts: {

    onComplete: null,

    isVerbose: true,

    showColors: true,

    includeStackTrace: true,

    defaultTimeoutInterval: 10000

  },

  framework: 'jasmine'

};

  - 체크

$ webdriver-manager start 

$ protractor protractor-e2e.conf.js

Using the selenium server at http://localhost:4444/wd/hub

[launcher] Running 1 instances of WebDriver


Finished in 0.001 seconds

0 tests, 0 assertions, 0 failures


[launcher] chrome passed

  - grunt를 이용하여 테스트 할 수 있도록 Gruntfile.js 에 설정. run: {..} 안의 options에 configFile 설정이 중요함 

$ npm install grunt-protractor-runner --save-dev


// grunt.initConfig 안에 설정

  protractor: {

      options: {

        keepAlive: true

      },

      run: {

        options: {

          configFile: "protractor-e2e.conf.js", // Target-specific config file

          args: {} // Target-specific arguments

        }

      }

  },


// task 설정

  grunt.registerTask('test', function(target) {

    if (target === 'server') {

      return grunt.task.run([

        'env:test',

        'mochaTest'

      ]);

    }


    else if (target === 'client') {

      return grunt.task.run([

        'concurrent:test',

        'autoprefixer',

        'karma',

        'protractor'

      ]);

    }


    else grunt.task.run([

      'test:server',

      'test:client'

    ]);

  });


// grunt test 에 첨부 

$ grunt test 또는 grunt test:client 수행 (단, 수행전에 webdriver-manager start 수행해 놓은 상태이어야함)


Running "protractor:run" (protractor) task

Using the selenium server at http://localhost:4444/wd/hub

[launcher] Running 1 instances of WebDriver


Finished in 0 seconds

0 tests, 0 assertions, 0 failures

[launcher] chrome passed

Done, without errors.


Execution Time (2014-06-02 15:43:51 UTC)

protractor:run  2.2s  ▇▇ 100%

Total 2.3s

  - 또는, grunt 설정을 하지 않았을 경우는 다음과 같이도 테스트 가능하다. 하지만 가급적 grunt를 이용하자.  

$ webdriver-manager start

$ protractor protractor-e2e.conf.js



End-to-End 테스트 코드 작성방식

  - 테스트 코드를 작성하기 위한 몇가지 개념을 익힌다. (위키)

> browser : webdriver를 감싼 객체. navigation 과 page information 을 갖음

> element : html element를 찾고 상호작용을 위한 helper method 

> by : element locator collection

> protractor : webdriver namespace를 wrapping한 protractor namespace


  - 샘플 코드 

    + browser.get : page loading 

    + element : page에서 element를 찾아줌 

    + by 종류 (소스 참조)

  • by.binding searches for elements by matching binding names, either from ng-bind or {{}} notation in the template.
  • by.model searches for elements by input ng-model.
  • by.repeater searches for ng-repeat elements. For example, by.repeater('phone in phones').row(11).column('price')returns the element in the 12th row (0-based) of the ng-repeat = "phone in phones" repeater with the binding matching{{phone.price}}.

describe('angularjs homepage', function() { it('should greet the named user', function() { // Load the AngularJS homepage. browser.get('http://www.angularjs.org'); // Find the element with ng-model matching 'yourName' - this will // find the <input type="text" ng-model="yourName"/> element - and then // type 'Julie' into it. element(by.model('yourName')).sendKeys('Julie'); // Find the element with binding matching 'yourName' - this will // find the <h1>Hello {{yourName}}!</h1> element. var greeting = element(by.binding('yourName')); // Assert that the text element has the expected value. // Protractor patches 'expect' to understand promises. expect(greeting.getText()).toEqual('Hello Julie!'); }); });


실제 End-to-End 테스트 코드

  - 로그인의 경우 e2e 코드 작성예 (필수참조)

'use strict';


var LoginPage = function() {

this.email = element(by.model('user.email'));

this.password = element(by.model('user.password'));


this.setEmail = function(email) {

this.email.sendKeys(email);

};


this.setPassword=  function(password) {

this.password.sendKeys(password);

};


this.url = function() {

browser.get('/#/signin');

};


this.login = function() {

return element(by.buttonText('button')).click();

};

};


describe('Login Page', function() {

it('should successfully login', function(){

var loginPage = new LoginPage();

loginPage.url();

loginPage.setEmail('test@test.com');

loginPage.setPassword('test');

loginPage.login().then(function(response){

console.log(response);

}, function(error){


})

});

});


  - 수행 : grunt test:client 

    + 수행 에러 발생함 : to be continue...



<참조>

  - Protractor 테스트 방법

  - Protractor Test PPT (필독)

  - Unit, E2E ToDo 예제

  - Protractor Grunt 설정하기

  - End-To-End Test 하기 예제

  - grunt-protractor-runner 

  - Angular Test Pattern

posted by 윤영식