关于react.js:react-vite-testinglibrary单测环境构建

2次阅读

共计 5046 个字符,预计需要花费 13 分钟才能阅读完成。

业务复杂多变迭代疾速,加上编写单测其实是消耗肯定工夫去做的,可能很多人认为编写单元测试是一件吃力不讨好的事儿,不会在我的项目中被动的去做单元测试,一两年前笔者也是这样的一种心态,对于单测不屑一顾,然而随着看的书多了,学习的货色多了,明确了单测可有无效的保障咱们一些外围性能的正确性,同样能够反推咱们的设计一些通用性能是否全面,再者也能够在咱们改变一些性能后,校验原有性能的正确性,说这么多,还须要大家本人写起来单测,一个货色好不好,只有用起来了才晓得,在 vite 下配置 jest 单测代码一上传至 git,有趣味的敌人,能够点此查阅;

(1)、测试项目筹备

  如果咱们通过 creat-react-app 创立我的项目会间接内置 @testing-library/react,能够开箱即用,然而这里咱们通过vite 形式创立的 react 我的项目,vite 构建的我的项目,默认是没有单测的,而后一步步欠缺 test 构建,这样做的益处呢就是咱们本人相熟配置构建流程,脱离 cli 脚手架工具,自在搭配;

  • 1、应用 vite 创立一个空白我的项目pnpm create vite react-test-example -- --template react-ts
  • 2、装置 react 单测相干依赖pnpm add @testing-library/react @testing-library/jest-dom jest -D
  • 3、pnpm jest --init生成 jest 配置文件

  上面咱们就对于配置我的项目做个阐明

  • 第一:咱们先设置匹配那些文件作为 test 文件

    testMatch: ['<rootDir>/src/**/__tests__/**/*.{spec,test}.{js,jsx,ts,tsx}',
      '<rootDir>/src/**/*.{spec,test}.{js,jsx,ts,tsx}',
      '<rootDir>/__test__/**/*.{spec,test}.{js,jsx,ts,tsx}',
    ],
  • 第二步:配置我的项目单测文件类型配置,留神这个配置内容是从左到右执行去查看匹配的,所以如果是 ts 主导的我的项目,咱们就将 ts 类型文件放在最后面;

    moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx']
  • 第三步:配置文件文件、门路解析方法,执行这个步骤之前,咱们须要对于文件解析工具进行装置,具体如下:

    • 1、装置 pnpm add identity-obj-proxy -D 解决 css 文件
    • 2、对于 jest 单测文件,因为 jest 是运行在 v8 引擎中,也就是会以 nodejs 环境中来去执行,所以对于文件都要本义操作,惯例有两种形式,第一种 ts tsx 形式写的单测,咱们能够选中用 ts-jest 形式疾速解决,第二种形式便是通过 babel 这种形式配置(繁琐一点),当然说道这儿了,咱们得提一嘴明天我这里找到的另一种形式,那就是基于 swc 的计划,这套计划劣势(我在理论我的项目亲测)就是执行 jest 单测文件效率会快过下面两种,速度快的不是一星半点,所以我举荐的用 swc 这套形式;
    • 3、基于第二步,咱们装置 swc 单测相干工具内容pnpm add @swc/core @swc/jest -D
    moduleNameMapper: {'^.+\\.module\\.(css|sass|scss|less)$': 'identity-obj-proxy',
      '\\.svg$': 'identity-obj-proxy',
      // webpack  or  vite 等编译工具中波及到的别名辨认
    },
    transform: {'^.+\\.(js|jsx|ts|tsx)$': ["@swc/jest"],
    },
    transformIgnorePatterns: ['[/\\\\]node_modules/(?!(antd)/)[/\\\\].+\\.(js|jsx|ts|tsx)$',
    ],
  • 第四步:以上步骤针对于一般测试文件,如果咱们须要对组件相干测试,咱们就须要配置testEnvironment,当初咱们我的项目上应用最新版本的 jest 后(jest 28 之后的版本),提醒装置的是jest-environment-jsdom,咱们装置后,依照上面配置;

    testEnvironment: 'jsdom',
  • 第五步:下面步骤咱们实现根本版本的 jest 配置,具体对于 coverage 等等这些配置能够查看官网,还有 setupFiles 相干配置依据具体应用状况减少,后续咱们应用 @testing-library/react 进行,组件测试都须要依赖 @testing-library/js-dom 所以咱们就间接设置setupFilesAfterEnv,将每个单测都须要的公共内容对立增加,具体如下:

    // ./jest/setupJestDom.ts
    import '@testing-library/jest-dom'
    
    // 调整 jest.config.js, 减少以下内容
     setupFilesAfterEnv: ['<rootDir>/jest/setupJestDom.ts'],
  • 第六步:每次执行结束后,不主动清理单测缓存,这样执行效率会快

    setupFiles: ['@testing-library/react/dont-cleanup-after-each'],

