测试消耗其他组件的组件的关注点分离是什么



当为使用其他Web组件(子组件)的Web组件(父组件)编写测试时,父组件的测试是否应该提供覆盖范围以确保子组件正确呈现/配置?

这里有一个例子,它可能是一个糟糕的例子,但让我们试试:假设我们有一个组件(WebComponent/React/Vue/Ember,任何组件都可以在这里):<Carousel @options=options>渲染各种子组件:例如<Video @options=options><Image @option=options>等等。

轮播组件从模型接收一组options,例如iconColorobjectFit,并以 datadown 方式传递这些,以便与子组件共享并由子组件使用。

我应该在<Image><Carousel>测试中测试"用户可以为图像配置图标颜色"吗?

对我来说似乎很尴尬,在<Carousel><Image>的相应测试中测试iconcolor的成功配置也不是很干燥。如果<Carousel>组件消耗 5 个不同的组件,则其测试的大小开始扩展,尤其是在我们添加更多配置选项的情况下。

但与此同时,在两者中都没有测试覆盖率似乎非常脆弱。 例如,如果我们依靠<Image>的测试覆盖率来配置 iconColor,<Image>可以随时重构,开发人员可以更改用于设置 iconColor 的属性名称,调整测试以匹配。开发人员不会意识到<Carousel>依赖于<Image>的API来配置iconColor。

如果您的目标是尽可能高的代码覆盖率,或者父组件和子组件的集成至关重要(即,如果它没有以正确的方式将某些东西交给子组件,那么事情可能会出错),那么您绝对应该测试父组件和子组件之间的多种可能配置。

我理解你说它感觉不是很干燥的意思(在某些形式或情况下它真的不是 DRY),但你应该这样想:

在隔离子组件并测试各种配置的情况下,您的测试应该主要关注测试这些组件在涉及 DOM 时对配置执行的操作,或者测试任何服务的边界等。

使用您的示例,如果我有一个<Image>组件,我将编写集成测试,以便在为其提供特定 props 或选项时断言其行为。例如,如果我传入这些参数会发生什么?

<Image @width=100 @height=100 @onClick={{action "doSomething"}} />

集成测试应测试这些值是否对它呈现的任何内容以及用户与图像的交互方式有一定影响。也许widthheight以百分比形式设置<img>标签的宽度和高度,单击图像应该调用提供给此组件的操作。

另一方面,如果我已经有一个集成测试来测试<Image />组件可以执行的所有操作,为什么我们需要测试我的<Carousel />组件是否可以呈现<Image />组件?

答案是测试这两个组件之间的集成,并确保父组件与子组件正确连接。换句话说,这是为了确保<Carousel />正确地向其子组件提供任何和所有选项。

在某些情况下,这可能没什么大不了的,实际上我认为很多时候这里的测试可能会被忽略,但就像我之前说的,如果集成至关重要,那么你必须测试父母如何将选项传递给孩子。

为了说明这如何提供覆盖范围,假设我像这样连接<Carousel />组件的模板:

旋转木马.hbs

<Image @width=50 @height=50 @onChange={{action "doSomething"}} />

看着这个,你可以清楚地看到发生了什么——我的意思是把这个动作连接成@onClick,而不是@onChange。然而,我所有的<Image />集成测试都通过了,所以如果不测试<Carousel />组件如何将属性传递给它的子组件,我将缺乏覆盖率,并且这个错误更有可能进入生产环境。

使其不 DRY 的部分是查看父级的集成测试,并且必须编写非常相似的代码(即,确保当我单击图像时它会调用正确的操作)。有时没有真正好的方法来解决这个问题 - 我认为这些场景是集成可能被忽视的地方。其他时候,可以做一些事情来减少重复测试代码的数量。

在 Ember 中,有时传入属性与子组件的特定类名相关联(以及其他功能)。与其复制检查"子组件的行为是否正确?"的测试,我们可以编写一个集成测试来检查"子组件是否收到了正确的属性?

例如,如果我们的父组件是这样连接的:

旋转木马.hbs

<Image @someFlag=true />

假设此@someFlag属性执行以下操作:

  • 向图像添加类
  • 使图像在鼠标悬停时变大
  • 发出网络请求,以便在点击图像时报告某些用户指标

<Image />组件的集成测试将在@someFlag为真时测试所有这些内容。但是,我们的<Carousel />组件的集成测试可以简单地检查:"<Image />组件是否具有预期的类名?这实际上是减少需要编写的重复测试代码数量的非常常见的方法。

当然,在某些情况下,您不需要测试集成。如果<Carousel />只是把它收到的任何东西传递给它的孩子,那么你有一个反对为这种事情编写整合测试的论据。

最新更新