前端必備測試技術總結

單元測試

目的:單元測試能夠讓開發者明確知道代碼結構
原則:單一職責、接口抽離、層次分離
斷言庫:保證最小單元是否正常運行檢測方法
測試風格:測試驅動開發(Test-Driven Development,TDD),行爲驅動開發(Behavior Driver Development,BDD),均是敏捷開發開發方法論。

  • TDD 關注所有功能十分被實現(每個功能必須有對應的測試用例),suite配合test利用assert('tobi' == user.name),即在開發前,有測試人員或其他人員將所有功能的測試用例編寫完成,評審通過後,再按照測試用例進行開發,這種對於測試用例是相當有導向性的
  • BDD關注整體行爲是否符合整體預期,編寫的每一行代碼都要目的提供一個全面的測試用例集。expect/should,describe配合it利用自然語言expect(1).toEqual(fn())執行結果,即開發完成後再編寫測試用例。

單元測試框架

  • better-assert(TDD斷言庫)
  • should.js、expect.js、Jasmine.js(BDD斷言庫)
  • Node本身集成的assert斷言庫
  • chai.js(TDD和BDD雙模)

單元測試運行流程

before -> before -> it -> after -> afterEach
每個測試用例組通過describe進行設置

  1. before每個測試用例(it)開始前
  2. beforeEach 每個測試用例開始前
  3. it定義測試用例並利用斷言庫進行設置chai如:expect(x).to.equal(true); 異步mocha
  4. 以上專業術語叫mock

karma的使用

  • 安裝全局karma腳手架
npm install -g karma-cli

首先在我們的項目中
使用命令

npm install karma --save-dev
  • 還需要安裝
npm install karma-jasmine jasmine-core --save-dev

先說一下這倆個包,karma-jasmine和jasmine-core是一對的,當我們有什麼karma-pack 後面就要安裝pack-core,是一對的,不能分開的

說明
自動化單元測試

karma自動化runner集成PhantomJS無刷新
npm install -g karma
npm install karma-cli --save-dev
npm install karma-chrome-launcher --save-dev
npm install karma-phantomjs-launcher --save-dev // 安裝無頭瀏覽器
npm install karma-mocha --save-dev
npm install karma-chai --save-dev

這裏還需要注意一個問題,因爲我們這裏是使用無頭瀏覽器
所以我們需要安裝一個無頭瀏覽器 , 需要哪個無頭瀏覽器就安裝哪個無頭瀏覽器

npm install karma-phantomjs-launcher --save-dev

e2e測試

由於現在nodejs可以驅動硬件的插件
插件selenium-webdriver
在測試文件夾下新建e2e/index.js

// e2e/index.js
const { Builder, By, Key, until } = require('selenium-webdriver');

(async function example() {
    let driver = await new Builder().forBrowser('firefox').build();
    try {
        await driver.get('http://www.baidu.com');
        await driver.findElement(By.name('wq')).sendKeys('測試', Key.RETURN);
        await driver.wait(until.titleIs('測試_百度搜索'), 1000);//Key.RETURN 綁定回車事件
    } finally {
        // 瀏覽器退出
        await driver.quit();
    }
})();

這裏還需要安裝一個插件 , 我們打開npmjs的selenium-webdriver插件頁面

 

TEST01.png

進入fireFox插件下載頁面下載完成後
將壓縮包放到項目根目錄下
然後在packag.json裏面添加一個e2e腳本

"scripts": {
    ...,
    "e2e": "node ./test/e2e/index.js",
    .....
}

然後使用命令npm run e2e , 他會自動打開瀏覽器執行我們上面寫的腳本
有哪些selenium-webdriver有很多API , 具體api在官網上
selenium-webdriver官網 https://selenium.dev/documentation/en/getting_started_with_webdriver/locating_elements/

提示 : 如果測試不通過他會顯示

 

TEST02.png

請求超時提示 , 表示返回的結果和預期不一樣
以上就是e2e測試的基本用法

