入门:前端自动化测试karma,Backstopjs,Selenium-webdriver,Mocha

3,448 阅读9分钟

前言:

最近在学习前端自动化测试,接触了很多测试框架,Karma+Jasmine+karma-coverage:单元测试和测试代码覆盖率、Backstopjs:css回归测试、Selenium-webdriver:e2e测试、Mocha+chai:异步测试,遇到过很多坑,勉勉强强总算跑通一个基本流程,若有错误,欢迎指出,感谢。

github地址:fetest

1.Karma+Jasmine+karma-coverage

单元测试(模块测试)是开发者编写的一小段代码,用于检验被测代码的一个很小的、很明确的功能是否正确。通常而言,一个单元测试是用于判断某个特定条件(或者场景)下某个特定函数的行为。

Karma是一个基于Node.js的JavaScript测试执行过程管理工具( Test Runner ).。该工具可用于测试所有主流Web浏览器, 也可集成到CI ( Continuous integration ) 工具, 也可和其他代码编辑器一起使用.。这个测试工具的一个强大特性就是, 它可以监控(Watch)文件的变化, 然后自行执行。

jasmine 是一个行为驱动开发(TDD)测试框架, 一个js测试框架,它不依赖于浏览器、dom或其他js框架。具体语法参照:官方api

1.1 使用 Karma 对代码进行单元测试,首先需要安装一系列的相关插件。

创建fetest的文件夹,并进入

安装karma

npm install -g karma-cli
npm install karma --save-dev

安装各种相关的插件

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

初始化,整体的配置选项如下:

karma init
Which testing framework do you want to use ?
Press tab to list possible options. Enter to move to the next question.
> jasmine

Do you want to use Require.js ?
This will add Require.js plugin.
Press tab to list possible options. Enter to move to the next question.
> no

Do you want to capture any browsers automatically ?
Press tab to list possible options. Enter empty string to move to the next question.
> PhantomJS
>
What is the location of your source and test files ?
You can use glob patterns, eg. "js/*.js" or "test/**/*Spec.js".
Enter empty string to move to the next question.
>

Should any of the files included by the previous patterns be excluded ?
You can use glob patterns, eg. "**/*.swp".
Enter empty string to move to the next question.
>

Do you want Karma to watch all the files and run the tests on change ?
Press tab to list possible options.
> no

启动karma

karma start

出现一下界面代表成功,可进行下一步操作,第一次需要安装phantomjs

npm install -g phantomjs


初始化完成之后,会在我们的项目中生成一个 karma.conf.js 文件,这个文件就是 Karma 的配置文件。

// Karma configuration
// Generated on Sat Jun 02 2018 11:06:15 GMT+0800 (中国标准时间)

module.exports = function(config) {
  config.set({

    // base path that will be used to resolve all patterns (eg. files, exclude)
    basePath: '',


    // frameworks to use
    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['jasmine'], //使用何种断言库


    // list of files / patterns to load in the browser
    files: [
       './unit/**/*.js',     //被测试的代码路径
       './unit/**/*.spec.js' //测试代码路径
    ],


    // list of files / patterns to exclude
    exclude: [
    ],


    // preprocess matching files before serving them to the browser
    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
    preprocessors: {
    },


    // test results reporter to use
    // possible values: 'dots', 'progress'
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
    reporters: ['progress'],

    // web server port
    port: 9876,


    // enable / disable colors in the output (reporters and logs)
    colors: true,


    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,


    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: false,


    // start these browsers
    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
    browsers: ['PhantomJS'],


    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: true,//执行完是否退出

    // Concurrency level
    // how many browser should be started simultaneous
    concurrency: Infinity
  })
}

创建unit文件夹,并创建index.js、index.spec.js

index.js

function add (num){
    if(num == 1){
        return 1;
    }else{
        return num+1;
    }

}

index.spec.js

describe("测试简单基本函数", function() {
    it("+1测试", function() {
        expect(add(1)).toBe(1);
        expect(add(2)).toBe(5);
    });
});

启动karma

karma start

成功了一个,错误一个。

1.2 使用 karma-coverage测试代码覆盖率

安装karma-coverage

npm install karma-coverage --save-dev

创建一个docs文件夹,用来存放生成的的测试文件,配置 karma.conf.js 文件:

// Karma configuration
// Generated on Sat Jun 02 2018 19:49:27 GMT+0800 (中国标准时间)

