Vitest 单元测试方案

 🔥 交流讨论:欢迎加入我们一起学习!

🔥 资源分享耗时200+小时精选的「软件测试」资料包

🔥 教程推荐:火遍全网的《软件测试》教程  

📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!

简介

  Vitest 是一个面向 Vite 的极快的单元测试框架。它利用了 Vite 的优势,提供了一种全新的测试体验。本文将介绍如何在项目中集成和使用 Vitest 进行单元测试。

  安装 Vitest

  npm install -D vitest

  配置 Vitest

  在项目根目录下创建 vitest.config.js 文件,用于配置 Vitest。

  更多详细配置 cn.vitest.dev/config/

  test: {

      globals: true,

      environment: 'happy-dom',

      restoreMocks: true,

      include: ['**/*.{test,spec,type-test}.{js,mjs,cjs,ts,tsx,jsx}'],

      coverage: {

        exclude: ['tests/**', '.eslintrc.cjs'],

        reporter: ['cobertura', 'text', 'html', 'clover', 'json'],

      },

      setupFiles: `${path.resolve(__dirname, 'tests/setup.ts')}`,

      snapshotFormat: {

        printBasicPrototype: true,

      },

      alias: []

    },

  配置 Vitest公共文件

  在项目根目录下创建setup-test.ts文件,用于统一处理定时器,原生事件,以及在vitest环境下无法模拟的事件

  import { vi, describe, it, expect } from 'vitest';

  import '@testing-library/jest-dom/vitest';

  import MockAdapter from 'axios-mock-adapter';

  import axios from 'axios';

  import { configure } from '.';

  export const mock = new MockAdapter(axios);

  configure({

    renderMode: 'global',

    enableMultipleSelection: false,

  });

  beforeEach(() => {

    mock.reset();

    console.error = vi.fn();

    console.warn = vi.fn();

    vi.useFakeTimers();

    window.requestIdleCallback = vi.fn();

    document.execCommand = vi.fn();

    window.onresize = vi.fn();

    vi.setSystemTime(new Date(1680278400000));

  });

  afterEach(() => {

    mock.reset();

    vi.useRealTimers();

  });

  window.vi = vi;

  window.describe = describe;

  window.it = it;

  window.expect = expect;

  ·全局暴露 vi describe it expect 方法,如果以后更换测试框架,单元测试内部代码无需改动

  · 全局暴露mock,并在beforeEach 与 afterEach 清空相关的mock接口

  · 初始化单元测试环境内时间

  单元测试分类

  · 单元测试:主要是对项目里的最小 组件 或模块进行测试,一般是在非浏览器环境下的测试

  · 集成测试:一般是对单元测试下的多个最小单元组成的较大 组件 或模块进行小型的组合测试,一般是在非浏览器环境下的测试。

  · 端到端 测试 (E2E) : 从用户的视角出发,基于整个页面或者应用,模拟用户操作测试,一般是在浏览器环境下的测试

  如何编写 单元测试

  在项目src目录平级的位置,新建tests文件,tests文件夹下新建mocks文件夹

  · mocks下主要存放对应单元测试模拟数据的文件

  · tests下主要存放对应的单元测试文件

  如何模拟接口请求

  在项目中引入axios-mock-adapter第三方工具库,在进行测试的test文件下新建Mock文件夹,然后新建 test-demo-mock.ts文件。

  详细配置 github.com/ctimmerm/ax…

  import { mock } from '../../../src/setup-test';

  export const TestDemoMock = {

    getUsersTitle: (status: number) => {

      mock.onGet('/users/title').reply(status, { title: '江雾' });

    },

  }; 

  编写测试用例

  新建一个test-demo.tsx文件,编写React组件

  import axios from 'axios';

  import { useEffect, useState } from 'react';

  const TextDemo: React.FC = () => {

    const [title, setTitle] = useState('测试');

    const getTitleValue = async () => {

      const response = await axios.get('/users/title');

      const { status, data } = response;

      if (status === 200) {

        setTitle(data.title);

      } else {

        // error

        setTitle('接口异常');

      }

    };

    const changeBtn = () => {

      setTitle('江雾');

    };

    return (

      <div className="test-dome-content">

        <span className="title"> {title} </span>

        <button className="refresh-button" onClick={getTitleValue}>

          refresh

        </button>

        <button onClick={changeBtn} className="change-btn">

          change

        </button>

      </div>

    );

  };

  export default TextDemo;

  新建test-demo.test.ts单元测试文件

  import { fireEvent, render } from '@testing-library/react';

  import TextDemo from '../../src/test-demo';

  import { TestDemoMock } from './Mock/test-demo-mock';

  describe('getUser', () => {

    it('mount title', async () => {

      const { container } = render(<TextDemo />);

      // 初始化期望 页面标题为测试

      const title = document.body.querySelector('.test-dome-content .title');

      expect(title?.innerHTML).toBe('测试');

    });

    it('change title', async () => {

      await TestDemoMock.getUsersTitle(200);

      render(<TextDemo />);

      // 初始化期望 页面标题为测试

      const title = document.body.querySelector('.test-dome-content .title');

      expect(title?.innerHTML).toBe('测试');

      // 点击按钮

      const btn = document.body.querySelector(

        '.test-dome-content .refresh-button',

      );

      fireEvent.click(btn!);

      await vi.waitFor(() => {

        const targetTitle = document.body.querySelector(

          '.test-dome-content .title',

        );

        expect(targetTitle?.innerHTML).toBe('江雾');

      });

    });

    it('change title error', async () => {

      // 模拟接口请求

      await TestDemoMock.getUsersTitle(201);

      render(<TextDemo />);

      // 初始化期望 页面标题为测试

      const title = document.body.querySelector('.test-dome-content .title');

      expect(title?.innerHTML).toBe('测试');

      // 点击按钮

      const btn = document.body.querySelector(

        '.test-dome-content .refresh-button',

      );

      fireEvent.click(btn!);

      // 期望接口失败内容为接口异常

      await vi.waitFor(() => {

        const title = document.body.querySelector('.test-dome-content .title');

        expect(title?.innerHTML).toBe('接口异常');

      });

    });

  });

  常见的命令

  ·pnpm run test : 执行所有单元测试

  · pnpm test xxx.test.ts : 执行某个单元测试文件

  · pnpm run coverage: 覆盖率报告

  代码覆盖率报告

  执行 pnpm run coverage 会生成coverage 文件夹,将其中的index.html 拖入浏览器中,查看具体的单元测试代码覆盖详情。

  E2E快速补齐单测方案

  自动化录制解决方案

  ·Chrome 插件 DeploySentinel Recorder

  · Chrome 插件 Headless Recorder

  · Playwrighg 官方的 CLI Playwright CLI Codegen

  · eTest 插件

