FE.TEST-前端測試初探

clipboard.png

前言

測試能夠提供快速反饋,根據測試用例覆蓋代碼,從而提高代碼開發效率和質量。根據投入產出價值,一般迭代較快的業務邏輯不作測試用例,對通用經常使用的代碼基本組件或框架須要編寫測試。javascript

在 2018 年年初對測試工具的總體回顧:
An Overview of JavaScript Testing in 2018html

測試與開發

TDD 測試驅動開發

測試驅動開發的基本思想就是在開發功能代碼以前,先編寫測試代碼。也就是說在明確要開發某個功能後,首先思考如何對這個功能進行測試,並完成測試代碼的編寫,而後編寫相關的代碼知足這些測試用例。而後循環進行添加其餘功能,直到徹底部功能的開發。(mocha示例)前端

//mocha
suite('Array', function() {
  setup(function() {
    // ...
  });

  suite('#indexOf()', function() {
    test('should return -1 when not present', function() {
      assert.equal(-1, [1,2,3].indexOf(4));
    });
  });
});

BDD 行爲驅動開發

Behavior Driven Development,行爲驅動開發是一種敏捷軟件開發的技術,它鼓勵軟件項目中的開發者、QA和非技術人員或商業參與者之間的協做。

與通常的自動化測試(如單元測試、服務測試、UI 測試)不同的是,BDD 是由多方參與的測試開發方式。如在使用 Protractor 寫 Angular 的 E2E 測試的時候,因此的測試都是前端測試人員編寫的。BDD 最重要的一個特性是:由非開發人員編寫測試用例,而這些測試用例是使用天然語言編寫的 DSL(領域特定語言)。換多話來講,業務人員、測試人員、客戶等利益相關者,以習慣的方式編寫相關的測試用例,再由開發人員去實現相關的測試。
(Jasmine示例)vue

//Jasmine
describe("A suite is just a function", function() {
  var a;

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

    expect(a).toBe(true);
  });
});

單元測試 Unit Testing

單元測試準則27條java

斷言庫

const assert = require('assert');
assert.equal(1, '1');//ok

const obj1 = {a: {b: 1}};
const obj2 = {a: {b: 1}};
assert.deepEqual(obj1, obj2);//ok
should(null).not.be.ok();
({ a: 10}).should.be.eql({ a: 10 });
'ab'.should.be.equalOneOf(['a', 10, 'ab']);
//should
chai.should();

foo.should.be.a('string');
foo.should.equal('bar');
foo.should.have.lengthOf(3);
tea.should.have.property('flavors')
  .with.lengthOf(3);
//except
var expect = chai.expect;
expect(foo).to.be.a('string');
expect(foo).to.equal('bar');
expect(foo).to.have.lengthOf(3);
expect(tea).to.have.property('flavors')
  .with.lengthOf(3);
//assert
var assert = chai.assert;
assert.typeOf(foo, 'string');
assert.equal(foo, 'bar');
assert.lengthOf(foo, 3)
assert.property(tea, 'flavors');
assert.lengthOf(tea.flavors, 3);

模擬響應數據

Mocknode

Mock.mock({"number|1-100": 100})
//{"number": 30}
Mock.mock({'regexp': /\d{5,10}/})
//{"regexp": "365355673"}
Mock.mock({
  "object|2-4": {
    "110000": "北京市",
    "120000": "天津市",
    "130000": "河北省",
    "140000": "山西省"
  }
})
/*
{
  "object": {
    "120000": "天津市",
    "130000": "河北省",
    "140000": "山西省"
  }
}
*/
Random.date()
//"2007-10-24"
Random.image('200x100', '#4A7BF7', 'Hello')

端到端測試 End to End Testing

cypress 在瀏覽器中邊預覽執行可視化測試用例,像selenium同樣模擬用戶操做,能夠接入Mocha和chaireact

describe('My First Test', function() {
  it('clicking "type" navigates to a new url', function() {
    cy.visit('https://example.cypress.io')

    cy.contains('type').click()

    // Should be on a new URL which includes '/commands/actions'
    cy.url().should('include', '/commands/actions')
  })
})

模擬瀏覽器交互

Nightmare
基於 Electron 的框架,針對 Web 自動化測試和爬蟲。git

webdriverio
Node.js的下一代WebDriver測試自動化框架,參考官方代碼示例github

性能測試 Performance Testing

jsPerf
benchmark.jsweb

持續集成 Continuous Integration

持續集成是一種很是優秀的多人開發實踐,經過代碼push觸發鉤子,實現自動運行編譯、測試等工做。接入持續集成後,咱們的每一次push代碼,每一個Merge Request都會生成對應的測試結果,項目的其餘成員能夠很清楚地瞭解到新代碼是否影響了現有的功能,在接入自動告警後,能夠在代碼提交階段就快速發現錯誤,提高開發迭代效率。

持續集成會在每次集成時提供一個幾乎空白的虛擬機器,並拷貝用戶提交的代碼到機器本地,經過讀取用戶項目下的持續集成配置,自動化的安裝環境和依賴,編譯和測試完成後生成報告,在一段時間以後釋放虛擬機器資源。

Travel CI 開源持續集成構建項目,採用yaml格式。

Coveralls nodejs下面的代碼測試覆蓋率,原理是經過istanbul生成測試數據,上傳到coveralls網站上,而後以badge的形式展現出來

代碼風格

目前比較流行js校驗工具備 JSLint、JSHint、JSCS、ESLint, 它們以前的差別比較能夠參考 A Comparison of JavaScript Linting Tools,推薦使用
ESlint
代碼風格檢查一樣也能夠集成到 ci,只須要在 ci 命令前追加檢查命令便可。以 eslint 爲例:

"scripts": {
    // ..
    "lint": "eslint .",
    "cov": "istanbul cover .",
    "ci": "tnpm run lint && TEST_TIMEOUT=60000 istanbul cover ."
 }

此時構建會先作代碼風格檢查,再作單元測試、覆蓋率統計,如代碼風格檢查失敗,會直接致使構建中斷。

流行的測試框架

Jest
Facebook 出品的一個測試框架,相對其餘測試框架,其一大特色就是就是內置了經常使用的測試工具,好比自帶斷言、測試覆蓋率工具。與React搭配更加。 (示例)

karma
一個測試集成框架,能夠方便地以插件的形式集成測試框架、測試環境、覆蓋率工具等等。與Angular搭配更加。(使用 vue-cli 能夠快速生成一個 Vue 項目,其中包含了 Webpack 和 Karma 以及覆蓋率統計的配置)

cucumber & cuketest
參考 一個建立 Cucumber. js 測試腳本的快速方法

其餘參考資料:
前端自動化測試概覽
E2E 測試之 Cypress
使用 Jest + Enzyme 對 React 項目進行單元測試
Testing Strategies for React and Redux

相關文章
相關標籤/搜索