module.exports = function(config) {
  config.set({

    // base path that will be used to resolve all patterns (eg. files, exclude)
    basePath: '',


    // frameworks to use
    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['jasmine'],


    // list of files / patterns to load in the browser
    files: [
        './unit/**/*.js',
        './unit/**/*.spec.js'
    ],


    // list of files / patterns to exclude
    exclude: [
    ],


    // preprocess matching files before serving them to the browser
    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
    preprocessors: {
        'unit/**/*.js': ['coverage']//对那些文件生成代码覆盖率检查

    },


    // test results reporter to use
    // possible values: 'dots', 'progress'
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter

    reporters: ['progress','coverage'],//添加'coverage'

    coverageReporter: {
          type : 'html',           //生成html页面
          dir : './docs/coverage/' //存放html页面位置
    },

    // web server port
    port: 9876,


    // enable / disable colors in the output (reporters and logs)
    colors: true,


    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,


    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: false,


    // start these browsers
    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
    browsers: ['PhantomJS'],


    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: true,

    // Concurrency level
    // how many browser should be started simultaneous
    concurrency: Infinity
  })
}

启动karma

karma start

会在docs中生成一个coverage文件夹,里面有生成的测试代码覆盖率的可视化html页面。


打开index.html


修改index.spec.js

describe("测试简单基本函数", function() {
    it("+1测试", function() {
        expect(add(1)).toBe(1);
    });
});
karma start


2.Backstopjs:css回归测试

BackstopJS就是一个能够实现css自动化回归测试的工具,和Mocha这种依靠JavaScript判断断言语句正误和PhantomJS以模拟用户操作的测试工具不同,BackstopJS是一个基于比较网站快照的变化的回归测试工具,因此他更适给项目中的样式做回归测试,可以确保我们在重构网站样式的时候样式不发生变化,而且他支持设置多种浏览器尺寸,可以测试响应式布局。

简单点说:backstopjs,可以自动的对比UI出的图与前端写好的图,不一致的地方会标出。

BackstopJS具有以下特性:

  • 支持多页面、多测试用例测试
  • 可以使用脚本模拟出用户的交互动作
  • 提供命令行和浏览器两种形式报告
  • 支持PhantomJS或SlimerJS做浏览器引擎,事实上两种引擎也可以改造出基于快照对比的回归测试方案,但是BackstopJS使用更简单,并且做到了可以通过配置切换引擎。
  • 支持设置多种浏览器尺寸,方便实现响应式布局测试
  • 可以测试HTML5元素,比如网页字体和Flexbox
  • 提供了扩展接口,可供用户集成到其他测试系统中 

安装BackstopJS

npm install -g backstopjs

初始化,会生成配置文件backstop.json和backstop_data文件夹

backstop init

配置 backstop.json

{
  "id": "backstop_default",//测试用例id,用于BackstopJS管理和为文件命名
  "viewports": [
    {
      "label": "phone",//配置手机分辨率
      "width": 375,
      "height": 667
    },
    {
      "label": "tablet",//配置平板分辨率
      "width": 1024,
      "height": 768
    }
  ],
  "onBeforeScript": "puppet/onBefore.js",
  "onReadyScript": "puppet/onReady.js",
 //测试用例  "scenarios": [                     
    {
      "label": "qq.map",//测试用例名
      "cookiePath": "backstop_data/engine_scripts/cookies.json",
      "url": "https://map.baidu.com/mobile/webapp/index/index/",//测试地址
      "referenceUrl": "",
      "readyEvent": "",
      "readySelector": "",
      "delay": 0,
      "hideSelectors": [],
      "removeSelectors": [],
      "hoverSelector": "",
      "clickSelector": "",
      "postInteractionWait": 0,
      "selectors": [],
      "selectorExpansion": true,
      "misMatchThreshold" : 0.1,
      "requireSameDimensions": true
    }
  ],
  "paths": {
    "bitmaps_reference": "backstop_data/bitmaps_reference",//存放测试时的ui给的图片
    "bitmaps_test": "backstop_data/bitmaps_test",//生成测试时的图片
    "engine_scripts": "backstop_data/engine_scripts",
    "html_report": "./docs/backstop_data/html_report",//生成测试的html页面存放路径
    "ci_report": "backstop_data/ci_report"
  },
  "report": ["browser"],
  "engine": "puppeteer",
  "engineFlags": [],
  "asyncCaptureLimit": 5,
  "asyncCompareLimit": 50,
  "debug": false,
  "debugWindow": false
}

我测试的是https://map.baidu.com/mobile/webapp/index/index/腾讯地图

启动

backstop test 