(2)、@testing-library/react 的根本用法

  下面咱们做了 jest 我的项目的配置,基本上能够满足咱们写 jest 单测了,上面咱们就用应用 @testing-library/react 形式做一下单元测试的写法,这里我先将@testing-library/reactapi 文档地址放在这儿,不便参考应用;
  首先咱们对于惯例组件测试写法,具体如下:

import React from 'react'

const HelloWorld: React.FC = () => {return <div>hello world</div>}

export default HelloWorld
单元测试写法
import React from 'react'
import {render, screen} from '@testing-library/react'
import HelloWorld from '../src/component/HelloWorld'

describe('HelloWorld Component', () => {it('render', () => {render(<HelloWorld></HelloWorld>)
    // 组件渲染后果打印进去,不便咱们去对照
    screen.debug()
    expect(screen.getByText('hello world')).toBeInTheDocument()})
})

咱们这里总结一下根本用法:

  • render:渲染 react 组件
  • screen:testing-library/react 提供的全局 dom 对象,咱们能够通过 screen 去查 dom 构造
  • 查找元素:findBy...、getBy...、queryBy

    • 对于 getBy... 与 queryBy... 两个用法相似,都是去查找页面内容,返回的是 fiberNode;
    • 对于 findBy... 返回的是一个 promise,如果页面初始状态没有的元素构造,最终会渲染进去的构造,能够通过这种形式来解决,例如咱们异步申请数据,渲染页面构造,咱们就能够通过 findBy 办法实现,如下所示:
    import React from 'react'
    import {render, screen} from '@testing-library/react'
    import HelloWorld from '../src/component/HelloWorld'
    
    describe('HelloWorld Component', () => {it('render', async () => {render(<HelloWorld></HelloWorld>)
      // 是在写单测不分明渲染进去的是啥,能够进行 debug
      screen.debug()
      expect(await screen.findByText('hello world')).toBeInTheDocument()})
    })
  • 针对 jest-dom 扩大的匹配器(下面用到的toBeInTheDocument()),还记得咱们通过 setupFiles 插入进去的工具库@testing-library/jest-dom,外面提供了一系列匹配器,不便咱们去做 test,倡议去看官网例子,没必要死记硬背,理论工作要用了就查阅文档;
  • fireEvent,进行事件模仿单元测试,具体用法如下:

    import React, {useState} from 'react'
    
    interface HelloWorldProps {onClick: () => void
    }
    
    const HelloWorld: React.FC<HelloWorldProps> = ({onClick}) => {
    return <div>
      <div>hello world</div>
      <button onClick={onClick}> 减少 </button>
    </div>
    }
    
    export default HelloWorld

      单测文件写法如下:

    import React from 'react'
    import {render, screen, fireEvent} from '@testing-library/react'
    import HelloWorld from '../src/component/HelloWorld'
    
    describe('HelloWorld Component', () => {it('render', async () => {const onClick = jest.fn()
      render(<HelloWorld onClick={onClick}></HelloWorld>)
      // 是在写单测不分明渲染进去的是啥,能够进行 debug
      screen.debug()
      expect(await screen.findByText('hello world')).toBeInTheDocument()
      // 模仿事件
      fireEvent.click(screen.getByText(/ 减少 /i))
      expect(onClick).toHaveBeenCalledTimes(1)
    })
    })

    (3)、@testing-library/react-hooks 对于 hooks 单元测试方法

      针对于 hooks 的单元测试,咱们能够装置 @testing-library/react-hooks 工具进行 hooks 单测,具体装置如下:

  • 首先,咱们须要装置pnpm add @testing-library/react-hooks -D
  • 其次,咱们须要留神 @testing-library/react-hooks 不与 react 版本捆绑在一起,所以如果咱们须要装置react-test-renderer 或者 react-dom 两个其中一个,二者都有,会默认以 react-test-renderer 为第一优先级;

上面对于 hooks 单测如下:

import {useCallback, useState} from "react"


function useCounter() {const [count, setCount] = useState(0)

  const increment = useCallback(() => setCount((x) => x + 1), [])

  return {count, increment}
}

export default useCounter
import {renderHook, act} from '@testing-library/react-hooks'
import useCounter from '../src/useCounter'

test('Counter', () => {const { result} = renderHook(() => useCounter())

  act(() => {result.current.increment()
  })

  expect(result.current.count).toBe(1)
})

  单元测试内容分很多,我这里次要就是我的项目构建,应用 testing-library 进行单测用法简短阐明,喜爱的敌人点赞评论珍藏三连一下,谢谢您们的反对~ 比心!!

正文完
 0