对单元测试的思考(稳定性建设)

news2024/11/16 11:43:56

单测是很常见的技术的名词,但背后的逻辑和原理你是否清楚,让我们一起review一下。

1. 单测是什么?🤔

单测是单元测试,主要是测试一个最小逻辑块。比如一个函数、一个react、vue 组件。

2.为什么要写单测?🤔

这里有短期和长远,两个方面做打算:

短期:

希望开发者在开发过程中,就要想清楚多种case的情况,来检测这个最小单元的可靠性

举个例:

describe('test getUriEnd', () => {
  it('case1', async () => {
    const ret = getUriEnd(...);
    expect(ret).toBe('...');
  });

  it('case2', async () => {
    const ret = getUriEnd(...);
    expect(ret).toBe('...');
  });

  it('case3', async () => {
    const ret = getUriEnd('');
    expect(ret).toBe('error');
  });

  it('case4', async () => {
    const ret = getUriEnd([]);
    expect(ret).toBe('error');
  });
});

长期:

从长期的维护角度来看的话,各个最小单元都是可能有被修改的风险。如果有完整的单侧的case,是可以保证:迭代、修改后的功能单元,不是会出现一些边缘问题

并且长期来看:单侧也可以作为一个这个功能单元的使用说明书的作用。帮助开发更好的理解功能。

3.单测是跑在什么环境的?🤔

是跑在node环境的。

那为什么可以测试一些和浏览器环境相关的操作?比如:document.createElement

test('use jsdom in this test file', () => {  
    const element = document.createElement('div');  
    expect(element).not.toBeNull();  
});

要设置当前单测运行的环境,否则上面的单测会报错,因为单测是跑在node环境的(我这里以jest为例)

在jest内,需要配置 testEnvironment: ‘jsdom’ (不主动配置的话,这里是node,代表node环境)。

jest文档:jestjs.io/zh-Hans/doc…

那jest是怎么做到模拟浏览器环境的?

jest用的是jsdom:github.com/jsdom/jsdom (jsdom模拟浏览器环境的原理,可以参考jsdom的官网)。

本质还是运行在node内,只不过用了jsdom来模拟浏览器环境。

4.单测的原理是什么?🤔

原理是:

给最小单元:提供运行时环境(node或浏览器环境,且包含对应依赖)。让这个最小单元在这个环境里面去执行,跑case,检验是否符合预期。

5.单测中需要注意哪些问题?为什么单测会引发这些问题?🤔

单测的核心问题就是准备环境,为了让单测可以正常执行,我们需要准备好上下游环境,还有依赖环境。

比如你要测试一个vue组件的props,那么你就需要为他准备好相关的vue实例,往单测的node环境里面注入Vue,例如 import { shallowMount } from ‘@vue/test-utils’

import { shallowMount } from '@vue/test-utils'
import Drawer from '@/components/common/drawer.vue'

test('test drawer', () => {
  const wrapper = shallowMount(Drawer, {
    propsData: {
      direction: 'top',
      show: true,
      canConfirm: true,
      title: 'my drawer',
      leftText: 'left text',
      rightText: 'right text'
    }
  })
  const text = wrapper.text()
  expect(text).toContain('my drawer')
  expect(text).toContain('left text')
  expect(wrapper.get('.drawer-top')).not.toBeNull()

  wrapper.find('.header-right').trigger('click')
  wrapper.find('.header-left').trigger('click')

  expect(wrapper.emitted()).toHaveProperty('onConfirm')
  expect(wrapper.emitted()).toHaveProperty('onCancel')
})

如果涉及到路由相关的话,那么还需要准备路由相关依赖。

有些依赖实在不好准备的话,需要设置mock(比如依赖一个额外的SDK,但这个SDK没法在node里面的跑)。

import { mount, createLocalVue } from '@vue/test-utils'
import Register from '@/components/xxx.vue'
import Vuex from 'vuex'

const localVue = createLocalVue()
localVue.use(Vuex)

jest.mock('@xxx/sdk.css', () => { // 这里设mock
  return ''
})

describe('test register', () => {
  const store = new Vuex.Store({
    actions: {},
    state: {
      form: {
        formData: {
          selectCountry: '',
        },
      },
    },
    getters: {
      'user/userCountry': () => ''
    },
  })
  const wrapper = mount(Register, {
    store,
    localVue,
    mocks: { // 这里也可以设mock
      $route: {
        query: {}
      }
    }
  })
  it('should vm', () => {
    expect(wrapper.vm).toBeTruthy()
  })

  it('should xxx', () => {
    expect(wrapper.find('#xxxdom').exists()).toBeTruthy()
  })
})

