Next.js | Jest + React testing library + Typescript 单元测试框架搭建及实现

news/2024/7/15 18:07:28 标签: javascript, react.js, typescript, 单元测试

前言

单元测试和 E2E 测试作为 前端项目健壮性的保障,在许多团队可能并没有足够的能力和资源去实现很好的自动化测试,但基本的了解还是必不可少的。

最近在上手并集成单元测试到已有的 Next.js 项目中,网上的文档虽然很多,但实际使用的时候遇到的问题可谓五花八门,这篇文章可以帮助你快速的在 Next.js + TS 的环境中构建单元测试环境及进行单测的编写。

框架搭建

Jest 是目前最主流的前端测试框架,仅通过 Jest 没办法完成前端的所有单元测试,因为前端的单元测试涉及到 Dom 和事件的模拟。因此我们还需要一些测试辅助库来为我们模拟相关的场景。DOM Testing Library 适用于任何提供 DOM API 的环境,这个库提供了包含 ReactVue, Angular 这三个主流框架的 API,使用这些 API 我们可以在执行单测时实现 类似于用户在页面上查找元素 的方式查询 DOM 中的节点的操作,帮助我们实现更加符合真实环境的测试。

下面我们在已有的 Next.js 项目的基础上引入 JestReact testing library 以及相关的一些依赖,执行以下命令:

yarn add jest jest-environment-jsdom @testing-library/react @testing-library/jest-dom -D

接下来我们需要创建一下一下 Jest 的配置文件,在项目根目录下创建 jest.config.ts ,写入以下配置:

const nextJest = require('next/jest');

const createJestConfig = nextJest({
  // Provide the path to your Next.js app to load next.config.js and .env files in your test environment
  dir: './',
});

// Add any custom config to be passed to Jest
const customJestConfig = {
  // Add more setup options before each test is run
  // if using TypeScript with a baseUrl set to the root directory then you need the below for alias' to work
  moduleDirectories: ['node_modules', '<rootDir>/'],
  testEnvironment: 'jest-environment-jsdom',
  testPathIgnorePatterns: ['<rootDir>/cypress/'],
  setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
  moduleNameMapper: {
    '^@/(.*)$': '<rootDir>/src/$1',
  },
};

// createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async
module.exports = createJestConfig(customJestConfig);

export {};

然后再创建 jest.setup.ts 文件,暂时先写入以下配置:

import '@testing-library/jest-dom/extend-expect';

这个配置文件是根据 Next.js 文档中提供的配置进行修改的,我们先看看文档中对于这段配置的描述:

在后台,next/jest 会自动为我们配置 Jest,包括以下步骤:

而我单独加的配置有如下几个:

  1. testPathIgnorePatterns: ['<rootDir>/cypress/']: 需要忽略的测试目录,这里我忽略了 cypres 目录,因为我们的 E2E 测试使用的是 Cypress ,如果不忽略的话,在执行 jest 的测试命令时会把 E2E 的测试也给跑起来。
  2. setupFilesAfterEnv: ['<rootDir>/jest.setup.ts']:配置 Jest 的 setup 文件位置,Jest 的 setup 文件用于在 执行测试时先执行一些固定的初始化操作,例如执行一些 import 等操作,这样就不需要在每一个测试中单独引入某些依赖了。
  3. moduleNameMapper: { '^@/(.*)$': '<rootDir>/src/$1', }:这一步是为了配置一下测试文件中 引入依赖时的别名,就像 webpack 或 vite 中 alias 配置的功能,当在引入依赖的目录中开头为 @ 时,会指向根目录下的 src 目录。
  4. 在配置文件的最后有一个 export {} ,这一步是为了解决当 tsconfig.json 中的 isolatedModules 设置为 true 时,如果 ts 文件中不存在
    importexport 时,ts 认为这个文件不是一个 ES Module,而是一个全局脚本,导致编译时报错。

接下来我们在 package.json 中新增一个指令:

"scripts": {
  //...
  "test": "jest"
}

当我们执行例如 yarn test 时,Jest 会去识别我们目录中的所有测试文件并执行。此时如果我们执行运行测试,会打印如下错误:

Error: Jest: Failed to parse the TypeScript config file

这个错误的原因是我们的配置文件是由 Node.js 去直接执行的,而 Node.js 并不能直接执行 ts 文件,我们也没有将配置文件进行编译,所以我们需要安装一下 ts-node,执行以下命令进行安装:

yarn add ts-node -D

安装后再次执行 yarn test 就不会报错了,ts-node 的作用就是让 Node.js 可以直接运行 ts 脚本,在执行的过程中自动进行编译,不需要我们自己提前编译为 js 脚本,更多详情可以参考 ts-node 官网

测试 Demo 编写

在框架搭建完成后,我们来实现一个简单的 demo 上手一下,首先我们需要设计一下测试的文件要放在哪个目录,这里我是将组件的测试目录与组件放在同一个目录中的,例如我们有一个 返回上一级的按钮组件 Back ,它的目录为 src/components/Back/index.tsx,这里我们再创建一个 src/components/Back/__test__ 目录用于放置测试文件,然后我们在目录中创建 index.test.tsx 文件,写入以下代码:

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

import Back from '../index';

describe('Back', () => {
  it('should render with default text', () => {
    render(<Back />);

    const element = screen.getByText(/back/i);

    expect(element).toBeInTheDocument();
  });

  it('should render with right test', () => {
    render(<Back text="Back to home" />);

    const element = screen.getByText(/Back to home/i);

    expect(element).toBeInTheDocument();
  });
});

