自动化测试

单元测试

编写单元测试是为了验证小的、独立的代码单元是否按预期工作。一个单元测试通常覆盖一个单个函数、类、组合式函数或模块。单元测试侧重于逻辑上的正确性,只关注应用整体功能的一小部分

快速开始

1. 安装依赖

vue add @vue/cli-plugin-unit-jest

安装完成后,项目自动生成如下文件

  • tests 目录是自动化测试的工作区, 可编写单元测试等
  • jest.config.js 文件时配置jest的测试环境、es6语法转化、覆盖率报告等
    在这里插入图片描述
    package.json自动生成如下内容
    在这里插入图片描述

2. jest配置

module.exports = {
  // ---- 必备 STRAT ---- 

  // 提供了jest默认配置,可通过路径node_modules/@vue/cli-plugin-unit-jest/presets/default/jest-preset.js找到该默认配置
  preset: "@vue/cli-plugin-unit-jest",
  // 多于一个测试文件运行时展示每个测试用例测试通过情况,默认多于一个测试文件时不展示;
  verbose: true,
  // 参数指定只要有一个测试用例没有通过,就停止执行后面的测试用例,默认值为0
  bail: true,
  // jsdom可以让js在node环境运行
  testEnvironment: 'jsdom',
  // 匹配所有源文件路径的regexp模式字符串数组,匹配的文件将跳过转换,转译时忽略 node_modules
  // transformIgnorePatterns: ['/node_modules/'],
  transformIgnorePatterns: ['node_modules/(?!axios)'],

  // ---- 必备 END ---- 

  // 覆盖率报告,运行测试命令后终端会展示报告结果
  collectCoverage: true,
  // 需要检测测的文件类型
  moduleFileExtensions: [
    'js',
    'jsx',
    'json',
    'vue'
  ],
  // 预处理器配置,匹配的文件要经过转译才能被识别,否则会报错
  transform: { 
    '.+\\.(css|styl|less|sass|scss|jpg|jpeg|png|svg|gif|eot|otf|webp|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga|avif)$':
    require.resolve('jest-transform-stub'),
    '^.+\\.jsx?$': require.resolve('babel-jest')
  },
  // 从正则表达式到模块名称的映射,和webpack的alisa类似
  moduleNameMapper: {
    "\\.(css|less|scss|sass)$": "<rootDir>/tests/unit/StyleMock.js",
  },
  // Jest在快照测试中使用的快照序列化程序模块的路径列表
  snapshotSerializers: [
    'jest-serializer-vue'
  ],
  // Jest用于检测测试的文件,可以用正则去匹配
  testMatch: [
    '**/tests/unit/**/*.spec.[jt]s?(x)',
    '**/__tests__/*.[jt]s?(x)'
  ],
  // 需要进行收集覆盖率的文件,会依次进行执行符合的文件
  collectCoverageFrom: [
    'src/views/**/*.{js,vue}',
    '!**/node_modules * '
  ],
  // Jest输出覆盖信息文件的目录,运行测试命令会自动生成如下路径的coverage文件
  coverageDirectory: "<rootDir>/tests/unit/coverage",
  // 覆盖结果的最低阈值设置,如果未达到阈值,jest将返回失败
  coverageThreshold: {
    global: {
      branches: 60,
      functions: 80,
      lines: 80,
      statements: 80,
    },
    "src/views/materialManage/materialList/index.vue": {
      branches: 100,
      functions: 100,
      lines: 100,
      statements: 100,
    },
  },
  // 环境预置配置文件入口
  setupFiles: ["<rootDir>/tests/unit/setup/main.setup.js"]
};

3. 执行测试

可以放在 test/unit/ 文件下,命名方式如 *.spec.js 或 *.test.js,jest 会识别自动识别类似文件, 运行下面代码启动测试脚本

全部执行

npm run test:unit

单个执行

npm run test:unit 文件路径

vue-test-utils

官网

主要负责节点获取,编写测试逻辑,以下是一些常用的api,

1、挂载

  • 主要包括mount && shallowMount, 两者都会创建一个包含被挂载和渲染的Vue组件的Wrapper
  • mount会渲染整个组件树, 而shallowMount会对子组件存根(不渲染其子组件)
  • 配置项详情
