单元测试(超详细整理)

news2025/1/14 18:01:37

前言

为什么我们需要测试?

让产品可以快速迭代,同时还能保持高质量

对于一些相对稳定的系统级别页面,自动化测试在提高测试的效率的方面起到非常重要的作用。前端的自动化测试主要包括:浏览器测试和单元测试。Vue官方脚手架自带自动化测试配置,并帮助你完成对组件,函数等的自动化测试。

什么是持续集成?它和持续部署有什么区别?

代码集成到主分支需要经过一系列的自动化测试,当测试都通过之后,方可执行自动化部署,否则不能完成集成。这说明了自动化测试的重要性,我们不能等测试工程师去发现问题。

在Vue脚手架当中,Karma和NightWatch分别对应着单元测试和e2e测试。单元测试更多是面向JS功能逻辑的检验,而NightWatch更多是面对业务逻辑的检验。

同时,在这我为大家准备了一份软件测试视频教程(含面试、接口、自动化、性能测试等),就在下方,需要的可以直接去观看,也可以直接【点击文末小卡片免费领取资料文档】

软件测试视频教程观看处:

2024年Python自动化测试全套保姆级教程,70个项目实战,3天练完,永久白嫖...

单元测试

代码的单元测试主要针对某些核心功能的某些函数进行测试。vue官方推荐是使用karma,mocha和chai等。karma并不是一个测试框架,也不是一个断言库。它可以运行HTTP Server,运行HTML文件在你喜欢的测试框架上。不仅仅只是运行测试,还可以计算测试的覆盖率。mocha是测试框架,专门实现各个单元划分测试。chai是典型的断言库。

vue单元测试

npm run unit # 运行单元测试

Karma

Karma是一个专门的测试运行器(runner),它不是一个测试框架框架,也不是以一个断言库。Karma兼容Jasmine,Mocha和QUnit,可以集成mocha,webpack等功能,成为以Karma为平台的单元测试,官方选择的事mocha的测试框架和chai的断言库。它拥有一些测试插件:

  • karma-webpack 用webpack预处理文件
  • karma-coverage 测试覆盖率
  • karma-mocha 接入mocha测试框架
  • karma-spec-reporter 输出报告
  • karma-phantomjs-launcher 控制PhantomJS
  • karma-phantomjs-shim 给PhantomJS兼容的控制

karma-coverage是基于istanbul。这些插件集成在karma这个runner,把webpack打包的vue项目,测试里组件实现的功能,包括组件库,业务逻辑和请求范围。它的配置文件karma.conf.js里面默认配置了很多插件的内容,基本上不需要调整。

var webpackConfig = require('../../build/webpack.test.conf');
 
module.exports = function (config) {
  config.set({
    browsers: ['PhantomJS'], // 测试服务浏览器
    frameworks: ['mocha', 'sinon-chai', 'phantomjs-shim'], // 测试框架
    reporters: ['spec', 'coverage'], // 报告输出
    files: ['./index.js'], // 文件入口,过滤掉index.html
    preprocessors: {
      './index.js': ['webpack', 'sourcemap'] // 预处理器
    },
    webpack: webpackConfig, // 专门测试webpack配置
    webpackMiddleware: {
      noInfo: true,
    },
    coverageReporter: {
      dir: './coverage', // 覆盖率配置
      reporters: [
        { type: 'lcov', subdir: '.' },
        { type: 'text-summary' },
      ]
    },
  });
};

Mocha

mocha本身只是一个单元测试框架,可以兼容第三方断言库,包括:

  • should.js
  • expect.js
  • chai
  • better-assert
  • unexpected

在Vue开发框架中位于specs(specifications)文件底下,可以针对某个组件或者某个js进行测试。

 
import Vue from 'vue';
import Hello from '@/components/Hello';
 
describe('Hello.vue', () => {
  it('should render correct contents', () => {
    const Constructor = Vue.extend(Hello);
    const vm = new Constructor().$mount();
    expect(vm.$el.querySelector('.hello h1').textContent)
      .to.equal('Welcome to Your Vue.js App');
  });
});

