自动化测试

  1. 首先我们来看下什么是BDD,什么是TDD
    测试风格:测试驱动开发(Test-Driven Development,TDD)、(Behavior Driven Development,BDD)行为驱动开发均是敏捷开发方法论。 TDD关注所有的功能是否被实现(每一个功能都必须有对应的测试用 例),suite配合test利用assert('tobi' == user.name); BDD关注整体行为是否符合整体预期,编写的每一行代码都有目的提 供一个全面的测试用例集。expect/should,describe配合it利用自然语 言expect(1).toEqual(fn())执行结果。

  2. 接下来我们看下单元测试的运行流程


    image.png

来开始一个单元测试

unit测试是把代码看成是一个个的组件。从而实现每一个组件的单独测试,测试内容主要是组件内每一个函数的返回结果是不是和期望值一样。
这里我们使用karma,官网地址为: karma: https://karma-runner.github.io/latest/index.html
安装karma:
karma-jasmine jasmine-core是断言库

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

然后执行karma init
这里会有很多步选择,我们都默认就好了,但是选择浏览器时我们选择phantomjs
做完这些操作后,会生成一个karma.conf.js文件如下:

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'],

    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'], // 进度,覆盖率(需要装karma-coverage)
    coverageReporter: { // 生成的测试报表
      type : 'html',
      dir : 'docs/coverage/'
    },

    // 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: true,

    // 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, // 使用无头浏览器这里必须设置为true

    // Concurrency level
    // how many browser should be started simultaneous
    // 并发级别
    concurrency: Infinity
  })
}

我们在util文件夹中新建一个文件index.js对其进行测试,内容如下

window.add = function (a) {
  return a + 1;
}

再新建一个测试文件index.spec.js(或indexSpec.js)

escribe("测试基本函数的api",function () {
  it("+1函数的应用",function(){
    expect(window.add(1)).toBe(2)
  })
})

这时就可以跑执行karma start开始测试了
到这里有一个问题,如果代码中有if,else怎么办。这时我们就需要代码覆盖率检查了。下载 karma-coverage,如果报错可能是缺了karma-phantomjs-launcher和phantomjs这两个包。在上面的配置文件中我已经进行了配置,现在直接跑就ok了。

页面测试: e2e

e2e测试是把我们的程序堪称是一个黑盒子,我不懂你内部是怎么实现的,我只负责打开浏览器,把测试内容在页面上输入一遍,看是不是我想要得到的结果。
这里我们使用selenium-webdriver来进行e2e测试,e2e测试需要一个浏览器的执行环境,所以首先在selenium-webdriver官网上下载浏览器驱动,然后安装selenium-webdriver

在e2e文件夹中新建一个baidu.spec.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('wd')).sendKeys('webdriver', Key.RETURN); // 通过名class名为wd的input框搜索webdriver
    await driver.wait(until.titleIs('webdriver_百度搜索'), 1000); // 等待1s看title是否等于webdriver_百度搜索
  } finally {
    await driver.quit(); // 无论是否成功,退出driver
  }
})();

然后我们运行: node ./e2e/baidu.spec.js

UI测试
PhantomCSS是一个很好的UI测试插件,但是我们这里使用backstopjs来做演示
安装backstopjs后,我们backstop init
这时会生成一个backstop_data文件夹,和backstop.json文件
我们首先来看下backstop_data文件夹结构

+-- backstop_data  
    +-- bitmaps_reference -- 放置ui切图的文件夹  
    +-- bitmaps_test -- 生成的测试图例地址
    +-- engine_scripts
        +-- casper -- 在无头浏览器中操作鼠标
        +-- chromy
        +-- puppet
        +-- cookies.json -- 如果网页需要配置cookie在这里配置

再来看下backstop.json文件配置

{
  "id": "yd", // 项目名称
  "viewports": [ // 设备配置项
    {
      "label": "phone",
      "width": 375,
      "height": 667
    },
    {
      "label": "tablet",
      "width": 1024,
      "height": 768
    }
  ],
  "onBeforeScript": "puppet/onBefore.js", // 引擎, 在engine_scripts文件夹中
  "onReadyScript": "puppet/onReady.js", // 同上
  "scenarios": [ // 配置截图
    {
      "label": "qqmap", 
      "cookiePath": "backstop_data/engine_scripts/cookies.json", // cookie地址
      "url": "https://map.qq.com/m/", // 要被测试页面地址
      "referenceUrl": "",
      "readyEvent": "",
      "readySelector": "",
      "delay": 0,
      "hideSelectors": [],
      "removeSelectors": [],
      "hoverSelector": "",
      "clickSelector": "",
      "postInteractionWait": 0,
      "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": "docs/backstop_data/html_report", // 生成报表地址
    "ci_report": "docs/backstop_data/ci_report" // ci报表
  },
  "report": ["browser"],
  "engine": "puppeteer",
  "engineOptions": {
    "args": ["--no-sandbox"]
  },
  "asyncCaptureLimit": 5,
  "asyncCompareLimit": 50,
  "debug": false,
  "debugWindow": false
}

最后执行backstop test进行测试

接口测试

接口测试我们这里使用mocha
首先安装mocha
我们新建一个app.js文件,对app.js文件的内容进行测试

var express = require("express");
var app = express();
app.get("/test",function(req,res){
    res.send({
        result:"Hello World"
    })
});
var server = app.listen(3000,function(){
    console.log("demo app 启动");
});
module.exports = app;

我们再创建测试文件router.spec.js

const axios = require("axios");
describe("node接口", function () {
  it("test接口测试", function (done) {
    axios.get('http://localhost:3000/test')
      .then(function (response) {
        if (response.data.result == "Hello World") {
          done();
        } else {
          done(new Error("数据请求格式错误"));
        }
      })
      .catch(function (error) {
        done(error);
      });
  });
});

// 高级写法
const superagent = require("superagent");
const app = require("./app");
function request(){
    return superagent(app.listen())
}
request()
.get("/test")
.expect("Content-Type",/json/)
.expect(200)
.end(function(err,res){
    if(res.data == "Hello World"){
        done();
    }else{
        done(err);
    }
})

最后新建mochaRunner.js文件如下,这里我们需要下载mochawesome来生成报表

const Mocha = require("mocha");
const mocha = new Mocha({
    reporter: 'mochawesome', // 安装mochawesome(生成报表的包)
    reporterOptions:{
        reportDir:"./docs/mochawesome-reporter" // 生成报表位置
    }
});
mocha.addFile("./service/router.spec.js");
mocha.run(function(){
    console.log("done");
    process.exit(); // 退出进程,不退出会卡死
});

这时我们运行node ./mochaRunner.js

如果我们需要将上面的的一起测试,只需要: npm run unit && npm run e2e && npm run ui就OK了

JavaScript Lint&Hint

目的:检测JavaScript代码标准 原因:JavaScript代码诡异,保证团队代码规范 lint:http://www.jslint.com/
hint: http://www.jshint.com/
搭配自动化任务管理工具完善自动化测试grunt- jshint、grunt-jslint

下面来介绍一些工程用的测试包

  1. nightwatchjs(vue专用)
  2. rize+puppeteer+rize
  3. 阿里的f2etest(自动化录制)
    这里我们需要注意下,在f2etest中有UI recorder,这个东西会打开两个浏览器,因为有些网站像验证码每次都不一样,第二台浏览器会与第一个比较,结果相同就算成功
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,482评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,377评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,762评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,273评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,289评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,046评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,351评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,988评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,476评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,948评论 2 324
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,064评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,712评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,261评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,264评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,486评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,511评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,802评论 2 345