美文网首页
前端必备测试技术总结

前端必备测试技术总结

作者: RexingLeung | 来源:发表于2020-03-22 23:04 被阅读0次

    [TOC]

    单元测试

    目的:单元测试能够让开发者明确知道代码结构
    原则:单一职责、接口抽离、层次分离
    断言库:保证最小单元是否正常运行检测方法
    测试风格:测试驱动开发(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一统江山了)

    相关文章

      网友评论

          本文标题:前端必备测试技术总结

          本文链接:https://www.haomeiwen.com/subject/btbbyhtx.html