其中,describe和it是mocha的语法结构,describe是这对某个组件或者函数的名字描述,测试脚本里面应该包括一个或多个describe块,每个describe块应该包括一个或多个it块。it是对它需要完成某些功能的描述,它里面是具体的测试用例。在测试框架中,describe,it, expect和sinon都是全局方法。

Chai

Chai也就是一个非常简单的断言库,所谓的断言,就是预期某些执行结果符合你自己的要求。所有的测试用例都应该含有一句或多句的断言。

expect(vm.$el.querySelector('.hello h1').textContent)
      .to.equal('Welcome to Your Vue.js App');

上面这句话的含义,就是在实例化了Hello这个组件之后,针对它某个dom上绑定的文字进行断言,保证了数据绑定后的文字显示。同理,也可以使用在某些js实现某个功能,对它进行自动化测试。

vue-test-utils

vuejs/vue-test-utils是官方的辅助测试库。它其实即是将组件实例化的过程进行封装,帮你模拟它组件实例化过程。shallow这个函数把组件List实例化,并传入props等参数,这样,你可以断言数据绑定的结果。

const items = ['', '']
const wrapper = shallow(List, {
    propsData: { items }
})
expect(wrapper.findAll('li').length).to.equal(items.length)

vue-router和vuex的单元测试问题

项目往往都是使用vuex和vue-router进行异步获取数据,需要外部依赖。这时,我们需要inject-loader来实现对vue组件对象内部的数据模拟。假设我们有这么一个组件,它引用了一个服务,可以是同步或异步(promise),这个对象会被整体替换。

<!-- example.vue -->
<template>
  <div class="msg">{{ msg }}</div>
</template>
 
<script>
// this dependency needs to be mocked
import SomeService from '../service'
 
export default {
  data () {
    return {
      msg: SomeService.msg
    }
  }
}
</script>

首先你要安装inject-loader,通过行内写法注入该组件。

npm install inject-loader@^2.0.0 --save-dev
 
const ExampleInjector = require('!!vue-loader?inject!./example.vue')

在对应的spec.js中添加了需要注入的对象。../service是在组件中的依赖对象,它的结果会被替换。

const ExampleWithMocks = ExampleInjector({
  // mock it
  '../service': {
    msg: 'Hello from a mocked service!'
  }
})

端对端测试

单元测试更多是对某个组件或者js进行功能测试。端对端测试(e2e)用于模拟整个业务流程的进行自动化测试(填报,增删查改等)。vue官方推荐是使用nightwatch,它同样只是个runner,默认配置chromedriver,phantomjs。

NightWatch

NightWatch是一个专门的端对端测试运行器(runner),它的配置文件nightwatch.conf.js会设置对应的命令参数,拼接到nightwatch的命令行操作,详情参考官网。

它依赖于浏览器控制器selenium,而selenium是一个.jar后缀的文件,需要java的运行环境。所以你需要安装java并配置好环境变量。然而,selenium需要对应的driver配合来操控浏览器。

执行测试

default e2e test类似单元测试中的describe和it的测试描述,browser则是传入的浏览器对象,这个对象可以是chrome,也可以是firefox,由selenium控制。url说明的是跳到目标路径,waitForElementVisible说明的是等待5000ms直到id为app的dom出现,然后,assert帮助你进行断言某个dom的内容。

module.exports = {
  'default e2e tests': function test(browser) {
    const devServer = browser.globals.devServerURL;
 
    browser
      .url(devServer)
      .waitForElementVisible('#app', 5000)
      .assert.elementPresent('.hello')
      .assert.containsText('h1', 'Welcome to Your Vue.js App')
      .assert.elementCount('img', 1)
      .end();
  },
};

综上所述,e2e测试的写法很简单,它相较于单元测试得功能检验,更多是浏览器外的控制,针对某些业务流程进行浏览器的操作验证。以前测试工程师要花十分钟完成的“测试流程”,我们可以快速得模拟出来。

写在最后

最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

这些资料,对于做【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!凡事要趁早,特别是技术行业,一定要提升技术功底。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1331944.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Unity中Shader观察空间推导(在Shader中实现)