UI測試

這裏介紹一個關於無頭瀏覽器的一個配對css測試庫 phantomcss , 但是這裏不使用這個庫

  1. 我們使用另外一個庫backstopjs
    首先安裝
npm install -g backstopjs // 全局
npm install  backstopjs --save-dev // 建議安裝本項目

添加運行命令 , 並運行命令

"scripts": {
    ...,
    "bsinit": "backstop init",
    .....
}
  1. 運行完bsinit命令後就會生成一個json文件和一個backstop_data文件

     

    TEST03.png

UI測試框架目錄介紹

├── backstop_data
│   └── bitmaps_reference //存儲樣板圖的地方
│   └── bitmaps_test  //截圖存儲的地方
│   └── engine_scripts //配置靜態服務器,自定義腳本casper/puppet/chromy
│       └──clickAndHoverHelper
│       └──loadCookies  
│       └──onBefore
│       └──onReady
│       └──waitForHelperHelper       
│   └── html_report  //執行test後彈出的html界面
├── backstop.json  //backstop的配置文件

backstop.json文件解釋

{
    //測試用例id,用於屏幕截圖命名。BackstopJS將自動爲您生成一個,以避免命名與BackstopJS資源的衝突。
    "id": "backstop_default",
    //測試視口,就是配置各種分辨率
    "viewports": [{
            "label": "phone", // iphone
            "width": 320,
            "height": 480
        },
        {
            "label": "phone", // iphone
            "width": 750,
            "height": 960
        },
        {
            "label": "tablet", //平板
            "width": 1024,
            "height": 768
        }
    ],
    //在執行所有腳本前、頁面加載後執行的腳本。通過他我們可以執行用express做一個靜態服務器 支持casper chromy puppet
    "onBeforeScript": "puppet/onBefore.js",
    "onReadyScript": "puppet/onReady.js",
    //測試用例
    "scenarios": [{
        "label": "BackstopJS Homepage", //測試名稱
        "cookiePath": "backstop_data/engine_scripts/cookies.json", //設置cookies
        "url": "https://garris.github.io/BackstopJS/", //所測試的url
        "referenceUrl": "", //創建引用時指定不同的狀態或環境。
        "readyEvent": "", //預定義的字符串記錄到控制檯來觸發屏幕捕獲。---實現異步交互
        "readySelector": "", //等到此選擇器存在後再繼續 ---實現異步交互
        "delay": 0, //等待幾秒後
        "hideSelectors": [], //設置爲visibility的選擇器數組:hidden
        "removeSelectors": [], //設置爲display的選擇器數組:none
        "hoverSelector": "", //滿足上述條件後 - 使用此腳本修改屏幕前的UI狀態鏡頭,例如懸停,點擊等
        "clickSelector": "", //在屏幕截圖之前單擊指定的DOM元素。
        "clickSelectors": "", // *僅限Puppeteer *獲取selctors數組 - 模擬多個順序點擊交互。
        "postInteractionWait": 0, //在與hoverSelector或clickSelector交互後等待選擇器(可選擇接受以ms爲單位的等待時間。想法用於單擊或懸停元素轉換。默認使用onReadyScript)
        "selectors": [], //選擇需要截圖的選擇器
        "selectorExpansion": true, //定位元素
        "expect": 0, //跟選擇器配合使用,說期望找到的選擇器的數量跟配置的數量是否匹配,不匹配的話表示測試失敗
        "misMatchThreshold": 0.1, //允許通過測試的不同像素的百分比
        "requireSameDimensions": true //測試必須與參考尺寸相同
    }],
    "paths": {
        "bitmaps_reference": "backstop_data/bitmaps_reference", //存儲樣板圖
        "bitmaps_test": "backstop_data/bitmaps_test", //截圖輸出路徑
        "engine_scripts": "backstop_data/engine_scripts", //js配置路徑
        "html_report": "backstop_data/html_report", //顯示對比圖的html
        "ci_report": "backstop_data/ci_report"
    },
    //報告的形式,支持命令行和瀏覽器兩種
    "report": ["browser"],
    "engine": "casper", //配置引擎屬性,slimerjs(Gecko / Mozilla,需要安裝),casper,chromy(webkit)
    "engineOptions": { //配置引擎屬性的默認值
        "casperFlags": [
            "--engine=slimerjs",
            "--proxy-type=http",
            "--proxy=proxyIp:port",
            "--proxy-auth=user:pass"
        ]
    },
    "asyncCaptureLimit": 5, //一次能捕獲5個屏幕
    "asyncCompareLimit": 50, //配置測試期間所需的RAM量
    //是否打印測試日誌
    "debug": false,
    "debugWindow": false,
    "resembleOutputOptions": {  //比較差異輸出圖片的配置
        "errorColor": {
            "red": 255,
            "green": 0,
            "blue": 255
        },
        "errorType": "movement",
        "transparency": 0.3,
        "ignoreAntialiasing": true
    }
}
  1. 然後繼續添加腳本命令
