1. 项目概述与核心价值如果你和我一样长期在前端测试的泥潭里摸爬滚打那你一定对下面这个场景深恶痛绝你写了一个针对复杂交互组件的Jest测试render出来的HTML结构像天书一样嵌套了十几层div中间还夹杂着各种动态生成的className。你瞪大眼睛试图在脑海中将这一串字符串还原成可视化的UI判断那个按钮到底有没有被正确禁用那个错误提示的样式是否正常。这个过程不仅低效而且极易出错尤其是当样式CSS、CSS-in-JS没有正确加载时你看到的DOM树和用户实际看到的界面可能完全是两回事。这就是jest-preview诞生的背景也是它最核心的价值所在。它不是一个全新的测试框架而是一个调试增强工具。简单来说它在你运行Jest测试时偷偷开了一个“后门”让你能在真实的浏览器环境中实时预览被测试组件渲染出的完整、带样式的UI。你可以把它想象成给Jest测试装了一个“可视化调试器”。它的工作原理并不复杂但设计得很巧妙。当你调用preview.debug()时jest-preview会做几件事捕获快照拦截当前测试用例中render或类似方法生成的DOM。收集资源通过配置好的Jest转换器transformer收集组件所依赖的CSS、CSS Modules、Sass甚至是CSS-in-JS如styled-components, Emotion运行时生成的样式。服务推送将这些HTML和CSS资源通过一个独立的预览服务器jest-previewCLI启动推送到一个本地网页上。实时预览你的默认浏览器会自动打开或刷新一个页面展示出与测试环境中几乎一模一样的UI。整个过程是毫秒级的你几乎感觉不到延迟。这对于调试那些高度依赖视觉反馈的测试——比如布局、样式、动态类名、条件渲染——简直是降维打击。它适合所有使用Jest进行前端单元测试或集成测试的开发者无论你是React、Vue、Svelte还是Angular的拥趸。如果你厌倦了“脑补”HTML那么jest-preview就是你工具箱里不可或缺的新利器。2. 核心设计思路与架构解析jest-preview的设计目标非常明确无侵入、轻量级、即时反馈。为了实现这个目标它的架构围绕几个关键点展开理解了这些你就能明白它为何如此工作以及如何更好地驾驭它。2.1 无侵入式集成这是jest-preview最聪明的地方。它不需要你改变现有的测试编写习惯。你不需要用特殊的render方法也不需要把组件包裹在某个Provider里。你只需要在现有的测试文件中在render语句之后简单地加一行preview.debug()即可。原有的测试断言expect完全不受影响可以照常运行。这意味着你可以渐进式地采用它只在需要可视化调试的测试用例中使用而不会污染其他测试。这种无侵入性得益于其“观察者”模式的设计。jest-preview的客户端库你import的那个更像是一个触发器和一个通信桥梁。它监听测试执行流在debug()被调用时收集当前测试环境的“状态”主要是DOM然后通过HTTP发送给预览服务器。它不参与也不干扰Jest本身的测试运行逻辑。2.2 双进程模型测试运行器与预览服务器jest-preview采用了一个经典的双进程模型这也是它能实现实时刷新的关键进程AJest测试进程。这是你的主战场npm test或jest命令启动的就是它。在这里你的测试代码执行jest-preview客户端库被调用。进程B预览服务器进程。通过jest-preview命令在另一个终端启动或者通过jest-preview serve在后台运行。它启动了一个小型的HTTP服务器通常运行在某个端口如3336。这两个进程通过HTTP API进行通信。当测试进程中的debug()被触发它会向服务器进程的特定端点发送一个POST请求携带最新的HTML和CSS数据。服务器进程接收到数据后会更新其内部状态并通过WebSocket或服务器端事件SSE通知前端页面刷新。这种分离确保了预览功能的稳定性即使预览服务器卡住或前端页面崩溃也不会影响你的测试进程继续执行。2.3 样式处理的核心Jest转换器Transformer要让浏览器中预览的UI带样式最大的挑战在于Jest环境本身。Jest运行在Node.js中没有真实的DOM和CSSOM。像import ./Button.module.css这样的语句在Jest中默认会被忽略或转换成空对象。jest-preview的解决方案是提供并推荐你使用它预设的Jest转换器。你需要在jest.config.js中配置transform字段。这个转换器的作用是当Jest遇到.css,.scss,.sass,.less等样式文件时不再简单地返回{}而是将这些文件的内容字符串形式收集起来并关联到当前运行的测试用例上。对于CSS-in-JS库如styled-components转换器会确保其运行时生成的样式标签style内容也能被正确捕获。这样当调用debug()时jest-preview就能拿到一份完整的样式列表并将它们注入到预览页面的head中。这就是为什么它支持多种样式方案的原因本质上是劫持了Jest的文件处理流程。2.4 框架无关性的实现虽然jest-preview起源于React生态与react-testing-library完美搭配但它的设计是框架无关的。它并不关心你是用ReactDOM.render、vue-test-utils还是svelte-testing-library来渲染组件。它的核心输入是HTML字符串和CSS字符串。只要你的测试框架能提供一个方法让你获取到渲染后的容器元素的innerHTML你就能将其传递给jest-preview。官方文档为不同框架提供了示例但其适配层通常很薄核心逻辑是一致的。这使得它成为一个通用的前端测试可视化工具。3. 从零开始的完整安装与配置指南纸上得来终觉浅绝知此事要躬行。让我们抛开文档从一个全新的React TypeScript项目使用Vite构建开始一步步配置jest-preview并解释每一个步骤背后的原因。我假设你已经有一个基本的Vite React项目并且已经配置了Jest和React Testing Library。如果没有你可以先通过npm create vitelatest my-app -- --template react-ts创建项目然后安装Jest相关依赖。3.1 安装核心依赖首先安装jest-preview及其预览服务器所需的CLI工具。npm install --save-dev jest-preview注意这里我们只安装了主包。jest-preview将预览服务器命令行工具捆绑在了主包中。在旧版本或某些文档中你可能会看到需要单独安装jest-preview-server但在最新版本中这已经不再是必须的。你可以通过npx jest-preview或npx jest-preview serve来启动服务器。3.2 配置Jest转换器最关键的一步这是整个配置的核心决定了样式能否被正确预览。我们需要修改jest.config.js或jest.config.ts。为什么必须配置转换器默认情况下Jest不知道如何处理非JavaScript文件。对于CSS文件它通常会使用一个返回空对象的模拟mock文件。这会导致jest-preview捕获不到任何样式信息。我们需要告诉Jest“当遇到这些样式或静态资源文件时不要简单地模拟它们请用jest-preview提供的处理器来转换它们以便我能收集到文件内容。”打开你的jest.config.js进行如下配置// jest.config.js const config { // ... 你的其他Jest配置 testEnvironment: jsdom, // 必须使用jsdom环境来模拟浏览器DOM transform: { // 使用你已有的转换器处理JS/TS/JSX/TSX文件例如babel-jest ^.\\.(t|j)sx?$: [babel-jest, { presets: [babel/preset-env, babel/preset-react, babel/preset-typescript] }], // 使用 jest-preview 的转换器处理样式和文件 ^.\\.(css|scss|sass|less)$: jest-preview/transforms/css, ^(?!.*\\.(js|jsx|mjs|cjs|ts|tsx|css|scss|sass|less|json)$): jest-preview/transforms/file, }, }; export default config;配置详解testEnvironment: jsdom这是必须的。jest-preview需要在一个模拟的DOM环境中运行才能获取到组件渲染后的HTML元素。node环境不行。transform字段第一行针对你的源代码.js,.jsx,.ts,.tsx使用你项目中已有的转换器如babel-jest。这保证了你的组件语法能被正确解析。第二行 (^.\\.(css|scss|sass|less)$)这是一个正则表达式匹配所有CSS及其预处理器文件。当Jest遇到这些文件时会调用jest-preview/transforms/css这个转换器。这个转换器不会对文件内容做实质性的语法转换因为Node.js不需要执行CSS但它会做一件关键的事将文件的原始内容作为一个字符串模块导出并通知jest-preview的运行时记录下这个文件及其内容。这样在debug()时这些CSS字符串就能被提取并注入到预览页面。第三行 (^(?!.*\\.(js|jsx|mjs|cjs|ts|tsx|css|scss|sass|less|json)$))这是一个负向零宽断言匹配除了前面列出的JS、TS、样式、JSON之外的所有其他文件如图片.png,.jpg,.svg字体文件等。它使用jest-preview/transforms/file转换器。这个转换器的作用是将文件路径转换成一个特殊的URL字符串以便在预览服务器中能够正确引用这些静态资源。3.3 配置全局CSS可选但重要如果你的项目通过index.js或main.jsx导入了一个全局CSS文件例如import ./index.css这个文件在测试中可能不会被某个具体的测试用例import。因此上面配置的转换器可能抓不到它。为了解决这个问题jest-preview允许你显式地声明这些全局CSS文件。创建一个名为jest.preview.config.js的文件与jest.config.js同级// jest.preview.config.js module.exports { // 将你的全局CSS文件路径放在这里 publicFolder: public, // 静态资源目录通常是 public globalCSS: [ ./src/index.css, // 你的全局样式文件路径 // 可以添加多个 // ./src/another-global.css, ], };这样当你启动预览服务器时它会自动将这些CSS文件注入到每一个预览页面中。3.4 启动预览服务器配置完成后你需要启动预览服务器进程。打开一个新的终端窗口在你的项目根目录下运行npx jest-preview或者明确指定服务命令npx jest-preview serve你会看到类似下面的输出说明服务器已经启动并在http://localhost:3336上监听。✔ Server started at http://localhost:3336保持这个终端窗口打开让服务器在后台运行。现在你的预览“画布”已经准备好了。3.5 在测试中调用预览最后让我们修改一个测试文件来使用它。假设你有一个Button.test.tsx文件。// Button.test.tsx import React from react; import { render, screen } from testing-library/react; import userEvent from testing-library/user-event; import preview from jest-preview; // 1. 导入 preview import Button from ./Button; describe(Button, () { it(should render correctly and apply styles, () { render(Button variantprimaryClick Me/Button); // 2. 在你想预览的时候调用 debug() preview.debug(); // 你的原有断言保持不变 const button screen.getByRole(button, { name: /click me/i }); expect(button).toBeInTheDocument(); expect(button).toHaveClass(btn-primary); }); it(should handle click event, async () { const handleClick jest.fn(); const user userEvent.setup(); render(Button onClick{handleClick}Clickable/Button); // 你可以在交互后再次调用 debug()查看状态变化后的UI // preview.debug(); const button screen.getByRole(button, { name: /clickable/i }); await user.click(button); expect(handleClick).toHaveBeenCalledTimes(1); // 例如点击后按钮可能被禁用此时再预览 // preview.debug(); }); });现在运行你的测试命令例如npm test或jest。当测试执行到preview.debug()这一行时你的默认浏览器会自动弹出一个标签页或刷新已打开的标签页展示出Button组件在那一刻被渲染出的、带样式的真实模样。4. 深度使用技巧与实战场景基础配置只是开始jest-preview的真正威力在于应对复杂的调试场景。下面分享一些我在实际项目中总结出的高阶用法和心得。4.1 精准控制预览时机你不需要在每个测试用例中都调用debug()。通常我只在以下几种情况下使用样式调试当测试涉及条件类名、动态样式、CSS-in-JS的props注入时这是最直观的验证方式。复杂DOM结构验证当组件的HTML输出非常复杂通过screen.debug()打印的文本难以阅读时。交互后状态验证在模拟用户点击、输入等操作后调用debug()查看UI状态是否按预期更新如模态框打开、列表项被选中、按钮禁用。定位测试失败原因当一个测试莫名其妙失败时在断言前插入debug()看看UI到底长啥样往往能快速定位是渲染问题还是断言逻辑问题。你可以通过条件判断来灵活控制it(should show error style on invalid input, () { render(Form field{invalidValue} /); if (process.env.DEBUG_TEST) { // 设置一个环境变量来控制 preview.debug(); } // ... 断言 });4.2 处理CSS-in-JSStyled-components, Emotion这是jest-preview的一大亮点。对于Styled-components或Emotion这类运行时生成样式的库关键在于确保Jest的测试环境能正确捕获到它们插入到文档中的style标签。实操要点确保有DOM环境testEnvironment必须设为jsdom或jest-environment-jsdom。检查Babel配置如果你在使用Styled-components并且有babel-plugin-styled-components进行服务端渲染SSR优化或类名美化请确保它在测试环境中也被启用。有时这可能会影响样式的捕获。一个简单的测试方法是在调用debug()后查看浏览器预览页面的HTML源码搜索styled-components相关的类名或style标签是否存在。Emotion的注意事项Emotion有两种模式emotion/css类似CSS-in-JS对象和emotion/reactcss prop。jest-preview对后者支持良好。如果你遇到样式丢失检查是否使用了Emotion的CacheProvider并确保它在测试的渲染树中。根据我的经验jest-preview官方提供的转换器对这两个库的主流用法支持已经相当完善开箱即用成功率很高。4.3 预览服务器的高级管理自定义端口如果默认的3336端口被占用你可以在启动时指定npx jest-preview serve --port 3006或者在jest.preview.config.js中配置module.exports { server: { port: 3006, }, // ... 其他配置 };手动打开浏览器有时你可能不希望自动打开浏览器。可以使用--no-open标志npx jest-preview serve --no-open然后手动访问http://localhost:3336。与CI/CD集成在持续集成环境中通常不需要也不应该启动交互式的预览服务器。你可以通过环境变量来禁用debug()调用或者确保预览服务器命令不会在CI中执行。一个常见的模式是// 在你的测试setup文件或条件判断中 if (process.env.CI ! true) { preview.debug(); }4.4 调试“不可见”的状态有些UI状态可能一闪而过或者依赖于复杂的用户交互链。你可以利用jest-preview进行“分步快照”调试。例如测试一个多步骤表单it(completes multi-step form, async () { render(MultiStepForm /); const user userEvent.setup(); // 步骤1预览初始状态 preview.debug(); // 快照1 await user.click(screen.getByText(Next)); // 步骤2预览第二步的UI preview.debug(); // 快照2 await user.type(screen.getByLabelText(Email), testexample.com); await user.click(screen.getByText(Submit)); // 步骤3预览提交后的状态如成功信息或加载状态 preview.debug(); // 快照3 });每次调用debug()预览页面都会更新。你可以通过浏览器的“后退”按钮如果服务器支持历史状态或观察URL的变化来回看不同步骤的UI。这比在控制台看一堆HTML字符串清晰多了。5. 常见问题排查与解决方案实录即使配置正确在实际使用中也可能遇到一些“坑”。下面是我和团队遇到过的一些典型问题及其解决方法。5.1 预览页面空白或没有样式这是最常见的问题根本原因通常是样式没有被正确捕获和注入。排查步骤检查转换器配置首先确认jest.config.js中的transform配置是否正确指向了jest-preview/transforms/css和jest-preview/transforms/file。一个常见的错误是配置了其他CSS转换器如jest-css-modules-transform与之冲突。检查控制台错误打开浏览器的开发者工具F12查看Console和Network标签页。如果有404错误可能是静态资源如图片、字体路径不对。检查jest.preview.config.js中的publicFolder配置是否正确指向了你的静态资源目录通常是public。检查全局CSS如果你的样式依赖于全局CSS确保已在jest.preview.config.js的globalCSS数组中正确声明。检查CSS-in-JS对于Styled-components/Emotion在预览页面右键“查看页面源代码”搜索style或>问题现象可能原因解决方案页面完全空白无HTMLpreview.debug()未被调用或调用时机不对如在render之前确保debug()在render之后且测试用例确实执行到了这一行。有HTML但无任何样式1. Jest转换器未配置或配置错误。2. 样式文件未被测试文件直接或间接导入。1. 复查jest.config.js的transform配置。2. 确保组件导入了样式或将样式添加到globalCSS。部分组件样式丢失但基础样式存在CSS-in-JS库的样式未被捕获。确认testEnvironment是jsdom。检查CSS-in-JS库的版本兼容性。尝试官方示例看是否工作。图片不显示文件转换器未配置或publicFolder路径错误。1. 确认transform中包含jest-preview/transforms/file。2. 检查jest.preview.config.js中的publicFolder是否指向正确的目录。5.2 预览服务器无法启动或端口冲突错误Address already in use端口3336被其他程序占用。解决使用--port参数指定另一个端口如npx jest-preview serve --port 3006。记得在访问时也使用新端口。错误命令未找到或执行失败解决确保jest-preview已正确安装在项目本地node_modules中或全局。尝试使用npx前缀。检查package.json中是否有其他脚本冲突。5.3 与测试库的细微冲突在某些极其罕见的情况下jest-preview的DOM操作可能会与测试库如Testing Library的cleanup流程产生干扰导致测试状态污染。如果你发现一个测试用例的预览影响了另一个可以尝试在每个测试用例中确保debug()调用在断言之后或者确保测试环境在用例间被正确清理。检查是否在测试设置文件如setupTests.js中正确配置了afterEach(cleanup)如果使用React Testing Library的旧版本。5.4 性能考量频繁调用debug()会向预览服务器发送网络请求理论上会轻微减慢测试速度。但在开发调试阶段这点开销相对于它带来的效率提升是微不足道的。对于成百上千的测试套件建议不要默认启用而是仅在你需要调试的特定测试或使用环境变量如DEBUG_TEST来控制。6. 横向对比与生态工具了解一个工具的边界才能更好地使用它。jest-preview并非万能它主要解决“测试运行时可视化”的问题。让我们把它和其他相关工具做个对比。工具核心用途与 jest-preview 的关系/对比JestJavaScript测试框架提供测试运行、断言、模拟等功能。jest-preview是建立在Jest之上的调试辅助工具它不替代Jest的任何功能而是增强其调试体验。React Testing Library / Vue Test Utils 等用于在测试中渲染组件、查询DOM节点、模拟用户交互的库。jest-preview与它们协同工作。你使用这些库渲染组件然后用jest-preview可视化渲染结果。testing-library/jest-dom提供针对DOM元素的定制化Jest断言匹配器如.toBeVisible(),.toHaveStyle()。互补关系。jest-preview让你看到样式和UIjest-dom让你能用代码断言样式和UI。两者结合调试和断言都更强大。Storybook组件开发、文档化和可视化测试的独立环境。定位不同。Storybook用于开发阶段的组件隔离和展示而jest-preview用于测试执行阶段的即时调试。Storybook的测试插件如storybook/testing-library可以结合两者。Cypress / Playwright端到端E2E测试框架在真实浏览器中运行整个应用。层级不同。E2E测试关注用户完整工作流和跨页面交互运行较慢。jest-preview聚焦于单元/集成测试的单个组件状态可视化速度极快。两者可分别用于不同粒度的测试阶段。Vitest Previewjest-preview的姊妹项目为Vitest测试框架提供相同的可视化调试功能。同一理念不同运行时。如果你的项目使用Vite Vitest那么应该选择vitest-preview。两者API和体验几乎一致。个人心得不要试图用jest-preview替代Storybook或E2E测试。它的最佳定位是作为你编写Jest测试时的“快速眼动仪”帮你瞬间确认“我写的测试看到的UI到底对不对”。它极大地缩短了从“测试失败”到“理解为什么失败”的认知路径。7. 项目配置与调优实战让我们深入两个常见但稍复杂的场景看看如何配置jest-preview。7.1 在Next.js项目中集成Next.js项目有其特殊的文件结构和构建过程配置时需要额外注意。安装与基础配置与普通React项目相同安装jest-preview并配置jest.config.js中的transform。处理Next.js的特殊导入Next.js的Image组件、next/head等需要特殊处理。jest-preview的文件转换器 (transforms/file) 通常能处理图片路径。但对于Image组件在测试环境中它可能无法正常工作建议在测试中使用jest.mock来模拟它或者使用next/jest提供的转换器。// jest.config.js - 使用 next/jest 的配置示例 const nextJest require(next/jest); const createJestConfig nextJest({ dir: ./ }); const customJestConfig { testEnvironment: jsdom, setupFilesAfterEnv: [rootDir/jest.setup.js], transform: { // next/jest 已经处理了大部分转换我们需要在其基础上添加 jest-preview 的转换 // 注意这可能需要对转换器顺序进行仔细配置避免冲突 // 一个更安全的方式是在 next/jest 配置完成后再merge jest-preview的transform ^.\\.(css|scss|sass|less)$: jest-preview/transforms/css, ^(?!.*\\.(js|jsx|mjs|cjs|ts|tsx|css|scss|sass|less|json)$): jest-preview/transforms/file, }, // 告诉 next/jest 忽略对这些文件的转换由 jest-preview 处理 transformIgnorePatterns: [ node_modules/(?!(jest-preview)/), // 确保 jest-preview 的转换器不被忽略 ], }; module.exports createJestConfig(customJestConfig);注意Next.js Jest jest-preview 的配置可能因版本而异最可靠的方法是参考jest-preview官网的 Next.js示例 。全局样式Next.js的全局样式通常在pages/_app.js或app/globals.css中。确保将这些文件路径添加到jest.preview.config.js的globalCSS数组中。CSS ModulesNext.js默认支持CSS Modules。jest-preview的CSS转换器能正确处理.module.css文件将其转换后的类名映射关系注入预览所以你应该能看到正确的样式。7.2 在Monorepo项目中的使用如果你的项目是Monorepo结构如使用Turborepo、Nx、Lerna配置的关键在于路径解析。依赖安装在需要用到jest-preview的子包package中安装它或者在工作区根目录安装并确保Jest配置能解析到它。Jest配置每个子包可能有自己的jest.config.js。你需要在每个包的配置中都加上jest-preview的转换器。为了避免重复可以创建一个共享的Jest预设preset配置文件。路径别名Alias如果项目使用了路径别名如/*指向src/*需要确保Jest和jest-preview都能理解这些别名。Jest的moduleNameMapper需要正确配置而jest-preview的转换器会基于Jest解析后的真实路径工作所以通常不需要额外配置。预览服务器在Monorepo根目录或任何一个子包目录下运行npx jest-preview serve都可以。服务器会处理来自所有子包的测试请求。但要注意不同子包的publicFolder路径可能是相对的。你可以在每个子包的jest.preview.config.js中正确设置publicFolder路径例如../../public如果静态资源在根目录。一个Monorepo的配置片段示例根目录jest.config.base.js// 根目录 jest.config.base.js const path require(path); module.exports { testEnvironment: jsdom, transform: { ^.\\.(t|j)sx?$: [swc/jest], // 使用SWC等 ^.\\.(css|scss|sass|less)$: jest-preview/transforms/css, ^(?!.*\\.(js|jsx|mjs|cjs|ts|tsx|css|scss|sass|less|json)$): jest-preview/transforms/file, }, moduleNameMapper: { // 处理路径别名确保 jest-preview 能基于正确路径处理文件 ^/(.*)$: path.join(__dirname, packages/web/src/$1), }, };然后在子包的jest.config.js中扩展这个基础配置。8. 总结与最佳实践建议经过一段时间的深度使用jest-preview已经成了我前端测试工作流中不可或缺的一环。它把测试调试从“脑内编译”变成了“所见即所得”效率提升是实实在在的。最后分享几条我认为最重要的最佳实践按需启用非全量使用不要在所有测试用例中都加上preview.debug()。这会影响测试速度且大部分简单的逻辑测试并不需要可视化。只为那些涉及复杂UI、样式或交互状态的测试启用它。可以结合环境变量如VISUAL_DEBUG来控制。先写断言再可视化调试测试的核心仍然是自动化断言。jest-preview是调试工具不是断言工具。你应该先编写或修改测试断言当测试失败或你对输出不确定时再使用debug()来辅助理解问题所在。善用“快照”对比思维虽然jest-preview不生成传统的快照文件但它提供了视觉快照。在重构样式或组件结构时你可以先运行现有测试并用debug()确认UI无误然后进行修改再次运行测试并用debug()检查UI变化是否符合预期。这比对比一串HTML字符串直观得多。关注控制台警告预览页面打开时也留意一下浏览器控制台是否有JS错误或警告。有时这些警告能提示你测试环境中潜在的问题如缺少Provider、React版本警告等这些问题可能也会影响测试本身的行为。团队协作约定如果是在团队中使用建议在项目的README或测试规范中简单说明jest-preview的用途和基本用法。特别是如何启动预览服务器可以写在package.json的scripts里如test:preview: jest-preview serve npm test避免每个成员重复摸索配置。与CI/CD流水线隔离确保你的CI/CD脚本如GitHub Actions, GitLab CI不会尝试启动或依赖jest-preview服务器。预览服务器需要图形化界面和长期运行不适合无头headless的CI环境。可以通过环境变量判断或者在CI中直接运行jest命令而非可能启动预览的脚本。jest-preview解决的痛点非常精准——前端测试中可视化反馈的缺失。它轻巧、无侵入、即时反馈的特性完美地填补了工具链上的这个空白。虽然它在处理极其复杂的、重度依赖构建时优化的CSS方案时可能仍有边界但对于90%以上的日常测试调试场景它都能提供巨大的帮助。下次当你再对着screen.debug()输出的一团HTML发呆时不妨试试jest-preview让浏览器来帮你“看图说话”。