为什么要用AI写单测

这个问题分两点来说,第一是为什么要写单测,第二是为什么要用AI。

先来说为什么写单测,这很简单,咱们项目或许说咱们前端团队有公共模块,包含有组件类型、工具函数类型、hooks类型等,咱们最大也是重点的项目,使用的技能栈是 React,因而这儿说的 hooks 是指 react hooks,随着前端队伍壮大,开端考虑用开源的思路来维护这些代码,那么单测便是正规化的其间很重要一环。

至于第二点,主要是考虑提效,所以做一次测验,项目里有祖传的 Jest 装备,可是具体需求什么依靠,需求依据所写的单测是什么类型,以及其时技能栈是什么版别,这就有必定建立的学习成本,因而,本次设定为从0到1建立 Jest 环境到跑通 AI 所写的用例。

使用的IDE

Cursor,版别0.2.5:

GPT 帮我搭建 Jest 到写用例(单元测试主题)

AI模型:

不是GPT-4

GPT 帮我搭建 Jest 到写用例(单元测试主题)

想要一直使用中文对话,能够这样装备:

GPT 帮我搭建 Jest 到写用例(单元测试主题)

点右上角的图标,翻开辅佐侧栏,点 MORE,然后告诉他,一直使用中文回答,这个装备现在只能有一条。

比如

Github仓库地址:

github.com/bdlite/hook…

用来做比如的分支:

preview/previous

感兴趣的话能够一边 clone 下来,用 Cursor 翻开文件夹,然后一边跟着操作。

开端

仓库都有什么

GPT 帮我搭建 Jest 到写用例(单元测试主题)
  • 有从咱们实际项目里剥离出的工程类装备文件,例如 .babelIrc、.gitignore、jest.config.js,装备项也只留取需求的
  • package.json 是使用 npm init 初始化的,生成进程略,触及到要添加的包后文也会有提及
  • src 目录便是放源码了,es 目录是编译为 esModules 的制品途径,发布到 npm 用的是这个目录,因而单测也引证的这个目录
  • coverage 目录是 jest 自动生成的报告结果
  • __tests__ 目录是空的

看下祖传的jest.config.js

全选整段文件内容,会出现两个选项(这儿的 Cursor 界面还有点小小的 bug),一个是 Edit,一个是 Chat,不同的是,Edit 能够直接帮你生成新代码或许改代码,Chat 是基于这段代码你能够问些问题,但不在编辑框内生成代码。

GPT 帮我搭建 Jest 到写用例(单元测试主题)

