尝试写第一个单元测试、自动化测试、持续集成2018-12-07

测试库:chai

// 安装
npm i -D chai

// 引入
import {expect} from 'chai'

打包工具:parcel

// 安装
npm i -D parcel

// 只需一行代码即可打包,不需要任何配置
parcel index.html --no-cache

测试刚在 vue 写按钮组件

:一个简单的轮子
button.vue





index.html




  
  
  
  Document


  
这是一个按钮

单元测试

开始第一次单元测试

import Vue from 'vue'
import Button from './button'
import {expect} from 'chai'

Vue.component('g-button', Button)
new Vue({
  el: '#app'
})

{
  const vm = Vue.extend(Button)
  const button = new vm({
    el: '#div',
    propsData: {
      icon: 'settings'
    }
  })
  const icon = button.$el.querySelector('use')
  console.log(icon)
  expect(icon.getAttribute('xlink:href')).to.eq('settings'); // 断言语句。
}
失败

第一次测试失败,svg属性没写全

所以再试一次~

import Vue from 'vue'
import Button from './button'
import {expect} from 'chai'

Vue.component('g-button', Button)
new Vue({
  el: '#app'
})

{
  const vm = Vue.extend(Button)
  const button = new vm({
    el: '#div',
    propsData: {
      icon: 'settings'
    }
  })
  const icon = button.$el.querySelector('use')
  console.log(icon)
  expect(icon.getAttribute('xlink:href')).to.eq('#icon-settings'); // 断言语句。
}
成功

成功啦~,
浏览器中没有任何报错说明测试通过

但是每次都打开浏览器、刷新,实在是非常麻烦,所以我们再继续自动化测试

自动化测试

工具:

  1. Karma(卡玛)是一个测试运行器,它可以呼起浏览器,加载测试脚本,然后运行测试用例
  2. Mocha(摩卡)是一个单元测试框架/库,它可以用来写测试用例
  3. Sinon(西农)是一个spy / stub / mock 库,用以辅助测试(使用后才能理解)

then:

// 安装各种工具
// npm i -D karma karma-chrome-launcher karma-mocha karma-sinon-chai mocha sinon sinon-chai karma-chai karma-chai-spies // 最新npm包,防止版本报错,建议锁定版本
npm i -D [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected]

创建 Karma 配置

// 新建 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: ['mocha', 'sinon-chai'],
    client: {
      chai: {
        includeStack: true
      }
    },
    // list of files / patterns to load in the browser
    files: [
      'dist/**/*.test.js',
      'dist/**/*.test.css'
    ],
    // list of files / patterns to exclude
    exclude: [],
    // preprocess matching files before serving them to the browser
    // available preprocessors: https//npmjs.org/browse/keyword/karma-reporter
    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 if 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: http://npmjs.org/browse/keyword/karma-launcher
    browsers: ['Chrome'],
    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: false,
    // Concurrenecy level
    // how many browser should be started simultaneous
    concurrency: Infinity
  })
}

创建test目录并在其目录下创建并更改 button.test.js

// import {expect} from 'chai'
const expect = chai.expect
import Vue from 'vue'
import Button from '../src/button'

Vue.config.productionTip = false
Vue.config.devtools = false

describe('Button', () => {
  it('存在', () => {
    expect(Button).to.be.ok //不是 undefined null 0 '' 等falsy值
  })
  it('可以设置icon', () => {
    const vm = Vue.extend(Button)
    const button = new vm({
      el: '#div',
      propsData: {
        icon: 'settings'
      }
    })
    const icon = button.$el.querySelector('use')
    console.log(icon)
    expect(icon.getAttribute('xlink:href')).to.equal('#icon-setting')
  })
  it('点击 button 触发 click 事件', () => {
    const vm = Vue.extend(Button)
    const button = new vm({
      el: '#div',
      propsData: {
        icon: 'settings'
      }
    })
    const callback = sinon.fake()
    button.$on('click', callback)
    button.$el.click()
    expect(callback).to.have.been.called
  })
})

创建测试脚本
package.json 里面找到 script 并改写里面的内容

"scripts": {
    "dev-test": "parcel watch test/* --no-cache & karma start",
    "test": "parcel build test/* --no-cache --no-minify & karma start --single-run"
  }

准备完毕,开始跑我们的代码

// 这行命令会自动打开浏览器并测试
npm run test
// 或者 npm run dev-test // 持续打包

当用例全部成功时:

成功~

当有用例失败时,终端会提示报错:

失败

更多测试语句请参考 chai官方API


-
-
-
-
-
-
-

中途遇到的报错~

image.png

package.json 添加如下:

"alias": {
    "vue": "./node_modules/vue/dist/vue.common.js"
  }

持续集成

说到懒,一向是程序员的优良传统~

目前比较流行的是 TravisCi(免费) 和 circleCi(收费,功能强大)

阮一峰的Travis教程

首先我们继续在根目录创建文件 .travis.yml

内容如下:

language: node_js # 使用node_js进行测试
node_js: # node_js版本号
  - "8"
  - "9"
  - "10"
addons: # 插件
  chrome: stable # 谷歌浏览器稳定版
sudo: required
before_script:
  - "sudo chown root /opt/google/chrome/chrome-sandbox"
  - "sudo chmod 4755 /opt/google/chrome/chrome-sandbox"

then:
我们前去 Travis 官方网站,并使用 GitHub 帐号关联登陆,并找到刚刚的测试项目,然后开启

只需点一下这个按钮

返回首页,我们就能看到已经在测试啦~

开始啦

但是,我们又报错了 =。=

error

报错并不可怕,翻来覆去只能想到返回 Karma 的配置,改一下浏览器设置

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

由于我们接入了 GitHub 所以,在我们提交之后, Travis 就会检测到文件改变并自动测试~

当 Travis 任务状态改变(失败或成功)都会向你的邮箱里发一封邮件,所以我们并不用一直打开他的网页

你可能感兴趣的:(尝试写第一个单元测试、自动化测试、持续集成2018-12-07)