import { mount } from '@vue/test-utils'
import Foo from './Foo.vue'

describe('Foo', () => {
  it('renders a div', async () => {
    const wrapper = mount(Foo);
    const wrapper1= shallowMount(Foo);
    // classes 返回 Wrapper DOM 节点的 class && 返回 class 名称的数组
    wrapper.classes();
    wrapper.classes('bar');
    // contains 判断 Wrapper 是否包含了一个匹配选择器的元素或组件
    wrapper.contains('div');
    wrapper.contains(Foo);
    // find 返回匹配选择器的第一个 DOM 节点或 Vue 组件的 Wrapper(可以使用任何DOM选择器)
    // findAll 返回一个 WrapperArray
    wrapper.find('div');
    wrapper.find('#foo');
    wrapper.findAll('div').at(0); // at索引
    // findComponent 返回第一个匹配的 Vue 组件的 Wrapper
    // findAllComponents 返回所有匹配的 Vue 组件返回一个 WrapperArray
    wrapper.findComponent(Foo);
    wrapper.findAllComponents(Foo);
    // filter 过滤 WrapperArray,与数组方法相同
    const filteredDivArray = wrapper
      .findAll('div')
      .filter(w => !w.hasClass('filtered'))
    // html 返回 Wrapper DOM 节点的 HTML 字符串
    // text 返回 Wrapper 的文本内容
    wrapper.html();
    wrapper.text();
    // is 断言 Wrapper DOM 节点或 vm 匹配选择器
    wrapper.is('div');
    // setData 设置 Wrapper vm 的属性, 通过递归调用 Vue.set 生效
    await wrapper.setData({ foo: 'bar' })
    // trigger 在该 Wrapper DOM 节点上异步触发一个事件。
    await wrapper.trigger('click')
  })
})

jest

主要负责对测试结果进行断言,以下是一些常用的断言函数

// 判断是否相等
it('equal', () => {
  expect(1 + 2).toBe(3);
  expect('a' + 'b').toBe('ab');
  expect(['a', 'b']).toEqual(['a', 'b']);
  expect({ name: 'xiaoming', age: 18 }).toEqual({ age: 18, name: 'xiaoming' });
});

// 判断类型
it('null', () => {
  const n = null;
  expect(n).toBeNull(); // 仅匹配 null
  expect(n).toBeDefined(); //仅匹配defined
  expect(n).not.toBeUndefined(); // 仅匹配undefined
  expect(n).not.toBeTruthy(); // 匹配任何 if 语句视为真实的内容
  expect(n).toBeFalsy(); // 匹配任何 if 语句视为虚假的内容
});

// 判断大小
it('two plus two', () => {
  const value = 2 + 2;
  expect(value).toBeGreaterThan(3); // >
  expect(value).toBeGreaterThanOrEqual(3.5); // >=
  expect(value).toBeLessThan(5); // <
  expect(value).toBeLessThanOrEqual(4.5); // <=
  expect(value).toBe(4);
  expect(value).toEqual(4);
  expect(0.1 + 0.2).toBeCloseTo(0.3); // // 浮点数
});

// 判断是否存在
it('there is no I in team', () => {
  expect('team').not.toMatch(/I/); // not表示相反
  expect('team').toMatch(/Is/);
  expect([1,2,3]).toContain('1');
});

端对端测试(e2e)

端到端测试(End-To-End Testing, 简称E2E测试)是一种从头到尾测试整个软件产品以确保应用程序流程按预期运行的技术。它定义了产品的系统依赖性,并确保所有集成部分按预期协同工作。

cypress
https://docs.cypress.io/guides

快速开始

安装

npm install cypress --save-dev

从项目根目录打开Cypress

npx cypress open

添加npm 脚本

{
  "scripts": {
    "cypress:open": "cypress open"
  }
}

编写测试脚本

describe('My First Test', () => {
  it('Visits the Kitchen Sink', () => {
    // 访问一个页面
    cy.visit('https://example.cypress.io');
    // 查询元素
    cy.contains('type');
    // 选择一个元素
    cy.get('[data-cy=account]');
    // 输入文本
    cy.get('[data-cy=account]').type('zhangsan');
    // 单击一个元素
    cy.contains('type').click();
    // 断言
    cy.url().should('include', '/commands/actions')
  })
})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

[chao]

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值