我这儿想让它直接帮我生成注释,便于辅佐剖析一下这个装备有哪些不妥(懒得看官方文档的这儿集合

GPT 帮我搭建 Jest 到写用例(单元测试主题)
GPT 帮我搭建 Jest 到写用例(单元测试主题)

生成的是英文,先 Reject,看来辅佐侧栏里边装备的在代码编辑框里并不共用,从头调整 Prompt 输入:

GPT 帮我搭建 Jest 到写用例(单元测试主题)

这一次 Accept:

GPT 帮我搭建 Jest 到写用例(单元测试主题)

这么读起来,尽管是祖传的装备,似乎看不出什么毛病,当然为了制造比如,其实是有所调整的,至少项目里的途径配的没问题,因而这儿的装备也是模拟了一下,途径也没问题,基于此,咱们开端让Cursor写用例,然后跑起来看看。

看下源码

GPT 帮我搭建 Jest 到写用例(单元测试主题)

为了确保环境建立及后续发布流程比较靠谱,咱们先 check 一下哪些是 dependencies,哪些是 devDependencies 和 peerDependencies:

  • ‘react’ 显然不能跟着打包,放 peer
  • ‘query-string’ 这种库仍是要谨慎点,放 depend

去 package.json 确认一下是否放对了

GPT 帮我搭建 Jest 到写用例(单元测试主题)

这儿有个问题,没有指定 react ,因而我让“助理”帮我加一下:

GPT 帮我搭建 Jest 到写用例(单元测试主题)
GPT 帮我搭建 Jest 到写用例(单元测试主题)

accept 之后多了个花括号,手动删吧,谁让它仍是个孩子啊。

好戏开场

GPT 帮我搭建 Jest 到写用例(单元测试主题)

我这是其时翻开 package.json 的状况下在侧边栏问的,再试试翻开 useSearch.js 的状况下问问:

GPT 帮我搭建 Jest 到写用例(单元测试主题)

公然其时翻开的文件便是提问的上文,能够见到上一个其实并不是我源码完成的内容,我估计是从其他地方找来的答案,公然是一本正经也能胡说八道呀

行,这儿的计划给得仍是蛮全面的,比方说教你加哪些依靠,手把手教你创建文件,可惜的是,它其实并不能读取整个工程,跨文件去理解上下文,因而它不知道的是,我配了 jest 去读 __tests__ 下的文件

review 下用例

依上文,用例只有三个,只看代码不履行的话,似乎做到了最小的功能检验

再换个思路试试

GPT 帮我搭建 Jest 到写用例(单元测试主题)

从以上两个提问的答案来看,看懂代码是没问题的,也能指出里边有问题的点,表现不错

GPT 帮我搭建 Jest 到写用例(单元测试主题)

GPT 帮我搭建 Jest 到写用例(单元测试主题)

基本上符合源码触及的几个场景,不过,依据我的判别,似乎还有点问题:

  • 没有开场处的验证 hooks 返回类型的用例

    GPT 帮我搭建 Jest 到写用例(单元测试主题)

  • 此处的第二个用例:假如key不是字符串或许value是null,那么函数不会进行任何操作

    • 看到这个才发现,源码里存在着 bug,为什么在问它有没有 bug 的时分没反应过来,因为其时还没做比如的时分问过,回答是没什么问题,看来这孩子也是变聪明了,也可能是其时的上下文有差异,导致孩子只管夸,没理性思考,是的,我会去问写得好不好,哈哈
    • bug 便是,其实咱们是希望 value是null 或许 undefined,那么会清掉 search 中对应的 key

其他问题不大,最多想起来什么场景补充一下就好

run 一下看

按上文说到的,在 __tests__ 目录下创建 useSearch.test.js 文件,然后把方才的代码仿制进去,可是引证 useSearch 函数的途径略微改一下:

import { useSearch } from 'es/useSearch';

装置 jest 各种依靠

GPT 帮我搭建 Jest 到写用例(单元测试主题)

依据提示,最省事儿的办法,从头装置,并在指令后加上 –legacy-peer-deps

npm install --save-dev jest @babel/core @babel/preset-env @babel/preset-react babel-jest identity-obj-proxy react-test-renderer --legacy-peer-deps

履行 test 指令

该指令的装备同样是祖传的

GPT 帮我搭建 Jest 到写用例(单元测试主题)

在终端里履行:

npm run test

还得装依靠

GPT 帮我搭建 Jest 到写用例(单元测试主题)

OK~装它!

GPT 帮我搭建 Jest 到写用例(单元测试主题)

一步一足迹啊,持续装它!

再履行一次,这次是 Module ts-jest in the transform option was not found.

ts-jest 装完了,然后再 run test

GPT 帮我搭建 Jest 到写用例(单元测试主题)

做个比如不容易,那就持续装!

可是这儿我会都装到 devDependencies,再 run

GPT 帮我搭建 Jest 到写用例(单元测试主题)

翻开引荐的链接

GPT 帮我搭建 Jest 到写用例(单元测试主题)

OK,试一下 use react-test-renderer

GPT 帮我搭建 Jest 到写用例(单元测试主题)

装 react,装到 devDependencies,再 run

GPT 帮我搭建 Jest 到写用例(单元测试主题)

履行成功,祖传的指令写得倒没啥问题,上“链接”:

npm install --save-dev cross-env jest-environment-jsdom ts-jest react-dom react-test-renderer react

剖析用例没经过的原因

GPT 帮我搭建 Jest 到写用例(单元测试主题)

选中这个用例,问下“助理”

GPT 帮我搭建 Jest 到写用例(单元测试主题)

点 Edit

GPT 帮我搭建 Jest 到写用例(单元测试主题)

GPT 帮我搭建 Jest 到写用例(单元测试主题)

好吧,怪我给的自由太过火,从头调整下

GPT 帮我搭建 Jest 到写用例(单元测试主题)

GPT 帮我搭建 Jest 到写用例(单元测试主题)

accept 然后跑看看,经过了,不截图了,看下一个

GPT 帮我搭建 Jest 到写用例(单元测试主题)

这个问题原因一致,但其实,这个不符合咱们对这个 hooks 的期待,用过错的源码逻辑来生成过错的用例了属于是,直接改

GPT 帮我搭建 Jest 到写用例(单元测试主题)

GPT 帮我搭建 Jest 到写用例(单元测试主题)

GPT 帮我搭建 Jest 到写用例(单元测试主题)

why?

看下提示中的 Received 就知道了

  • 第三个用例因为源码确实存在这个 bug,这现在来说是按照“预期” failed了
  • 第四个为什么就不对了,第一次能跑出结果的时分不是经过了么,其实跟第二个用例的问题一样,不谨慎导致的,这儿面每一个用例中的 window 并不处于块级效果域,像第二个一样改过来就好了

让它改第四个

GPT 帮我搭建 Jest 到写用例(单元测试主题)

GPT 帮我搭建 Jest 到写用例(单元测试主题)

就剩下第三个用例没跑通了

改源码中的 bug

改源码,选中源码,然后 Edit

GPT 帮我搭建 Jest 到写用例(单元测试主题)

GPT 帮我搭建 Jest 到写用例(单元测试主题)

我哭死,感觉它不会写代码,又或许是我的锅?

算了算了,先手动改改

import { useCallback } from 'react'
import queryString from 'query-string'
export function useSearch() {
  const searchList = [] // 同一组件接连调用的缓冲区
  const getSearch = useCallback(() => queryString.parse(window.location.search), [ window.location.search ])
  const setSearch = useCallback((key, value = null) => {
    const search = getSearch()
    if (search[key] === `${value}` || typeof key !=='string') return
    searchList.push({ [key]: value })
    const nextSearchData = { ...search, ...searchList.reduce((before, current) => ({ ...before, ...current }), {}) }
    const nextSearch = queryString.stringify(nextSearchData, { skipNull: true })
    window.history.replaceState(queryString.parse(nextSearch), '', `?${nextSearch}`)
  }, [ getSearch, window.history ])
  return { getSearch, setSearch }
}

这儿改的是 src 目录下的文件,咱们测的时分引证的是 es 的文件,因而在 package.json 的 script 里改下

GPT 帮我搭建 Jest 到写用例(单元测试主题)

从头履行

GPT 帮我搭建 Jest 到写用例(单元测试主题)

4个用例终于跑通了,yes!

使用 Prompt 供给上下文修复报错

再把之前说到的类型验证加上

  it('should return an object with getSearch and setSearch functions', () => {
    const { getSearch, setSearch } = useSearch();
    expect(typeof getSearch).toBe('function');
    expect(typeof setSearch).toBe('function');
  });

run 后报错:

GPT 帮我搭建 Jest 到写用例(单元测试主题)

用侧边栏的 Chat 求救一下

GPT 帮我搭建 Jest 到写用例(单元测试主题)

选顶用例,Edit

GPT 帮我搭建 Jest 到写用例(单元测试主题)

GPT 帮我搭建 Jest 到写用例(单元测试主题)

GPT 帮我搭建 Jest 到写用例(单元测试主题)

喜提大结局,撒花~

总结

本次实验操作途径

  1. 喂源码
  2. 生成用例
  3. 依据提示搭环境
  4. review 用例和源码
  5. 找出问题并修复
  6. 丰富用例
  7. 遇到报错
  8. 喂过错信息
  9. 依据信息修复
  10. 跑通

假如没有喂给比较合适的上下文,可能会得不到精确的答案。

假如给的描绘不行精准,例如我让它修复源码的 bug 就不尽如人意,信任给出足够多,足够精准的信息,应该仍是能够的,或许你代码的结构上原本就有点问题,AI 不见得能够懂你希望连结构上的问题一同都能优化的心思,限于本文不是生成代码,而是用例,这一块没有展开来做测验。

工程领域的希望

这个比如建立 Jest 的进程仍是比较顺利的,我在咱们的业务项目里建立,过错信息很难解,比如中的步骤其实是带有一点天主视角的,包含里边其完成已自带了装备文件。

现在发现 AI 并不能阅读整个工程的装备、某个指定目录下的文件,据我了解,必须把整个工程丢给某个 AI 的程序,才能完成一些特定的任务,这对于追求轻量 IDE 的咱们来讲,还远远不行,因而,我仍是对于这一点抱有很高的期待,这对再次下降前端门槛将是一个很大的奉献。

描绘问题的能力

这尽管不是本文想要提及的主题,大家能够经过比如自己去感受一下。


谢谢你读到了这儿~