文章目录 前言一、观察空间矩阵推导1、求观察空间基向量2、求观察空间的基向量在世界空间中的矩阵 的 逆矩阵2、求平移变换矩阵3、相乘得出 观察空间转化矩阵4、得到顶点的世界空间坐标&#xff0c;然后转化到观察空间5、把观察空间坐标转化为齐次裁剪坐标输出到屏幕 二、最终效…

Python入门学习篇(五)——列表字典

1 列表 1.1 定义 ①有序可重复的元素集合 ②可以存放不同类型的数据 ③个人理解:类似于java中的数组1.2 相关方法 1.2.1 获取列表长度 a 语法 len(列表名)b 示例代码 list2 [1, 2, "hello", 4] print(len(list2))c 运行结果 1.2.2 获取列表值 a 语法 列表名…

STM32实现三个小灯亮

led.c #include"led.h"void Led_Init(void) {GPIO_InitTypeDef GPIO_VALUE; //???RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);//???GPIO_VALUE.GPIO_ModeGPIO_Mode_Out_PP;//???? ????GPIO_VALUE.GPIO_PinGPIO_Pin_1|GPIO_Pin_2|GPIO_P…

深度学习中的池化

1 深度学习池化概述 1.1 什么是池化 池化层是卷积神经网络中常用的一个组件&#xff0c;池化层经常用在卷积层后边&#xff0c;通过池化来降低卷积层输出的特征向量&#xff0c;避免出现过拟合的情况。池化的基本思想就是对不同位置的特征进行聚合统计。池化层主要是模仿人的…

Openwrt AP 发射 WiFi 信号

问题 想一次把 OpenWrt 路由器 wifi 问题给解决&#xff0c;完全取代路由器。 使用 倍控的 N5105 设备&#xff0c;有 mPCIe 接口&#xff0c;使用了 intel AX200 无线网卡&#xff0c;支持 2.4G 与 5G。 设置步骤 OpenWrt 镜像 第一次使用的镜像不支持 wifi&#xff0c;在…

Docker知识总结

Docker 学习目标&#xff1a; 掌握Docker基础知识&#xff0c;能够理解Docker镜像与容器的概念 完成Docker安装与启动 掌握Docker镜像与容器相关命令 掌握Tomcat Nginx 等软件的常用应用的安装 掌握docker迁移与备份相关命令 能够运用Dockerfile编写创建容器的脚本 能够…

51单片机拆字程序实验

一、实验内容 1.基本要求 熟悉51仿真系统&#xff1b;设计并单步调试&#xff0c;实现将R5中数值&#xff08;初值为本人学号后两位&#xff09;拆分成两位独立的数据分别存于R6,R7中&#xff1b; 2.扩展要求 将R6,R7中的被拆出来的一位HEX数据转换为可显示的ASCII编码&…

Python算法例27 对称数

1. 问题描述 对称数是一个旋转180后&#xff08;倒过来&#xff09;看起来与原数相同的数&#xff0c;找到所有长度为n的对称数。 2. 问题示例 给出n2&#xff0c;返回[&#xff02;11&#xff02;&#xff0c;&#xff02;69&#xff02;&#xff0c;&#xff02;88&#x…

docker构建镜像及项目部署

文章目录 练习资料下载一、docker基础1. 基本概念2. docker常见命令3. 命令别名4. 数据卷 二、docker自定义镜像1. 了解镜像结构2. 了解Dockerfile3. 构建Dockerfile文件&#xff0c;完成自定义镜像 三、网络1. docker常见网络命令2. docker自带虚拟网络3. 自定义网络 四、dock…

Web前端 ---- 【Vue】vue路由守卫(全局前置路由守卫、全局后置路由守卫、局部路由path守卫、局部路由component守卫)

目录 前言 全局前置路由守卫 全局后置路由守卫 局部路由守卫之path守卫 局部路由守卫之component守卫 前言 本文介绍Vue2最后的知识点&#xff0c;关于vue的路由守卫。也就是鉴权&#xff0c;不是所有的组件任何人都可以访问到的&#xff0c;需要权限&#xff0c;而根据权限…

simulinkveristandlabview联合仿真——模型导入搭建人机界面

