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 fromng-bind
or{{}}
notation in the template.by.model
searches for elements by inputng-model
.by.repeater
searches forng-repeat
elements. For example,by.repeater('phone in phones').row(11).column('price')
returns the element in the 12th row (0-based) of theng-repeat = "phone in phones"
repeater with the binding matching{{phone.price}}
.
실제 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 Test PPT (필독)
'AngularJS > Start MEAN Stack' 카테고리의 다른 글
[MEAN Stack] Karma 통한 클라이언트 Unit Test (0) | 2014.06.02 |
---|---|
[MEAN Stack] 다국어 처리하기 (1) | 2014.05.28 |
[MEAN Stack] 로그인 서비스 개발 및 정보 저장하기 (0) | 2014.02.04 |
[MEAN Stack] Yo 이용하여 Controller 생성하고 UI-Router에 설정하기 (0) | 2014.01.30 |
[MEAN Stack] 메뉴 구성하고 UI Routing 설정하기 (0) | 2014.01.29 |