第一次启动会显示下面的错误,需要在backstop_data文件夹中创建文件夹bitmaps_reference并在里面存放对应的测试图。上面的3张图分别对应的是测试图自动截取的网站图对比图(粉色区域不一致)


再次启动

backstop test 


3.Selenium-webdriver:e2e测试

Selenium是一个浏览器自动化测试库,大多时候我们用它来测试web应用,Selenium 可以胜任任何在浏览器上自动化测试的任务。

Webdriver (Selenium2)是一种用于Web应用程序的自动测试工具,它提供了一套友好的API,与Selenium 1(Selenium-RC)相比,Selenium 2的API更容易理解和使用,其可读性和可维护性也大大提高。Webdriver完全就是一套类库,不依赖于任何测试框架,除了必要的浏览器驱动,不需要启动其他进程或安装其他程序,也不必需要先启动服务。

安装Selenium-webdriver

npm install Selenium-webdriver --save-dev

安装火狐驱动文件,只需要下载解压到当前目录则可,下载连接:geckodriver(.exe)



创建e2e文件夹,在里面创建baidu.js

baidu.js       可查看 Selenium-webdriver api

const {Builder, By, Key, until} = require('selenium-webdriver');

(async function example() {
    let driver = await new Builder().forBrowser('firefox').build();
    try {
        await driver.get('https://www.baidu.com/');//打开测试页面
        await driver.findElement(By.name('wd')).sendKeys('随风而行', Key.RETURN);//定位某个元素,在输入框中输入内容
        await driver.wait(until.titleIs('随风而行_百度搜索'), 1000);
    } finally {
        await driver.quit();//退出
    }
})();

用node来启动

node ./e2e/baidu.js

之后会自动弹出测试,成功退出,报错会弹出报错信息,大家可以自行玩耍。

4.Mocha+chai:异步测试

mocha是一款功能丰富的javascript单元测试框架,支持TDD,BDD等多种接口,它既可以运行在nodejs环境中,也可以运行在浏览器环境中。
javascript是一门单线程语言,最显著的特点就是有很多异步执行。同步代码的测试比较简单,直接判断函数的返回值是否符合预期就行了,而异步的函数,就需要测试框架支持回调、promise或其他的方式来判断测试结果的正确性了。mocha可以良好的支持javascript异步的单元测试。
mocha会串行地执行我们编写的测试用例,可以在将未捕获异常指向对应用例的同时,保证输出灵活准确的测试结果报告。

安装mocha ,mochawesome ,chai 

npm install -g mocha 
npm install chai mochawesome --save-dev

创建mochaRunner.js

const Mocha = require("mocha");
const mocha = new Mocha({
    reporter: 'mochawesome',
    reporterOptions:{
        reporteDir:"./docs/mochawesome-reporter" //生成测试页面路径
    }
});
mocha.addFile('./service/router.spec.js');//测试的文件路径
mocha.run(function(){
    console.log("done");
    process.exit();
})

创建文件夹service并在里面创建app.js、router.spec.js

app.js 启动一个服务器监听3000端口,若访问http://127.0.0.1:3000/test便返回数据data

var express = require('express');
var app = express();

app.get('/test', function (req, res) {
    res.send({
        data:'Hello World'
    });
});

var server = app.listen(3000, function () {
    console.log('服务启动');
});
module.exports = app;

要安装express

npm install express

router.spec.js

const axios = require('axios');
const { expect } = require('chai');
describe("node接口测试",function(){
    it("test 接口测试",(done) => {
        axios.get('http://localhost:3000/test') //请求的url
            .then(function (res) {
            expect(res.status).to.equal(200);
            console.log(res.data)
            if(res.data.data == "Hello World!"){
                    done();
            }else{
                    done(new Error('结果不符合预期!!!'));
            }
            }).catch(function (error) {
            done(error);
        });
    });
});

需要安装axios

npm install axios

启动mocha

mocha ./mochaRunner.js

或者

node ./mochaRunner.js


将会在同级目录生成mochawesome-reports,访问html


也可以在package.json中配置:

"scripts": {
  "test": "npm run unit",
  "e2e": "node ./e2e/baidu.js",
  "unit": "karma start",
  "uitest": "backstop test",
  "service": "mocha ./mochaRunner.js"
},

这样就可以直接使用npm run ***

结尾:

前端自动化测试的框架还有很多很多,例如:Rizejs、Nightwhatchjs、F2etest等等。刚接触这些测试框架,有太多的不懂,这就需要时间的积累,不断学习,不断进步,让自己成长为想要成为的那个自己,感谢大家观看!!!