describe 用于定义一个 测试用例组it 则用于定义一个 单独的测试用例,这两个 API 是全局定义的,并不需要引入。

代码中我们创建了一个测试用例组,其中包含了两个测试,it 的第一个参数用于描述测试的作用,这里就简单测试下 默认情况传入参数的情况 下组件是否能正确渲染。render 用于渲染组件,screen 大家可以理解为测试环境的 document,可以用于获取渲染的 dom 节点,expect 则是用于检查值是否满足特定条件。

因此这里的测试流程也就是:

  1. 引入并渲染组件
  2. 根据某些条件获取 dom 节点
  3. 判断组件是否正确渲染

后续更复杂的测试大致也是根据这种测试思路进行延伸,关于 API 的具体作用请参考 React-testing-library 文档 与 Jest API 文档

配置 Github Action

在我们的测试可以顺利执行后,我们可以实现一下单测的自动化,这里以 Github Action
为例,基础的实现还是非常简单的,首先创建一个新的 workfolw 配置文件 your_project/.github/workflows/frontend-unit.yml

然后写入以下配置:

name: CI
on: push
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - name: Install modules
      run: yarn
    - name: Run tests
      run: yarn test

这个配置文件就是在 ubuntu 环境中执行 yarn test 开始测试,当然在实际的项目中肯定不止这么简单,但根据实际情况进行触发时机的修改或增加执行流程即可,当然你也可以增加测试覆盖率的打印等命令,这个会在后面我实践后单独出文章介绍。

总结

这篇文章介绍了下如何在 Next.js 搭建组件测试的环境以及最基本的测试实现,关于更多的踩坑以及一些最佳实践会在后续摸索后继续出文章,如果大家对于 E2E 测试想要了解也可以评论区留言,在 E2E 测试方面我们已经有了比较丰富的实践经验,可以期待下后续的文章。如果这篇文章对你有帮助欢迎点赞或关注


http://www.niftyadmin.cn/n/26021.html

相关文章

Oracle常用命令,DBA的基础操作,Oracle运维基础操作

用户 sys 和system都是系统管理员&#xff08;DBA&#xff09;&#xff0c;拥有最大的权限&#xff0c;密码是安装时设置的&#xff1b; scott是普通用户&#xff0c;拥有一些用于学习的表&#xff0c;初始密码是tiger。 内置角色 角色是权限的集合&#xff0c;以下是三个内…

通过软考高项的朋友看过来~“专家库”等你申报

众所周知&#xff0c;取得软考证书有几大好处&#xff0c;可以升职加薪&#xff0c;落户&#xff0c;加入专家库等等。 很多朋友问&#xff1a;其他几个都好理解&#xff0c;加入专家库是什么呢&#xff1f;软考高级可以申请加入哪种专家库&#xff1f;接下来就来为大家解答如…

2023兔年大吉HTML,兔兔动态代码「兔了个兔」

文章目录一.2023兔年大吉HTML&#xff0c;兔兔动态代码「兔了个兔」1.1 资源获取和效果预览二.代码讲解&#xff08;主要代码&#xff09;1.1 背景加圆圈圈1.2.兔兔和提示字1.3 JavaScript控制动态一.2023兔年大吉HTML&#xff0c;兔兔动态代码「兔了个兔」 1.1 资源获取和效果…

异常检测-缺陷检测-论文精读PaDiM

Abstract 我们提出了一个新的 Patch 分布建模框架&#xff0c;在单类学习的设置下&#xff0c;PaDiM 同时检测和定位图像中的异常。PaDiM 利用一个预先训练好的卷积神经网络 (CNN) 进行 patch 嵌入&#xff0c;利用多元高斯分布得到正常类的概率表示。它还利用了 CNN 的不同语…

ELAN设计理念:通过梯度路径分析设计网络设计策略

设计高效、高质量的表达性网络架构一直是深度学习领域最重要的研究课题。当今的大多数网络设计策略都集中于如何集成从不同层提取的特征&#xff0c;以及如何设计计算单元来有效地提取这些特征&#xff0c;从而增强网络的表现力。本文提出了一种新的网络设计策略&#xff0c;即…

Biome-BGC生态系统模型区域模拟

Biome-BGC是利用站点描述数据、气象数据和植被生理生态参数&#xff0c;模拟日尺度碳、水和氮通量的有效模型&#xff0c;其研究的空间尺度可以从点尺度扩展到陆地生态系统。在Biome-BGC模型中&#xff0c;对于碳的生物量积累&#xff0c;采用光合酶促反应机理模型计算出每天的…

网络基础(一)

网络基础&#xff08;一&#xff09;计算机网络背景网络发展独立模式: &#xff08;计算机之间相互独立&#xff09;网络互联: ( 多台计算机连接在一起, 完成数据共享)局域网LAN: (计算机数量更多了, 通过交换机和路由器连接在一起);广域网WAN: &#xff08;将远隔千里的计算机…

feign.FeignException$BadRequest: status 400 reading 诡异错误记录

诡异事情描述&#xff1a;A客户端通过feign调用 服务端接口报错feign.FeignException$BadRequest: status 400 reading。B客户端通过feign调用服务端接口 又是正常的返回。 A和B 项目中导入的相关feign版本都一样。代码调整前如下&#xff1a;客户端代码&#xff1a;Data publi…