Skip to content

2021-08-17

统计信息:字数 5628 阅读12分钟

前端自动化测试

主要内容:前端测试分类;VUE中如何使用单元测试;测试驱动开发TDD思路

怎样使用

在VUE-CLI 或者 create-react-app 中,初始化项目会设置使用单元测试和E2E测试。

单元测试针对一个API或者一个小模块进行测试;E2E针对一个功能进行测试。国内产品经理经常修改需求,所以E2E测试部署不多。初始化时,可以选择测试框架(JEST 或者 Mocha+Chai)

测试好处

  • 便于后期编写接口文档
  • 节省手动测试的时间和不全面性
  • 减少开发时产生bug
  • 改进设计;促进代码重构

单元测试

function add(a, b) {
  return Number(a) + Number(b);
}

describe('test add two var', () => {
  it('two number', () => {
    expect(add(1, 2)).toBe(3);
  });
  // 健壮性测试(传入的数据类型不对,或者不传参)
  it('string add', () => {
    expect(add('1', '3')).toBe(4);
  });
});

测试代码可以保证后续的修改不会出问题(不会被其他人改错);

测试代码可以很好的改写成接口文档

提交前测试——哈士奇插件

哈士奇插件(Hushy)可以在commit前,执行单元测试;通过测试后才能提交代码

npm install husky --save-dev

然后在 package.json 中增加配置

{
  "husky": {
    "hooks": {
      "pre-commit": "npm test",
      "pre-push": "npm test",
    }
  }
}

VUE中单元测试

APP.vue 模板文件

<template>
    <div id="app">
    <div>
      <span>{{message}}</span>
      <button @click="changeMsg">click</button>
    </div>
  </div>
</template>

<script>
export default {
  name: 'app',
  data() {
    return {
      message: 'helloMili'
    }
  },
  created() {
    this.message = 'created';
  },
  components: {},
  methods: {
    changeMsg() {
      this.message = 'clicked'
    }
  }
}
</script>

官网测试文件示例

import { mount } from '@vue/test-utils';
import Counter from './counter';

// 挂载组件,获取对应的包裹器
const wrapper = mount(Counter);

// 访问Vue实例,后续进行测试
const vm = wrapper.vm;

实际测试文件 test.spec.js

测试静态方法;组件加载后状态,组件响应后状态

import Vue from 'vue';
import Test from '@/components/Test.vue';
import { mount } from '@vue/test-utils';

describe('test fn', () => {
  it('static fn', () => {
    expect(typeof Test.created).toBe('function');
  });
  it('mounted', () => {
    let vm = new Vue(Test).$mount();
    expect(vm.message).toBe('ctreated');
  });
  it('trigger btn', () => {
    let wrapper = mount(Test);
    wrapper.find('button').trigger('click');
    expect(wrapper.vm.message).toBe('clicked');
  });
});

Todolist.vue

<template>
    <div>
    <h1>List</h1>
    <input v-model="todoText" @keyup.enter="enterText" type="text"/>
    <ul>
      <li v-for="todo in todos">{{todo.text}}</li>
    </ul>
  </div>
</template>

<script>
export default {
  data() {
    return {
      todoText: '',
      todos: [],
      completeds: [],
    }
  },
  methods: {
    enterText() {
    }
  },
}
</script>
<style scoped>
</style>

测试代码

import { shallowMount } from '@vue/test-utils';
import Todolist from '@/components/Todolist';

describe('test todolist', () => {
  let wrapper;
  beforeEach(() => {
    wrapper = shallowMount(Todolist);
  });
  afterEach(() => {
    wrapper = null;
  });
  it('test input', () => {
    let res = 'test text';
    wrapper.find('.todo-list').setValue(res);
    expect(wrapper.vm.todoText).toBe(res);
  });

  it('test enter keydown', () => {
    const len = wrapper.vm.todos.length;
    const input = wrapper.find('.todo-list');
    input.setValue('Bilibili');
    input.trigger('keyup.enter');
    expect(wrapper.vm.todos.length).toBe(length + 1);
  });
});

异步事件测试(Mock数据)

<template>
    <div>
    <h1>axios</h1>
  </div>
</template>

<script>
export default {
  data() {
    return {
      usetInfo: {}
    }
  },
  created() {
    this.$axios.get('/kkd/users').then(res => {
      this.userInfo = res.data
    });
  }
}
</script>

测试代码

如果需要登录验证(token),需要提前获取token;测试一个组件前后,需要预处理,和清理代码。

import AxiosTest from '@/components/AxiosTest.vue';
import { shallowMount, createLocalVue } from '@vue/test-utils';
import axios from 'axios';

jest.mock('axios');

const localVue = createLocalVue();
localVue.prototype.$axios = axios;

describe('test axios', () => {
  let wrapper;
  beforeAll(() => {
    axios.mockClear();
    wrapper = shallowMount(AxiosTest, {
      localVue,
      stubs: ['app-button']
    });
  });

  afterAll(() => {
    wrapper.destory();
  });
})

测试覆盖率

jest 中配置可以设置测试覆盖率(大项目中,测试覆盖率必须达标才能通过提交)

{
  "jest": {
    "preset": "@vue/cli-plugin-unit-jest",
    "collectCoverage": true,
    "collectCoverageFrom": [
      "src/components/**/*.{js,vue}"
    ],
  }
}

E2E 测试

从用户或者产品经理的角度部署测试(公共组件可以进行 E2E 测试,这样修改后可以判断是否会影响已有功能)

describe("Test", () => {
  it('Visit root page', () => {
    cy.visit('/');
    cy.contains('h1', 'Welcome to MrAn\'s page');
  });
});

不需要知道具体的组件,关注界面加载后显示的内容

可能只监控核心业务界面(登录,购物车等)

看一些经典的库如何实现功能,如何部署测试,可以提高自己


Last update: November 9, 2024