"scripts": {
    ...,
    "bsui": "backstop test",
    .....
}
  1. 然後修改backstop.json文件

     

    TEST04.png

  2. 這裏添加我們的所需要測試機型的寬高 , iphone和tablet是ipad端的意思

     

    TEST05.png

  1. 所需的cookie和所需測試的url地址

     

    TEST06.png

所需要測試的圖片下面就是backstop從我們工程截圖下來用作比對的圖片 , 是backstop工具自己截圖的
其他就不細說了

node端的測試

  1. 這裏使用mocha測試和mochawesome做測試圖表 , 具體的配置可查看npm官網 https://www.npmjs.com/package/mochawesome
    安裝好這兩個npm包後 , 我們在根目錄下新建一個文件mochaRunner.js ,
// mochaRunner.js
const Mocha = require('mocha')
const mocha = new Mocha({
    reporter: 'mochawesome',
    reporterOptions: {
        // reportFilename: 'customReportFilename',
        reportDir: 'doc/custom-report', // 用來存放
        //   quiet: true
    }
});
mocha.addFile('./test/service/router.spec.js'); // 這是我們需要測試的文件
mocha.run(function () {
    process.exit();
})
  1. 然後在test目錄下新建service -> app.js和service -> router.spec.js , 代碼如下
// app.js 一個簡單的http服務
const express = require('express')
const app = express();
app.get('/', function(req, res){
    res.send({
        data: '123'
    })
    res.end()
})
const listen = app.listen(3000, function(){
    console.log('listen 3000');
    
})
module.exports = app
  1. 編寫測試代碼
// router.spec.js
const superagant = require('supertest');


const app = require('./app');
function request() {
    return superagant(app.listen());
    
}
describe('node接口測試',function(){
    it('接口測試', function (done) {
        request()
            .get('/')
            .expect(200)
            .expect("Content-Type", /json/)
            .end(function  (err, res) {
                if(err) done(err)
                if(res.body.data === '123'){
                    console.log(res,'res');
                    
                    done()
                }else{
                    done(new Error('接口數據異常'))
                }
            })
    })
})
  1. 然後在package.json添加腳本文件 , 運行命令 , 即可
"scripts": {
    ...,
    "service": "node ./mochaRunner.js",
    .....
}

總結 : 當然以上都是一些非常簡單且相對比較繁瑣的工作 , 一般工程是不會做這種工作的 , 因爲這樣的編碼速度太低了
我們工程真正做e2e的時候工程一般使用 night watch , 爲了避免工程太大 , 這樣寫e2e編碼任務過於繁重 , 我們一般會做一下ui的記錄 UI自動錄入 , 讓QA工程師點 , 點完自動生成測試腳本 , 使用阿里巴巴的f2etest
包括jest
rize.js( 替代了phantomJS , phantomJS已經停止更新了 , 由rize.js一統江山了)

 

0人點贊

 

前端測試

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章