前端必备测试技术总结

2020-03-22  本文已影响0人  RexingLeung

[TOC]

单元测试

目的:单元测试能够让开发者明确知道代码结构
原则:单一职责、接口抽离、层次分离
断言库:保证最小单元是否正常运行检测方法
测试风格:测试驱动开发(Test-Driven Development,TDD),行为驱动开发(Behavior Driver Development,BDD),均是敏捷开发开发方法论。

单元测试框架

单元测试运行流程

before -> before -> it -> after -> afterEach
每个测试用例组通过describe进行设置

  1. before每个测试用例(it)开始前
  2. beforeEach 每个测试用例开始前
  3. it定义测试用例并利用断言库进行设置chai如:expect(x).to.equal(true); 异步mocha
  4. 以上专业术语叫mock

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一统江山了)

上一篇下一篇

猜你喜欢

热点阅读