前端自動化測試(一)

目前開發大型應用,測試是一個很是重要的環節,可是大多數前端開發者對測試相關的知識是比較缺少的。由於可能項目開發週期短根本沒有機會寫,因此你沒有辦法體會到前端自動化測試的重要性。javascript

來講說爲何前端自動化測試如此重要!前端

先看看前端常見的問題:java

  • 修改某個模塊功能時,其它模塊也受影響,很難快速定位bug
  • 多人開發代碼愈來愈難以維護
  • 不方便迭代,代碼沒法重構
  • 代碼質量差

增長自動化測試後:node

  • 咱們爲核心功能編寫測試後能夠保障項目的可靠性
  • 強迫開發者編寫更容易被測試的代碼,提升代碼質量
  • 編寫的測試有文檔的做用,方便維護

1.測試簡介

1.1 黑盒測試和白盒測試

  • 黑盒測試通常也被稱爲功能測試,黑盒測試要求測試人員將程序看做一個總體,不考慮其內部結構和特性,只是按照指望驗證程序是否能正常工做
  • 白盒測試是基於代碼自己的測試,通常指對代碼邏輯結構的測試。

1.2 測試分類

單元測試(Unit Testing) es6

單元測試是指對程序中最小可測試單元進行的測試,例如測試一個函數一個模塊一個組件...web

集成測試(Integration Testing) npm

將已測試過的單元測試函數進行組合集成暴露出的高層函數或類的封裝,對這些函數或類進行的測試json

端到端測試(E2E Testing)
打開應用程序模擬輸入,檢查功能以及界面是否正確瀏覽器

1.3 TDD & BDD

TDD是測試驅動開發(Test-Driven Development)bash

TDD的原理是在開發功能代碼以前,先編寫單元測試用例代碼

BDD是行爲驅動開發(Behavior-Driven Development)

系統業務專家、開發者、測試人員一塊兒合做,分析軟件的需求,而後將這些需求寫成一個個的故事。開發者負責填充這些故事的內容,保證程序實現效果與用戶需求一致。

小結:

TDD是先寫測試再開發 (通常都是單元測試,白盒測試);而BDD則是按照用戶的行爲來開發,再根據用戶的行爲編寫測試用例 (通常都是集成測試,黑盒測試)

1.4 測試框架

  • Karma:Karma爲前端自動化測試提供了跨瀏覽器測試的能力,能夠在瀏覽器中執行測試用例
  • Mocha:前端自動化測試框架,須要配合其餘庫一塊兒使用,像chai、sinon...
  • Jest:Jest 是Facebook推出的一款測試框架,集成了 Mocha,chai,jsdom,sinon等功能。
  • ...

看到這裏Facebook 都在推Jest,你還不學嗎? Jest也有一些缺陷就是不能像Karma這樣直接跑在瀏覽器上,它採用的是jsdom,優點是簡單、0配置! 後續咱們經過Jest來聊聊前端自動化測試。

2.Jest的核心應用

在說Jest測試以前,先來看看之前咱們是怎樣測試的

const parser = (str) =>{
    const obj = {};
    str.replace(/([^&=]*)=([^&=]*)/g,function(){
        obj[arguments[1]] = arguments[2];
    });
    return obj;
}
const stringify = (obj) =>{
    const arr = [];
    for(let key in obj){
        arr.push(`${key}=${obj[key]}`);
    }
    return arr.join('&');
}
// console.log(parser('name=webyouxuan')); // {name:'webyouxuan'}
// console.log(stringify({name:'webyouxuan'})) // name=webyouxuan

咱們每寫完一個功能,都先須要手動測試功能是否正常,測試後可能會將測試代碼註釋起來,這樣會產生一系列問題。由於會污染源代碼,全部的測試代碼和源代碼混合在一塊兒。若是刪除掉,下次測試還須要從新編寫。

因此測試框架就幫咱們解決了上述的問題

2.1 分組、用例

Jest是基於模塊的,咱們須要將代碼包裝成模塊的方式,分別使用 exportparserstringify這兩個方法導出。

安裝jest

npm init -y # 初始化pacakge.json
npm i jest

咱們創建一個qs.test.js來專門編寫測試用例,這裏的用例你能夠認爲就是一條測試功能 (後綴要以.test.js結尾,這樣jest測試時默認會調用這個文件)。

