使

使用 Storybook 进行更好的测试

2025-06-07

使用 Storybook 进行更好的测试

在本文中,我们将讨论我喜欢的、有助于保持Storybook故事更新的策略。对于那些不熟悉 Storybook 的人来说,是一个 UI 组件工作区,我发现它在构建前端应用程序时很有帮助。

它允许您独立开发组件,与这些组件单独交互,并在比屏幕或页面级别更精细的级别上查看质量问题。此外,此工作区还可以与其他开发人员沟通,记录系统中存在的可复用组件。点击此处了解更多关于 Storybook 的信息

我经常听到的一个批评是,如果开发人员忘记将他们的组件添加到 Storybook 中, Storybook项目很容易过时。我经常发现 Storybook 确实加快了开发速度,但我理解在实时运行的应用程序环境中构建新组件的趋势。当你拥有一个已经运行并经过测试的功能时,很容易忘记添加故事。

我们如何才能始终保持这种“独立构建组件”的思维模式,以便为那些可能不需要先在 Storybook 中开发组件的人提供直接的价值?在这种情况下,我经常喜欢将故事作为测试策略的一部分。

传统测试

假设我们正在构建一个活动提要。在活动提要项组件中,我们希望确保渲染正确的文本,并且按钮的 onClick 事件能够按预期触发。我们可以使用react-testing-library来确保组件能够按预期运行。

我们将使用该render实用程序来渲染我们要测试的组件。我们将检查文本和 onClick 功能,以确保一切正常。

// ActivityFeedItem.js
export default function ActivityFeedItem({ name, text, onClick }) {
  return (
    <Card>
      <Heading>{name}</Heading>
      <Text>{text}</Text>
      <Button onClick={onClick}>See Details</Button>
    </Card>
  );
}

// ActivityFeedItem.test.js
import { render } from '@testing-library/react';
...
it("shows the correct text", () => {
  const { getByText } = render(
    <ActivityFeedItem
      name="This is the heading!"
      text="Nostrud tempor ullamco aute nostrud commodo cillum amet ad velit veniam officia minim."
    />
  );

  expect(
    getByText(
      "Nostrud tempor ullamco aute nostrud commodo cillum amet ad velit veniam officia minim."
    )
  ).toBeInTheDocument();
});
Enter fullscreen mode Exit fullscreen mode

当我们运行测试时,我们会看到一切都按预期进行。

Test Suites: 7 passed, 7 total
Tests:       9 passed, 9 total
Snapshots:   5 passed, 5 total
Time:        2.62s
Ran all test suites.
Enter fullscreen mode Exit fullscreen mode

调试失败的测试

如果我们的测试失败了,我们想要深入调试,会发生什么?

Test Suites: 1 failed, 6 passed, 7 total
Enter fullscreen mode Exit fullscreen mode

有很多选择,但我最常用的是debugReact 测试库中的工具。这个工具可以照亮渲染元素的 HTML。

我们可以按如下方式更新我们的测试以利用debug

const { getByText, debug } = render(
  <ActivityFeedItem
    name="This is the heading!"
    text="Sit enim irure pariatur nostrud id non deserunt laboris veniam velit."
  />
)

debug()
Enter fullscreen mode Exit fullscreen mode

debug实用程序将记录我们组件的 HTML。对于我们这个简单的示例组件来说,这种策略效果很好,但对于更复杂的组件来说,这种方法很快就会变得难以处理。

我们可以利用 Storybook 故事来实现这一点,而不是直接在测试中定义要渲染的元素。我们将使用以 Storybook组件故事格式编写的故事作为render测试中所需的元素。

我们首先创建故事元数据。这些元数据为 Storybook 提供了如何在实用程序中显示故事的信息。接下来,我们将创建一个具有组件故事格式的故事。您可能会注意到,我们正在创建一个箭头函数,这并非 Storybook 独有的。我们可以导出此箭头函数并将其导入到测试中。

// ActivityFeedItem.stories.js
export default { title: "ActivityFeedItem" }

export const standard = (callback = undefined) => {
  return (
    <ActivityFeedItem
      name="This is the heading"
      text="Nostrud tempor ullamco aute nostrud commodo cillum amet ad velit veniam officia minim."
      onClick={callback}
    />
  )
}
Enter fullscreen mode Exit fullscreen mode

在我们的测试中使用故事

rendered在测试组件之前,我们将使用导入的故事。现在,如果我们想要调试测试,除了我们传统上使用的其他调试策略之外,我们还有一个故事可以使用。

import { standard } from "./ActivityFeedItem.stories"

it("shows the correct text", () => {
  const { getByText } = render(standard())

  expect(
    getByText(
      "Nostrud tempor ullamco aute nostrud commodo cillum amet ad velit veiam officia minim."
    )
  ).toBeInTheDocument()
})
Enter fullscreen mode Exit fullscreen mode

组件的故事书视图

我们现在有一种方法可以可视化并与我们正在测试的组件进行交互。

总结

Storybook 除了测试之外还有很多好处,但有时我们在尝试推出功能时很容易忘记这一点。我发现,使用 Storybook 作为确保质量的工具,有助于避免故事过时或被忽视的情况。

文章来源:https://dev.to/ryanlanciaux/better-testing-with-storybook-3fn
PREV
SolidJS 与其他 JS 框架的 5 个不同之处 1. 组件不重新渲染 2. 代理是只读的 3. 没有 isSignal/isObservable/isRef 4. 更新是同步的 5. 没有取消订阅 结论
NEXT
为什么你的技术博客应该放在 Dev.to