最后我邀请你进入我们的【软件测试学习交流群:785128166】, 大家可以一起探讨交流软件测试,共同学习软件测试技术、面试等软件测试方方面面,还会有免费直播课,收获更多测试技巧,我们一起进阶Python自动化测试/测试开发,走向高薪之路

作为一个软件测试的过来人,我想尽自己最大的努力,帮助每一个伙伴都能顺利找到工作。所以我整理了下面这份资源,现在免费分享给大家,有需要的小伙伴可以关注【公众号:程序员二黑】自提!

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

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

相关文章

鸿蒙OS开发案例:【API9】遍历沙漏文件夹并输入文件的大小

1.获取打印文件大小 /*** 获取打印文件大小*/static getFileSize(byteNum: number) {if (byteNum < 0) {return "shouldnt be less than zero!";} else if (byteNum < 1024) {return ${byteNum.toFixed(3)}B;} else if (byteNum < 1048576) {return (byteNu…

Mysql各种日志管理

文章目录 事务日志事务日志的记录过程事务日志类型事务日志的相关变量 错误日志二进制日志功能作用文件的构成日志格式查看日志删除日志 通用日志慢查询日志 Mysql日志记录着数据库在运行过程中的各种操作&#xff0c;帮助管理员定位查找问题。 事务日志 事务日志(Transaction…

(原型与原型链)前端八股文修炼Day5

一 原型链的理解 原型链定义&#xff1a; 原型链是 JavaScript 中实现对象继承的关键机制之一&#xff0c;它是一种对象之间的关系&#xff0c;通过这种关系&#xff0c;一个对象可以继承另一个对象的属性和方法。 原型链的组成&#xff1a; 每个对象都有一个指向另一个对象的…

Vue3尚硅谷张天禹笔记

1. Vue3简介 2020年9月18日&#xff0c;Vue.js发布版3.0版本&#xff0c;代号&#xff1a;One Piece&#xff08;n 经历了&#xff1a;4800次提交、40个RFC、600次PR、300贡献者 官方发版地址&#xff1a;Release v3.0.0 One Piece vuejs/core 截止2023年10月&#xff0c;最…

每日一题 --- 删除链表的倒数第 N 个结点[力扣][Go]

删除链表的倒数第 N 个结点 题目&#xff1a;19. 删除链表的倒数第 N 个结点 给你一个链表&#xff0c;删除链表的倒数第 n 个结点&#xff0c;并且返回链表的头结点。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5], n 2 输出&#xff1a;[1,2,3,5]示例 2&#x…

zotero+word优化管理参考文献

写论文&#xff0c;整理参考文献&#xff0c;管理参考文献很麻烦&#xff0c;参考文献格式罗列很麻烦&#xff0c;论文需要修改时&#xff0c;重新调整参考文献顺序很麻烦。 zoteroword可以很好的帮助解决这个问题。 Step1 zotero软件安装 默认word你已经安装好了 step2 安…

linux下的打包/解包命令(tar,zip/unzip)

目录 打包/解包 作用 zip -r选项 unzip -d选项 如果不使用递归压缩 -l / -v选项 tar 介绍 选项 示例 打包/解包 作用 使多个文件变成一个文件,不易造成数据缺失使下载时间变短 zip 将目录或文件压缩成zip格式 -r选项 递归式压缩某目录及其所有子目录中的文件 如果不…

有效三角形的个数【双指针】

1.优化版暴力求解 如果能构成三⻆形&#xff0c;需要满⾜任意两边之和要⼤于第三边。实际上只需让较⼩的两条边之和⼤于第三边即可。将原数组排序&#xff0c;从⼩到⼤枚举三元组&#xff0c;这样三层 for 循环枚举出的三元组只需判断较⼩的两条边之和是否⼤于第三边。 class…

Qt开发(2)——在已有VS项目中配置Qt

在之前的Qt开发学习中&#xff0c;基本都是在Qt Creator中创建一个Qt项目&#xff0c;或者即便是在VS中也是直接新建一个Qt项目。但很少有记录如何在已有的C项目中添加Qt,这就好比我有个项目已经开发完了&#xff0c;现在又说加个Qt界面的功能。这篇文章就是记录如何在已有项目…

那如何解决信创设配问题呢?怎么成为信创产品?

信创也好、国产化也好都是国家部署的重点工作&#xff0c;所有涉及到的相关行业和部门都必须坚持执行和并且要执行好的重点任务&#xff0c;这一点无容置疑。在信息化层面&#xff0c;随着我国基础水平&#xff08;芯片、OS、DB、中间件&#xff09;的提升&#xff0c;信创工作…

臻奶惠:无人售货奶柜,让纯净营养触手可及

臻奶惠&#xff1a;无人售货奶柜&#xff0c;让纯净营养触手可及 在这个快速发展的时代&#xff0c;每一个创新都在为生活带来便捷和品质的提升。臻奶惠深谙此道&#xff0c;特推出无人售货奶柜&#xff0c;将健康营养与现代科技完美融合&#xff0c;为您和家人提供24小时不间…

如何让笔记本电脑发挥120%的性能?原来还有这种小技巧

前言 现在的笔记本电脑性能真的是越来越好了&#xff01;但笔记本的CPU终究受到功耗的限制&#xff0c;与同代的台式机CPU性能相差不是一点半点的。 小白在之前很长一段时间也是使用着Windows系统的笔记本&#xff0c;也见过不下百款笔记本。 笔记本为了轻便&#xff0c;通常…

逐步学习Go-并发通道chan(channel)

概述 Go的Routines并发模型是基于CSP&#xff0c;如果你看过七周七并发&#xff0c;那么你应该了解。 什么是CSP&#xff1f; "Communicating Sequential Processes"&#xff08;CSP&#xff09;这个词组的含义来自其英文直译以及在计算机科学中的使用环境。 CSP…

SpringBoot整合Swagger-UI实现在线API文档

✅作者简介:大家好,我是Leo,热爱Java后端开发者,一个想要与大家共同进步的男人😉😉🍎个人主页:Leo的博客 💞当前专栏: 循序渐进学SpringBoot ✨特色专栏: MySQL学习 🥭本文内容:SpringBoot整合Swagger-UI实现在线API文档 📚个人知识库: Leo知识库,欢迎大…

YOLOv9改进策略:卷积魔改 | DCNv2升级版本,助力检测

&#x1f4a1;&#x1f4a1;&#x1f4a1;本文改进内容&#xff1a;在DCN的基础上&#xff0c;增加了2个创新点&#xff0c;分别是调制模块和使用多个调制后的DCN模块&#xff0c;从形成了DCN的升级版本——DCNv2 &#x1f4a1;&#x1f4a1;&#x1f4a1;如何使用&#xff1a…

红岩思维导图的制作软件,分享4款热门的!

红岩思维导图的制作软件&#xff0c;分享4款热门的&#xff01; 在当今信息爆炸的时代&#xff0c;思维导图作为一种有效的知识整理和思维拓展工具&#xff0c;受到了广大用户的青睐。红岩思维导图以其独特的风格和实用性&#xff0c;成为了许多人学习和工作中的得力助手。那么…

【SpringSecurity】基础入门

目录 权限管理什么是权限管理认证授权权限管理解决方案Shiro开发者自定义Spring Security Spring Security特性Spring、Spring Boot 和 Spring Security 三者的关系整体架构1.认证AuthenticationManagerAuthenticationSecurityContextHolder 2.授权AccessDecisionManagerAccess…

作为数据分析师,如何能把AI工具和数据分析工作更好的结合?

在当今信息爆炸的时代&#xff0c;数据已经成为企业、研究机构乃至个人决策的重要依据。然而&#xff0c;如何高效地处理、分析和解读这些数据&#xff0c;从而提炼出有价值的信息&#xff0c;却成为了一个亟待解决的问题。 幸运的是&#xff0c;随着人工智能技术的飞速发展&a…

二叉树|450.删除二叉搜索树中的节点

力扣题目链接 class Solution { public:TreeNode* deleteNode(TreeNode* root, int key) {if (root nullptr) return root; // 第一种情况&#xff1a;没找到删除的节点&#xff0c;遍历到空节点直接返回了if (root->val key) {// 第二种情况&#xff1a;左右孩子都为空&…

【WEEK4】 【DAY5】AJAX第二部分【中文版】

2024.3.22 Friday 接上文【WEEK4】 【DAY4】AJAX第一部分【中文版】 目录 8.4.Ajax异步加载数据8.4.1.新建User.java8.4.2.在pom.xml中添加lombok、jackson支持8.4.3.更改tomcat设置8.4.4.修改AjaxController.java8.4.5.新建test2.jsp8.4.5.1.注意&#xff1a;和WEB-INF平级&…