import {parser,stringify} from './qs';

it('測試 parser 是否能正常解析結果',()=>{
    // expect 斷言,判斷解析出來的結果是否和 {name:'webyouxuan'}相等
    expect(parser(`name=webyouxuan`)).toEqual({name:'webyouxuan'});
})

jest默認自帶斷言功能,斷言的意思就是判斷是否是這個樣子,我判定你今天沒吃飯~,結果你吃了,說明此次斷言就失敗了,測試就沒法經過。

經過配置scripts 來執行命令

"scripts": {
    "test": "jest"
}

執行 npm run test,惋惜的是默認在node環境下不支持es6模塊的語法,須要babel轉義,固然你也能夠直接使用commonjs規範來導出方法,由於大多數如今開發都採用es6模塊,因此安裝一下便可。

# core是babel的核心包 preset-env將es6轉化成es5
npm i @babel/core @babel/preset-env --save-dev

而且須要配置.babelrc文件,告訴babel用什麼來轉義

{
    "presets":[
        [
            "@babel/preset-env",{
                "targets": {"node":"current"}
            }
        ]
    ]
}

默認Jest中集成了babel-jest,運行時默認會調用.babelrc進行轉義,能夠直接將es6轉成es5語法。
運行 npm run test 出現:

test

繼續編寫第二個用例

import {parser,stringify} from './qs';
describe('測試qs 庫',()=>{
    it('測試 parser 是否能正常解析結果',()=>{
        expect(parser(`name=webyouxuan`)).toEqual({name:'webyouxuan'});
    });
    
    it('測試 stringify 是否正常使用stringify',()=>{
        expect(stringify({name:'webyouxuan'})).toEqual(`name=webyouxuan`)
    })
});
describe的功能是給用例分組,這樣能夠更好的給用例分類,其實這就是咱們所謂的單元測試,對某個具體函數和功能進行測試。

2.2 matchers匹配器

在寫第一個測試用例時,咱們一直在使用toEqual其實這就是一個匹配器,那咱們來看看jest中經常使用的匹配器有哪些?由於匹配器太多了,因此我就講些經常使用的!

爲了方便理解,我把匹配器分爲三類:判斷相等、不等、是否包含。

it('判斷是否相等',()=>{
    expect(1+1).toBe(2); // 至關於 js中的===
    expect({name:'webyouxuan'}).toEqual({name:'webyouxuan'}); // 比較內容是否相等
    expect(true).toBeTruthy(); // 是否爲 true / false 也能夠用toBe(true)
    expect(false).toBeFalsy();
});

it('判斷不相等關係',()=>{
    expect(1+1).not.toBe(3); // not取反
    expect(1+1).toBeLessThan(5); // js中的小於
    expect(1+1).toBeGreaterThan(1); // js中的大於
});

it('判斷是否包含',()=>{
    expect('hello world').toContain('hello'); // 是否包含
    expect('hello world').toMatch(/hello/); // 正則
});

2.3 測試操做節點方法

說了半天,咱們本身來寫個功能測試一下!

export const removeNode = (node) => {
    node.parentNode.removeChild(node)
};

核心就是測試傳入一個節點,這個節點是否能從DOM中刪除

import { removeNode } from './dom'
it('測試刪除節點',()=>{
    document.body.innerHTML = `<div><button data-btn="btn"></button</div>`
    let btn = document.querySelector('[data-btn="btn"]')
    expect(btn).not.toBeNull()
    removeNode(btn);
    btn = document.querySelector('[data-btn="btn"]');
    expect(btn).toBeNull()
})

這個就是咱們所說的jsdom,在node中操做DOM元素

2.4 Jest經常使用命令

咱們但願每次更改測試後,自動從新執行測試,修改執行命令:

"scripts": {
    "test": "jest --watchAll"
}

從新執行 npm run test,這時就會監控用戶的修改

修改

提示咱們按下w,顯示更多信息

w

這裏我把每一個命令的含義都列好了,有須要能夠本身嘗試一下~

想要知道如何測試異步邏輯,如何mock接口數據,如何深度使用Jest嗎?敬請期待下期文章!

圖片描述

相關文章
相關標籤/搜索