記一個前端自動化測試解決方案探析

前端測試一直是前端項目開發過程當中及其重要的一個環節,高效的測試方法能夠減小咱們進行代碼自測的時間,提升開發效率,若是你的代碼涉及的測試用例較多,並且項目須要長期維護,這時就能夠考慮使用一下自動化測試了。css

1、前端自動化測試html

  前端自動化測試通常是指是在預設條件下運行前端頁面或邏輯模塊,評估運行結果。預設條件應包括正常條件和異常條件,以達到自動運行測試過程、減小或避免人工干預測試的目的。在前端自動化測試中,咱們一般是經過不一樣的工具來解決不一樣場景下不一樣的問題的。就測試類型來看,主要分爲BDD(Bebavior Driven Developement,行爲驅動測試)和TDD(Testing Driven Developement,測試驅動開發)。BDD可讓項目成員(甚至是不懂編程的)使用天然描述語言來描述系統功能和業務邏輯,從而根據這些描述步驟進行系統自動化的測試;TDD則要求在編寫某個功能的代碼以前先編寫測試代碼,而後只編寫使測試經過的功能代碼,經過測試來推進整個開發的進行。這有助於編寫簡潔可用和高質量的代碼,並加速實際開發過程前端

  BDD和TDD均有各自的適用場景,BDD通常更偏向於系統功能和業務邏輯的自動化測試設計,而TDD在快速開發並測試功能模塊的過程當中則更加高效,以快速完成開發爲目的。下面咱們看下BDD和TDD具體的特色:node

  BDD的特色: - 從業務邏輯的角度定義具體的輸入與預期輸出,以及可衡量的目標; - 儘量覆蓋全部的測試用例狀況; - 描述一系列可執行的行爲,根據業務的分析來定義預期輸出。例如,expect, should, assert; - 設定關鍵的測試經過節點輸出提示,便於測試人員理解; - 最大程度的交付出符合用戶指望的產品,避免輸出不一致帶來的問題。jquery

TDD的特色:需求分析,快速編寫對應的輸入輸出測試腳本;實現代碼讓測試爲成功;重構,而後重複測試,最終讓程序符合全部要求。git

2、單元測試解決方案github

  就前端而言,單元測試的實現工具比較多。主要有mocha,jasmine和qunit。咱們先來看看使用mocha是怎樣實現單元測試的。web

·mocha面試

mocha的特色是簡單可擴展、支持瀏覽器和Node、支持同步和異步、支持連續用例測試。測試集,以函數describe(string, function)封裝;測試用例,以it(string, function)函數封裝,它包含2個參數;斷言,以assert語句表示,返回true或false。另外,mocha在完成異步測試用例時經過done()來標記。chrome

  $ npm install mocha

  $ mkdir test

  $ $EDITOR test/test.js # or open with your favorite editor

  測試用例:

  var assert = require('assert');

  describe('Array', function() {

  describe('#indexOf()', function() {

  it('should return -1 when the value is not present', function() {

  assert.equal(-1, [1,2,3].indexOf(4));

  });

  });

  });

  輸出爲:

  $ ./node_modules/mocha/bin/mocha

  Array

  #indexOf()

  ? should return -1 when the value is not present

  1 passing (9ms)

  同時,mocha支持異步和Promise。

  describe('#find()', function() {

  it('respond with matching records', function(done) {

  db.find({type: 'User'}, function(err, res) {

  if (err) return done(err);

  res.should.have.length(3);

  done();

  });

  });

  });

  });

· jasmine

  jasmine是一個BTT的框架,不依賴其它框架。測試集以函數describe(string, function)封裝;測試用例,以it(string, function)函數封裝,它也包含2個參數;斷言,以expect語句表示,返回true或false;斷言的比較操做時,將Expectation傳入的實際值和Matcher傳入的指望值比較,另外任何Matcher都能經過在expect調用Matcher前加上not來實現一個否認的斷言(expect(a).not().toBe(false);)

若是對軟件測試、接口測試、自動化測試、面試經驗交流。感興趣能夠加軟件測試交流:1085991341,還會有同行一塊兒技術交流。

  describe("A suite is just a function", function() {

  var a;

  it("and so is a spec", function() {

  a = true;

  expect(a).toBe(true);

  expect(a).not().toBe(false);

  });

  });

  jasmine也支持異步測試用例。

describe("long asynchronous specs", function() {

beforeEach(function(done) {

done();

}, 1000);

it("takes a long time", function(done) {

setTimeout(function() {

done();

}, 9000);

}, 10000);

afterEach(function(done) {

done();

}, 1000);

});

· qunit

  qunit是一個可基於jquery的簡單測試框架,主要運行在瀏覽器端。它經過QUnit.test定義一個測試集,一個測試集中經過回調函數裏面多個斷言判斷來實現多個測試用例,使用起來很是簡單。

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

<meta name="viewport" content="width=device-width">

<title>QUnit Example</title>

<link rel="stylesheet" href="https://code.jquery.com/qunit/qunit-2.0.1.css">

</head>

<body>

<div id="qunit"></div>

<div id="qunit-fixture"></div>

<script src="https://code.jquery.com/qunit/qunit-2.0.1.js"></script>

<script>

QUnit.test( "hello test", function( assert ) {

assert.ok( 1 == "1", "Passed!" );

assert.equal( null, false, "null, false; equal fails" );

});

</script>

</body>