目录 1.软件版本 2.搭建simulink仿真模型 编译错误 3.导入veristand并建立工程 4.veristand导入labview labview显示veristand工程数据 labview设置veristand工程数据 运行labview工程 1.软件版本 matlab2020a&#xff0c;veristand2020 R4&#xff0c;labview2020 SP…

第1课 配置FFmpeg+OpenCV开发环境

一、配置开发环境 1.下载FFmpegOpenCV开发所用的SDK压缩包&#xff0c;并解压到E:\SDK下&#xff0c;解压后的路径应为&#xff1a;E:\SDK\ffmpeg-sdk\58\x86\dll及E:\SDK\opencv-sdk\340\x86\dll。 2.新建VC项目&#xff0c;名称为demo1&#xff0c;项目类弄为MFC应用程序&a…

2023年浙大城市学院新生程序设计竞赛(同步赛)G

登录—专业IT笔试面试备考平台_牛客网 题意 思路 首先想法非常单一&#xff0c;一定是去枚举操作点&#xff0c;然后看它染白和不染的价值差值 也就是说&#xff0c;把一个黑色结点染白之后&#xff0c;对哪些结点的价值会影响 不难想象其实就是操作结点的子树和该点连通的…

嵌入式硬件电路原理图之跟随电路

描述 电压跟随电路 电压跟随器是共集电极电路&#xff0c;信号从基极输入&#xff0c;射极输出&#xff0c;故又称射极输出器。基极电压与集电极电压相位相同&#xff0c;即输入电压与输出电压同相。这一电路的主要特点是&#xff1a;高输入电阻、低输出电阻、电压增益近似为…

C/C++ 连接访问 MySQL数据库

前面我们已经讲述了MySQL的基础使用&#xff0c;现在我们来看一下如何使用语言来操作数据库。在实际开发中&#xff0c;语言连接MySQL是为了能够在编程语言中与MySQL数据库进行交互和操作。大部分情况我们都是通过语言连接MySQL&#xff0c;建立与MySQL数据库的连接&#xff0c…

docker笔记2-docker 容器

docker 容器的运行 docker run 镜像名&#xff1a;版本标签&#xff1a; 创建 启动容器 docker run 镜像名 &#xff0c;如果镜像不存在&#xff0c;则会在线下载镜像。 注意事项&#xff1a; 容器内的进程必须处于前台运行状态&#xff0c;不能后台&#xff08;守护进程运行…

Android UID相关知识

一、UID/PID/GID/GIDS的含义和作用 UID : android中uid用于标识一个应用程序&#xff0c;uid在应用安装时被分配&#xff0c;并且在应用存在于手机上期间&#xff0c;都不会改变。一个应用程序只能有一个uid&#xff0c;多个应用可以使用sharedUserId 方式共享同一个uid&#…

【四】【C语言\动态规划】地下城游戏、按摩师、打家劫舍 II,三道题目深度解析

动态规划 动态规划就像是解决问题的一种策略&#xff0c;它可以帮助我们更高效地找到问题的解决方案。这个策略的核心思想就是将问题分解为一系列的小问题&#xff0c;并将每个小问题的解保存起来。这样&#xff0c;当我们需要解决原始问题的时候&#xff0c;我们就可以直接利…

YOLOv8改进 | 主干篇 | 利用SENetV1改进网络结构 (ILSVRC冠军得主)

一、本文介绍 本文给大家带来的改进机制是SENet&#xff08;Squeeze-and-Excitation Networks&#xff09;其是一种通过调整卷积网络中的通道关系来提升性能的网络结构。SENet并不是一个独立的网络模型&#xff0c;而是一个可以和现有的任何一个模型相结合的模块(可以看作是一…

Linux 宝塔mysql莫名其妙数据库不见了恢复数据库

起因&#xff1a;宝塔安装的mysql 线上运行突然表包括库都不见了&#xff0c;想办法恢复数据库 登陆mysql cd /www/server/mysql/binmysql -u root -p查看binlog日志是否打开 show variables like log_%;log_bin如果为 ON 则为开启状态&#xff0c;如果开启了才可以进行下一…