如果涉及到接口请求的话,接口是下游rpc或者是服务发现的话,那么单侧环境是肯定调不通的。因为有环境隔离。这种情况下就只能Mock数据了。

为什么单测会引发这些问题,感觉这么麻烦?

因为单测是运行在node环境里跑,相当于本地,本地去掉下游rpc服务或走服务发现,本来就是不行的,因为环境隔离。本地加代理,也只能调通测试环境rpc服务

单测环境是一个“干净”的环境,不主动准备的话 是没有node_modules的。如果你的测试单元 有各种依赖,单测环境肯定是没有的,除非你自己准备好 或者 mock模拟/代理掉

6.哪些场景适合写单测?🤔

首先写单测肯定是有成本的,我个人认为,非常重要的toC项目才有必要写单测;

先覆盖核心功能;

功能单一的函数或组件是很适合写单测的。

7.怎么定义一个单测写的好不好?🤔

单纯不考虑成本的话,那么一个单测的好坏应该是看这一个单元的功能覆盖率 + 边界case的覆盖情况。越多越好。

8.对单测成本和收益的思考?🤔

团队内的任何决策都是有成本的,单测也不例外,需了解成本和收益后,再考虑在团队内推进。

单测成本:

主要是开发成本:写单测、code review,边界case覆盖。

单测收益:

未来的维护成本会更低,项目质量、稳定性更好。

有利于倒逼开发写出高质量的代码、关注稳定性。

我个人思考,还是想低成本得到所有好处(“我都要”):选择性写单测

个人认为写单测的条件:toC且核心流程 + 很难自测的部分(边界case) + e2e或快照测试很难覆盖到的部分

某些业务场景,后续肯定也是要自测的话,那这部分相关的可以不用写单测。

e2e或快照测试,能覆盖到的,可以不写单测。

行动吧,在路上总比一直观望的要好,未来的你肯定会感谢现在拼搏的自己!如果想学习提升找不到资料,没人答疑解惑时,请及时加入群:1007119548,里面有各种测试开发资料和技术可以一起交流哦。

最后: 下方这份完整的软件测试视频教程已经整理上传完成,需要的朋友们可以自行领取 【保证100%免费】

在这里插入图片描述

软件测试面试文档

我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。在这里插入图片描述
在这里插入图片描述在这里插入图片描述

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

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

相关文章

扩展学习|大数据分析的现状和分类

文献来源:[1] Mohamed A , Najafabadi M K , Wah Y B ,et al.The state of the art and taxonomy of big data analytics: view from new big data framework[J].Artificial Intelligence Review: An International Science and Engineering Journal, 2020(2):53. 下…

windows系统下安装RabbitMQ

一、RabbitMQ安装软件资源准备 因为RabbitMQ是Erlang语言开发的,因此安装Erlang环境在进行安装RbbitMQ的操作,选择两者版本时一定要参考版本的兼容性 1.RabbitMQ国内下载地址,因官网下载比较缓慢,还是国内的稍微快些 https://r…

CTFHUB--文件包含漏洞--RCE

文件包含漏洞 文件包含漏洞也是一种注入型漏洞,其本质就是输入一段用户能够控制的脚本或者代码,并让服务端执行。有时候由于网站功能需求,会让前端用户选择要包含的文件,而开发人员又没有对要包含的文件进行安全考虑,…

Linux yum安装pgsql出现Bad GPG signature错误

官方文档:https://www.postgresql.org/download/linux/redhat/ sudo yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm sudo yum install -y postgresql12-server sudo /usr/pgsql-12/bin/…

Angular 由一个bug说起之四:jsonEditor使用不当造成的bug

一:问题 项目中使用了一个JSON第三方库: GitHub - josdejong/jsoneditor: A web-based tool to view, edit, format, and validate JSON 当用户编辑JSON格式的数据,查找替换时: 用户的期望结果是:$$ 被替换为$$_text&a…

使用 Azure 部署静态网页

Author:AXYZdong 硕士在读 工科男 有一点思考,有一点想法,有一点理性! 定个小小目标,努力成为习惯!在最美的年华遇见更好的自己! CSDNAXYZdong,CSDN首发,AXYZdong原创 唯…

ROS开发基础-Linux基础第四部(开发板设置本地IP)

一 、网线连接设备 使用网线连接jetson NX与机械臂,如下图所示: 二、 修改上位机IPV4 IP ①测试是否可连接。网线连接机械臂之后,在桌面打开终端输入命令“ping 192.168.1.18”,如不可正常通信,可按照下述步骤进行设置。 ②在U…