</html>

  qunit也支持異步測試用例,異步完成時經過done()來結束。

  QUnit.test( "assert.async() test", function( assert ) {

  var done = assert.async();

  var input = $( "#test-input" ).focus();

  setTimeout(function() {

  assert.equal( document.activeElement, input[0], "Input was focused" );

  done();

  });

  });

  小結一下,單元測試工具的主要組成部分實際上是相似的,主要包括測試集、測試用例、斷言和斷言比較等。它能夠用來快速測試單元模塊的主要功能,有助於輔助咱們快速開發。

3、集成化測試解決方案

  除了模塊單元的測試驅動開發,在系統功能測試階段,咱們但願自動化完成業務功能正確性的檢測,此時咱們就要考慮集成測試方案了。目前前端集成化測試自動化工具也有比較多。例如CasperJS、Nighmare、Nightwatch、Dalekjs,咱們來逐個看下。

· casperJS

  casperJS基於PhantomJS或SlimerJS(PhantomJS或SlimerJS都是用於web測試的自動化無界面瀏覽器),能夠模擬完成頁面內系統級的自動化操做行爲測試。

  var casper = require('casper').create();

  casper.start('http://casperjs.org/');

  casper.then(function() {

  this.echo('First Page: ' + this.getTitle());

  });

  casper.thenOpen('http://phantomjs.org', function() {

  this.echo('Second Page: ' + this.getTitle());

  });

  casper.run();

  輸出內容爲:

  $ casperjs sample.js

  First Page: CasperJS - a navigation scripting & testing utility for PhantomJS and SlimerJS written in Javascript

  Second Page: PhantomJS | PhantomJS

  頁面內的操做結合casper的操做就能夠這樣來實現。

var casper = require('casper').create();

var links;

function getLinks() {

// Scrape the links from top-right nav of the website

var links = document.querySelectorAll('ul.navigation li a');

return Array.prototype.map.call(links, function (e) {

return e.getAttribute('href')

});

}

// Opens casperjs homepage

casper.start('http://casperjs.org/');

casper.then(function () {

links = this.evaluate(getLinks);

});

casper.run(function () {

for(var i in links) {

console.log(links[i]);

}

casper.done();

});

 · Nightmare

  相似的,nightmare也是一個模擬還原瀏覽器上業務操做的強大工具,並且更易於使用。同時可使用chrome的插件daydreem自動錄製生成用戶行爲操做的事件序列,更加方便咱們進行實際的測試。

  yield Nightmare()

  .goto('http://yahoo.com')

  .type('input[title="Search"]', 'github nightmare')

  .click('.searchsubmit');

  Nightmare也支持異步操做,並支持多種斷言庫,這裏結合chai.js就能夠這樣來使用。

var Nightmare = require('nightmare');

var expect = require('chai').expect; // jshint ignore:line

describe('test yahoo search results', function() {

it('should find the nightmare github link first', function(done) {

var nightmare = Nightmare()

nightmare

.goto('http://yahoo.com')

.type('form[action*="/search"] [name=p]', 'github nightmare')

.click('form[action*="/search"] [type=submit]')

.wait('#main')

.evaluate(function () {

return document.querySelector('#main .searchCenterMiddle li a').href

})

.end()

.then(function(link) {

expect(link).to.equal('https://github.com/segmentio/nightmare');

done();

})

});

});

 · Nightwatch

  Nightwatch則可使用node書寫端對端的測試用例,並在Selenium server服務端運行測試,一樣支持同步和異步。

this.demoTestGoogle = function (browser) {

browser

.url('http://www.google.com')

.waitForElementVisible('body', 1000)

.setValue('input[type=text]', 'nightwatch')

.waitForElementVisible('button[name=btnG]', 1000)

.click('button[name=btnG]')

.pause(1000)

.assert.containsText('#main', 'The Night Watch')

.end();

};

 · Dalekjs

  DalekJS是一個跨瀏覽器平臺的前端集成測試框架,能夠自動配置啓動本地的瀏覽器,也能夠模擬填寫提交表單、點擊、截屏、運行單元測試等豐富的操做。

module.exports = {

'Amazon does its thing': function (test) {

test

.open('http://www.amazon.com/')

.type('#twotabsearchtextbox', 'Blues Brothers VHS')

.click('.nav-submit-input')

.waitForElement('#result_0')

.assert.text('#result_0 .newaps a span').is('The Blues Brothers')

.done();

}

};

test.open('http://adomain.com')

.click('#aquestion')

.answer('Rose')

.assert.text('#aquestion').is('Rose', 'Awesome she was!')

.done();

  小結一下,和單元測試相同的是,集成測試和單元測試相似,通常也會對測試預期輸出進行斷言和判斷,不一樣的是,集成測試的輸入設計和功能流程中涉及到瀏覽器自己的行爲模擬,用以代替測試人員手動操做的過程,從而可以提升測試效率。

4、總結與注意事項

  經過對單元測試工具和集成測試工具的概述介紹,咱們基本瞭解了單元測試和集成測試的核心部分和特色,儘管目前主流的測試工具各不相同,可是基本的流程原理確實相同的,上面小結裏面也爲你們作了分析。

  固然,還有一些仍須要咱們注意的問題。自動化測試不可避免地要求咱們去編寫測試用例,會花去必定的事件,咱們在實際的項目開發過程當中,決定要不要使用自動化的測試方案應該根據具體的場景來決定,若是業務規模並不複雜,並且系統功能流程清晰,則不建議使用測試用例,由於這樣得不償失;但若是業務達到必定規模,須要在原有較大項目繼續維護開發的狀況下,編寫測試用例有利於咱們較快暴露和定位問題,並極有助於後期的維護。

以上內容但願對你有幫助,有被幫助到的朋友歡迎點贊,評論。

相關文章
相關標籤/搜索