Zombie.js 是一個(gè)node.js環(huán)境下轻抱,非常小巧高效率的Web UI Automation Test庫(kù).本文將介紹如何使用Zombie.js對(duì)Web UI進(jìn)行自動(dòng)化測(cè)試.
本文使用到的環(huán)境:
快速預(yù)覽Zombie.js測(cè)試
const Browser = require('zombie');
Browser.localhost('example.com', 3000);
describe('User visits signup page', function() {
const browser = new Browser();
before(function(done) {
browser.visit('/signup', done);
});
describe('submits form', function() {
before(function(done) {
browser
.fill('email', 'zombie@underworld.dead')
.fill('password', 'eat-the-living')
.pressButton('Sign Me Up!', done);
});
it('should be successful', function() {
browser.assert.success();
});
it('should see welcome page', function() {
browser.assert.text('title', 'Welcome To Brains Depot');
});
});
});
Zombie.js適用場(chǎng)景
好的方面
Zombie.js與傳統(tǒng)的Selenium和PhandomJS不同,它不會(huì)啟動(dòng)真正的瀏覽器评汰,使得測(cè)試運(yùn)行效率媲美單元測(cè)試梧躺。 Zombile.js默認(rèn)采用mocha風(fēng)格編寫(xiě)測(cè)試栓袖,無(wú)需再為WebDriver做額外的配置,如果你熟悉mocha, Zombie.js將是開(kāi)箱即用的庫(kù).
Features
- 模擬瀏覽器行為
- Assertions, 可以采用jQuery的Selector對(duì)dom進(jìn)行assert
- Cookies
- Ajax & WebSocket
限制
由于Zombie.js沒(méi)有真正啟動(dòng)傳統(tǒng)的WebDriver, 因此過(guò)于復(fù)雜的場(chǎng)景將會(huì)無(wú)法測(cè)試. 例如时捌,如何對(duì)高德地圖經(jīng)測(cè)試,我還沒(méi)有找到好的方法.
安裝Zombie.js
npm install -g mocha
npm install zombie --save-dev
由于本文使用coffeescript代替javascript, 還需要安裝coffeescript環(huán)境
npm install -g coffee-script
編寫(xiě)第一個(gè)測(cè)試
Brower = require 'zombie'
Brower.localhost('yourdomain.com', 5000)
describe 'User visits login page', () ->
browser = new Brower()
before (done) ->
browser.visit '/login', done
describe 'submits login form', () ->
before (done) ->
browser
.fill 'username', 'xxxx@mail.com'
.fill 'password', 'password'
.pressButton('登錄', done)
it 'should be successful', () ->
browser.assert.success()
it 'should visit admin page', () ->
browser.assert.url /^http:\/\/yourdomain\.com\/users\/\d\/admin/
it 'should see profile button with email', () ->
browser.assert.link('#profile-button', 'xxxx@mail.com', '#')
運(yùn)行測(cè)試:
- 開(kāi)啟你的web server
- 運(yùn)行測(cè)試
mocha --harmony --compilers coffee:coffee-script/register login_spec.coffee
由于Zombie.js使用到了ECMA 6,需要使用 --harmony 參數(shù)開(kāi)啟 node.js 對(duì)ECMA 6語(yǔ)法支持.
使用Gulp.js構(gòu)建Build Pipeline
通常我們會(huì)講自動(dòng)化測(cè)試加入到build pipeline中. 這里將介紹將 Express.js + Zombie.js + gulp.js的配置方法.
Build pipeline策略
- checkstyle, 檢查代碼格式
- 運(yùn)行unit test
- compile coffeescript -> javascript
- 啟動(dòng)server
- 運(yùn)行automation test
- 出錯(cuò)或者結(jié)束測(cè)試,停止server
由于gulp-develop-server無(wú)法用coffeescript啟動(dòng)server,所以需要添加compile步驟.
express.js項(xiàng)目結(jié)構(gòu)組織
├── acceptence-test // automation test代碼
│ ├── admin_spec.coffee
│ └── login_spec.coffee
├── app //后臺(tái)app代碼 coffeescript
├── bin
├── config
├── dist //coffeescript編譯后的js代碼
├── gulpfile.coffee
├── gulpfile.js
├── node_modules
├── package.json
├── public
├── spec // unit test代碼
│ ├── activities_spec.coffee
│ ├── auth_spec.coffee
│ └── projects_spec.coffee
└── views
安裝依賴
npm install -g gulp
npm install gulp-mocha gulp-coffee gulp-coffeelint gulp-sync gulp-task-listing gulp-develop-server harmonize --save-dev
- harmonize: 使gulp支持ECMA 6
- gulp-develop-server: 用于啟動(dòng)node.js connect based Web Server
- gulp-sync: 用于同步運(yùn)行tasks
- gulp-task-listing: 為gulp.js添加help支持脆丁, 可以列出gulpfile中的所有tasks.
配置gulpfile
require("harmonize")()
gulp = require 'gulp'
gulpsync = require('gulp-sync')(gulp)
server = require 'gulp-develop-server'
coffeelint = require 'gulp-coffeelint'
mocha = require 'gulp-mocha'
karma = require 'gulp-karma'
coffee = require 'gulp-coffee'
task_listing = require('gulp-task-listing')
gulp.task 'help', task_listing.withFilters null, 'sync'
gulp.task 'coffee:lint', ->
gulp.src(['app/**/*.coffee', './*.coffee'])
.pipe(coffeelint('config/coffeelint.json'))
.pipe(coffeelint.reporter())
.pipe(coffeelint.reporter('fail'))
gulp.task 'coffee:compile', ['coffee:lint'], ->
gulp.src ['app.coffee', './app/**/*.coffee']
.pipe coffee()
.pipe gulp.dest('./dist')
gulp.task 'test:unit', ['coffee:lint'], ->
gulp.src('spec/**/*.coffee')
.pipe(mocha(reporter: 'spec'))
gulp.task 'test:ui', ['coffee:compile'], ->
server.listen path: './dist/app.js'
gulp.src('acceptence-test/**/*.coffee')
.pipe(mocha(reporter: 'spec'))
.on 'error', () -> server.kill()
.on 'end', () -> server.kill()
gulp.task 'test', gulpsync.sync(['test:unit', 'test:ui']), ->
gulp.task 'clean', ->
console.log 'clean task...'
gulp.task 'default', ['clean'], ->
gulp.start 'test'
運(yùn)行測(cè)試
gulp test:ui
運(yùn)行結(jié)果
[11:03:21] Starting 'coffee:lint'...
[11:03:22] Finished 'coffee:lint' after 184 ms
[11:03:22] Starting 'coffee:compile'...
[11:03:22] Finished 'coffee:compile' after 114 ms
[11:03:22] Starting 'test:ui'...
server listening on 5000
[11:03:22] Development server listening. (PID:6427)
User visit admin projects page
and has login
when click profile button
? should see dropdown menu
? should see project admin item
? should see logout item
when click project admin link
? should visit to admin page
when click logout link
? should logout
? should redirect to login page
User visits login page
submits login form
? should be successful
? should visit admin page
? should see profile button with email
9 passing (6s)
[11:03:28] Finished 'test:ui' after 6.08 s
[11:03:28] Development server was stopped. (PID:6427)
由于已經(jīng)將test:ui加入到default task中. 直接運(yùn)行 gulp
便可運(yùn)行所有測(cè)試.