React富文本编辑器开发(一)

这是一个系统的完整的教程,每一节文章的内容都很重要。这个教程学完后自己可以开发出一个相当完美的富文本编辑器了。下面就开始我们今天的内容: 安装 是的,我们的开发是基于Slate的开发基础,所以要安装它: yarn ad…

Go 互斥锁的实现原理?

Go sync包提供了两种锁类型:互斥锁sync.Mutex 和 读写互斥锁sync.RWMutex,都属于悲观锁。 概念 Mutex是互斥锁,当一个 goroutine 获得了锁后,其他 goroutine 不能获取锁(只能存在一个写者或读者,不能同时…

Neural Network Diffusion论文解读

详细解读:扩散模型生成神经网络参数,速度快了44倍:Neural Network Diffusion论文解读 摘要: 扩散模型在图像和视频生成方面取得了显著的成功。在这项工作中,我们证明了扩散模型也可以生成高性能的神经网络参数。我们…

程序员的金三银四求职宝典!

目录 ​编辑 程序员的金三银四求职宝典 一、为什么金三银四是程序员求职的黄金时期? 二、如何准备金三银四求职? 1. 完善简历 2. 增强技术能力 3. 提前考虑目标公司 4. 提前准备面试 三、程序员求职的常见面试题 1. 数据结构和算法 2. 数据库 …

在原有pytorch环境下安装DGL库和其对应的CUDA【自用】

前段时间看到一篇AAAI2024的论文Patch-wise Graph Contrastive Learning for Image Translation,它采用GNN的思想来进行image-to-image translation的任务,非常的新颖,但我进行复现的时候,发现直接下载它里面需要的DGL库是无法运行…

旧的Spring Security OAuth已停止维护,全面拥抱新解决方案Spring SAS

Spring Authorization Server 替换 Shiro 指引 背景 Spring 团队正式宣布 Spring Security OAuth 停止维护,该项目将不会再进行任何的迭代 目前 Spring 生态中的 OAuth2 授权服务器是 Spring Authorization Server 已经可以正式生产使用作为 SpringBoot 3.0 的最新…

C#中什么是非托管代码?托管代码和非托管代码有什么区别

在C#中,托管代码和非托管代码是两种不同类型的代码,它们在内存管理和执行环境上有所不同。 托管代码(Managed Code): 托管代码是由.NET运行时(CLR,Common Language Runtime)管理和执…

Neo4j学习笔记2:使用Neo4j-admin import快速初始化导入数据

上一篇提到过小规模数据如何新增到数据库,但是一旦数据开始变多,效率就不够看了 同样的数据,使用上一篇的方法,预计要26天,但是使用Neo4j-admin import只要1分钟 参考文档在这里 文件处理 具体的导入csv文件结构可以…

没有经验的新手小白能做抖音小店无货源吗?

大家好,我是电商花花。 一个没有电商经验,没有货源的新手能做抖音小店吗? 这应该是很多想做抖音小店的一个疑虑吧,想做又担心做不好。 今天花花说一下关于我个人对抖音小店无货源的一些小见解吧,希望能给到你建议。 …

为什么网站页面没有被百度搜索收录?是网站被攻击了?

例如,为什么网站页面没有被百度搜索收录? 网站是否受到攻击? 网站索引量和网站流量之间有关系吗? 您在运行网站或小程序时是否有过这样的疑问? 下面我将为大家详细解答这些问题。 1.PC/H5站点相关 1、为什么新网站页面…

【真机Bug】异步加载资源未完成访问单例导致资源创建失败

1.错误表现描述 抽卡时,10抽展示界面为A。抽取内容可能是整卡或者碎片,抽到整卡,会有立绘展示和点击详情的按钮。点击详情后出现详情页B。【此时界面A预制体被销毁,卡片数据进入数据缓存池】点击页面B的返回按钮,单例…

2024理解这几个安全漏洞,你也能做安全测试!

如今安全问题显得越来越重要,一个大型的互联网站点,你如果每天查看日志,会发现有很多尝试攻击性的脚本。 如果没有,证明网站影响力还不够大。信息一体化的背后深藏着各类安全隐患,例如由于开发人员的不严谨导致为Web应…

【计算复杂性理论】证明复杂性(九):命题鸽巢原理的指数级归结下界——更简短的证明

往期文章: 【计算复杂性理论】证明复杂性(Proof Complexity)(一):简介 【计算复杂性理论】证明复杂性(二):归结(Resolution)与扩展归结&#xff…