Storybook中如何配置Jest快照测试时忽略特定样式属性?

晏鸣 Dev 阅读 28

我在给React组件写Storybook快照测试时遇到问题,快照里总是包含组件上不需要的样式属性,比如data-testid。我尝试在Jest配置里加了snapshotSerializers,但还是报错说快照不匹配,应该怎么排除这些属性呢?

具体场景是这样的:我用Storybook+Jest做快照测试,组件有data-testid="button"这样的测试辅助属性。执行测试时快照里会包含这个属性,但我想只保留组件的核心结构。之前试过修改jest.config.js


module.exports = {
  snapshotSerializers: ['@testing-library/react-native/serializer'],
  // 其他配置...
};

但运行npm test时仍然得到这样的错误:


- Received value does not match stored snapshot.
  
  - Diff:
    @@ -10,10 +10,9 @@
        "props": {
          "children": "Click me",
          "className": "primary-btn",
    -     "data-testid": "button",
          "onClick": [Function]
        },
    ...

有什么办法能全局配置快照测试忽略特定属性吗?或者需要在Storybook的预处理器里做处理?

我来解答 赞 3 收藏
二维码
手机扫码查看
1 条解答
远香(打工版)
你这个需求其实挺常见的,data-testid 这种测试属性确实不该进快照。问题出在你用的 serializer 不对路——@testing-library/react-native/serializer 是给 React Native 用的,你在 Web 环境下用它基本没效果。

标准写法是用 @storybook/testing-react 提供的预处理器机制,在快照序列化前把不需要的属性过滤掉。你可以通过自定义一个 snapshot serializer 来实现全局过滤。

在项目根目录新建一个文件,比如 jest-serializer-remove-test-ids.js

const reactElement = Symbol.for('react.element');

module.exports = {
test(val) {
return val && val.$$typeof === reactElement;
},
serialize(element, config, indentation, depth, refs, printer) {
const filteredProps = { ...element.props };
delete filteredProps['data-testid'];
// 如果还有其他想忽略的也可以删,比如 data-cy、aria-label 测试用的等
// delete filteredProps['data-cy'];

const filteredElement = {
...element,
props: filteredProps,
};

return printer(filteredElement, config, indentation, depth, refs);
},
};


然后在 jest.config.js 里注册这个 serializer:

module.exports = {
setupFilesAfterEnv: ['@testing-library/jest-dom/extend-expect'],
snapshotSerializers: ['/jest-serializer-remove-test-ids.js'],
};


注意路径要写对,可以用 path.resolve 引入。

这样所有快照里的 data-testid 都会被自动移除,不会再出现 diff 报错。而且这是全局生效的,不用每个 story 单独处理。

另外提醒一点,别指望 Storybook 的 render 预处理能解决这个问题,因为快照是 Jest 拿到的 VDOM 结构,必须在序列化阶段动手脚才有效。这套方案是目前社区的标准做法,文档也明确推荐过类似模式。
点赞 1
2026-02-12 22:03