视觉测试
任何 Storybook 教程都不会缺少测试。测试对于创建高质量的 UI 至关重要。在模块化系统中,微小的改动都可能导致重大的回归。到目前为止,我们已经接触了两种类型的测试。
- 借助 Storybook 和 Vitest 集成的组件测试,可以帮助开发人员在真实的浏览器环境中自动化渲染和组件行为。
- 借助 play 函数进行的交互测试,可以在与组件交互时验证组件是否按预期运行。它们非常适合测试组件在使用过程中的行为。
“但它看起来是正确的吗?”
不幸的是,上述测试方法本身不足以防止 UI 错误。UI 很难测试,因为设计是主观且微妙的。手动测试就是,嗯,手动。其他 UI 测试,例如快照测试,会触发过多的误报,而像素级单元测试的价值不高。完整的 Storybook 测试策略还包括视觉回归测试。
使用 Storybook 进行视觉测试
视觉测试旨在捕获视觉回归并确保 UI 外观的一致性。它们通过捕获每个测试的快照,并在提交之间进行比较来检测变化。非常适合验证布局、颜色、大小和对比度等图形元素。
Storybook 是一个出色的视觉测试工具,因为每个 story 本身就是一个测试规范。每次我们编写或更新 story 时,我们都会免费获得一个规范!
有几种进行视觉测试的工具。我们推荐 Chromatic,这是由 Storybook 维护者创建的一个免费发布服务,它能在闪电般快速的云浏览器环境中运行视觉测试。它还允许我们将 Storybook 在线发布,正如我们在上一章中所看到的。
捕获 UI 更改
视觉测试依赖于将新渲染的 UI 代码的图像与基线图像进行比较。如果捕获到 UI 更改,我们将收到通知。
让我们通过调整 Task 组件的背景颜色来了解它是如何工作的。
首先为此更改创建一个新分支。
git checkout -b change-task-background
将 src/lib/components/Task.svelte 更改为以下内容
<script lang="ts">
import type { TaskData } from '../../types';
interface Props {
/** Composition of the task */
task: TaskData;
/** Event to change the task to archived */
onArchiveTask: (id: string) => void;
/** Event to change the task to pinned */
onPinTask: (id: string) => void;
}
const {
task = {
id: '',
title: '',
state: 'TASK_INBOX',
},
onArchiveTask,
onPinTask,
}: Props = $props();
let isChecked = $derived(task.state === 'TASK_ARCHIVED');
</script>
<div class="list-item {task.state}">
<label
for="checked-{task.id}"
class="checkbox"
aria-label="archiveTask-{task.id}"
>
<input
type="checkbox"
checked={isChecked}
disabled
name="checked-{task.id}"
id="archiveTask-{task.id}"
/>
<span
role="button"
class="checkbox-custom"
aria-label="archivedTask-{task.id}"
onclick={() => onArchiveTask(task.id ?? "")}
onkeydown={(e) => {
if (e.key === "Enter" || e.key === " ") {
e.preventDefault();
onArchiveTask(task.id ?? "");
}
}}
tabindex="-1"
></span>
</label>
<label for="title-{task.id}" aria-label={task.title} class="title">
<input
type="text"
value={task.title}
readonly
name="title"
id="title-{task.id}"
placeholder="Input title"
+ style="background-color: red;"
/>
</label>
{#if task.state !== "TASK_ARCHIVED"}
<button
class="pin-button"
onclick={(e) => {
e.preventDefault();
onPinTask(task.id ?? "");
}}
id="pinTask-{task.id}"
aria-label="pinTask-{task.id}"
>
<span class="icon-star"></span>
</button>
{/if}
</div>
这将为该项产生新的背景颜色。

添加文件
git add .
提交它
git commit -m "change task background to red"
并将更改推送到远程仓库。
git push -u origin change-task-background
最后,打开你的 GitHub 仓库,然后为 change-task-background 分支打开一个拉取请求。

为你的拉取请求添加描述性文本,然后点击 Create pull request。点击页面底部的“🟡 UI Tests” PR 检查。

它将向你展示你的提交捕获到的 UI 更改。

更改很多!`Task` 是 `PureTaskList` 和 `InboxScreen` 的子组件,这使得一个微小的改动滚雪球般地造成了重大的回归。这种情况正是开发人员需要视觉测试和其他测试方法的原因。

审查更改
视觉测试可确保组件不会意外更改。但决定更改是否是故意的仍取决于我们。
如果更改是故意的,我们将需要更新基线,以便将未来的测试与 story 的最新版本进行比较。如果更改是无意的,则需要修复。
由于现代应用程序是由组件构建的,因此在组件级别进行测试非常重要。这样做有助于我们精确地找到更改的根本原因(即组件),而不是对更改的症状(即屏幕和复合组件)做出反应。
合并更改
完成审查后,我们就可以放心地合并 UI 更改了——知道更新不会意外地引入 bug。如果你喜欢新的 red 背景,则接受更改。如果不喜欢,则恢复到以前的状态。

Storybook 帮助我们构建组件;测试帮助我们维护它们。到目前为止,本教程中介绍的两种 UI 测试类型是手动测试和视觉测试。正如我们刚刚完成的设置一样,这两种都可以自动化到 CI 中,并帮助我们发布组件而不必担心隐藏的 bug。但是,这并非测试组件的唯一方法。我们需要确保我们的组件对所有用户(包括残障人士)都是可访问的。这意味着将可访问性测试纳入我们的工作流程。