툴선택
웹서비스 개발을 하면서 보다 편하게 브라우저 상에서 테스트를 진행하기 위해 여러 툴들을 찾아본 결과 Selenium과 Nightwatch.js 를 채용하기로 결정을 했다. 먼저 각각에 대하여 간단하게 알아보자.
- Selenium: 브라우저 상에서 일어나는 행위들을 자동으로 동작시키거나, 값들을 체크할 수 있다. Selenium은 목적에 따라 크게 두 개로 구성되어 있다. 하나는 Selenium WebDriver이고 다른 하나는 Selenium IDE이다.
- Selenium WebDriver: 다양한 언어로 브라우저를 컨트롤 하고 테스트할 수 있는 인터페이스를 제공한다. 따라서 웹서비스를 개발하는 언어에 통합해 UnitTest를 생성하고 통합테스트를 진행할 수 있다.
- Selenium IDE: firefox plug-in으로 브라우저를 통해 쉽게 testcase를 기록하고, 테스트를 할 수 있다. java/python/ruby와 같은 언어로 생성한 testcase를 추출해 낼 수도 있다.
- Nightwatch.js:
- Node.js를 기반으로 하는 browser 앱 테스트 솔루션이다. Selenium WebDriver API를 통해 브라우저에 명령을 내린다.
준비물
Selenium WebDriver를 통해 다양한 브라우저를 통한 UnitTest를 생성하고 테스트를 진행할 수 있다. 여기서는 Chrome을 통한 테스트를 만들어보도록 하자
1. Nightwatch.js
npm을 통해 설치하거나,
$ git clone git@github.com:nightwatchjs/nightwatch.git
$ cd nightwatch
$ npm install
2. Selenium WebDriver:
selenium다운로드 페이지에서 Selenium Standalong Server를 다운로드한다. jar로 되어 있기 때문에 JAVA가 설치되어 있어야 한다.
3. ChromeDriver - WebDriver for Chrome
시작하기
이제 테스트를 시작해보자. 테스트를 생성할 프로젝트 디렉토리를 만들고, 아래와 같이 testNightwatchjs/bin 디렉토리 아래에 Selenium Webdriver와 chromedriver를 둔다. 다음으로 testcase를 저장할 tests디렉토리를 만든다. 그리고 다음과 같이 nightwatch.json 으로 설정 파일을 만든다. 여기서 server_path와 webdrive.chrome.driver는 실제 파일이 있는 경로를 입력한다. 그리고 start_process 값을 true로 해 준다. 이 값을 false로 할 경우에는 selenium server를 별도로 수행하거나 localhost가 아닌 다른 컴퓨터에 selenium server가 존재할 경우 설정한다.
{
"src_folders" : ["tests"],
"output_folder" : "reports",
"custom_commands_path" : "",
"custom_assertions_path" : "",
"page_objects_path" : "",
"globals_path" : "",
"selenium" : {
"start_process" : true,
"server_path" : "./selenium-server-standalone-2.53.0.jar",
"log_path" : "",
"host" : "127.0.0.1",
"port" : 4444,
"cli_args" : {
"webdriver.chrome.driver" : "./chromedriver",
"webdriver.ie.driver" : ""
}
},
"test_settings" : {
"default" : {
"launch_url" : "http://localhost",
"selenium_port" : 4444,
"selenium_host" : "localhost",
"silent": true,
"screenshots" : {
"enabled" : false,
"path" : ""
},
"desiredCapabilities": {
"browserName": "firefox",
"javascriptEnabled": true,
"acceptSslCerts": true
}
},
"chrome" : {
"desiredCapabilities": {
"browserName": "chrome",
"javascriptEnabled": true,
"acceptSslCerts": true
}
}
}
}
다음으로 testcase코드를 만들어보자. tests 폴더 아래에 google.js파일을 다음과 같이 생성한다.
module.exports = {
'Demo test Google' : function (browser) {
browser
.url('http://www.google.com')
.waitForElementVisible('body', 1000)
.setValue('input[type=text]', ['nightwatch', browser.Keys.ENTER])
.waitForElementVisible('button[name=btnG]', 3000)
.click('button[name=btnG]')
.pause(1000)
.assert.containsText('#main', 'Night Watch')
.end();
}
};
여기까지 하면 디렉토리 구조가 다음과 같다.
testNightwatchjs/
├── bin
│ ├── chromedriver
│ └── selenium-server-standalone-2.53.0.jar
├── nightwatch.json
└── tests
└── google.js
이제 nightwatch를 콘솔에서 입력해 테스트를 수행해보자. firefox 브라우저가 실행되고 google에서 nightwatch를 검색하고 테스트를 마친다.
nightwatch
Starting selenium server... started - PID: 95618
[Google] Test Suite
===================
Running: Demo test Google
✔ Element <body> was visible after 270 milliseconds.
✔ Element <button[name=btnG]> was visible after 1060 milliseconds.
✔ Testing if element <#main> contains text: "Night Watch".
OK. 3 assertions passed. (9.792s)
reports 디렉토리가 생기고, 그 아래에 테스트를 구행한 브라우저와 os, testcase이름으로 된 파일에 테스트 수행결과가 정리되어 있음을 확인할 수 있다.
testNightwatchjs/
├── bin
│ ├── chromedriver
│ └── selenium-server-standalone-2.53.0.jar
├── nightwatch.json
├── reports
│ ├── CHROME_49.0.2623.87_MAC_google.xml
│ └── FIREFOX_45.0.1_MAC_google.xml
├── selenium-debug.log
└── tests
└── google.js
chrome으로 테스트를 수행하기 위해서는 다음과 같이 명령을 내리면 된다.
firefox와 chrome으로 테스트를 수행하기 위해서는 다음과 같이 명령을 내리면 된다.
nightwatch --env default,chrome
이런 명령도 가능하다.
nightwatch --env default,chrome,chrome,chrome,chrome
테스트 케이스를 만들기 위해서는 화면 내에서 특정 요소를 선택해, 다음과 같은 작업들을 수행해 테스트케이스를 만든다.
- 동작을 수행
- 값을 변경
- 원하는 요소가 맞는지 확인
이와 관련한 자료들은 쉽게 찾을 수 있기 때문에 여기서는 생략하고 웹서비스 페이지 내에서 Javascript Ojbect값을 검사하는 코드예제를 살펴보자. Nightwatch.js의 execute명령을 통해 브라우저에서 javascript 코드를 수행하고, 이 결과를 testcase에서 얻어올 수 있다. 아래 코드는 페이지에서 user Object를 받아서 name이 'testname'이고, id가 'testid'인지 확인한다.
client.execute("return window.user;", [], function(response) {
var loginUser = response.value;
this.assert.ok(loginUser.name, 'testname');
this.assert.ok(loginUser.id, 'testid');
});
참고
http://nightwatchjs.org/guide
http://www.slideshare.net/sethmcl/join-the-darkside-nightwatchjs
http://techblog.daliworks.net/Nightwatchjs/
http://techblog.daliworks.net/Nightwatchjs-part2/