【问题标题】:Unit testing (?) an angular 6 component with TestBed使用 TestBed 进行单元测试(?)一个 Angular 6 组件
【发布时间】:2018-05-22 19:52:32
【问题描述】:

在使用TestBed 时,您真的是在对组件进行单元测试还是在进行集成测试?

创建夹具 (TestBed.createComponent(AppComponent)) 并调用 fixture.detectChanges() 会自动调用 ngOnInit。如果您想测试另一种方法,您现在正在测试多个单元。

这就引出了另一个问题:您应该测试单元还是测试用户操作?例如,您是否应该测试 setDimensions 方法,或者您是否应该测试当用户单击某个按钮时,元素是否具有适当的尺寸。

我猜第一种测试方式会更接近于“单元测试”方式,但是你仍然需要处理被调用组件的生命周期方法。这让我觉得没有办法使用TestBed 对组件进行单元测试。存根所有生命周期方法似乎很荒谬。

无论您决定测试哪种方式,都应该测试 DOM,不是吗?然后,您不会通过包含 DOM api 进行孤立测试。

【问题讨论】:

  • 在将包含相关组件的所有内容称为“集成测试”stackoverflow.com/a/5357837/4793951 之前,您应该考虑这一点
  • 我不确定集成测试是否必须涉及系统的外部部分(例如 DB)而不是单元测试。对您指出我的答案的评论反映了我的想法:“单元测试的描述非常好,但您是否认为成对集成不涵盖整个应用程序,仅涵盖两个可测试单元”。那么你是说我的问题中描述的测试,使用TestBed断言DOM是一个单元测试,或者单元测试和集成测试之间可能有一条灰线,它可以被认为是其中之一?

标签: angular unit-testing integration-testing angular-components testbed


【解决方案1】:

引用自Angular docs:

一个组件,与 Angular 应用程序的所有其他部分不同, 结合了 HTML 模板和 TypeScript 类。该组件真正 是模板和类一起工作。并充分测试 一个组件,您应该测试它们是否按预期协同工作。

此类测试需要在 浏览器 DOM,就像 Angular 所做的那样,并调查组件类的 与模板描述的 DOM 交互。

Angular TestBed 促进了这种测试,正如您将在 下面的部分。但是在很多情况下,测试组件类 单独,无需 DOM 参与,可以验证组件的大部分 以更简单、更明显的方式进行行为。

所以这里,单元是一个组件模板和类一起工作)。您应该尝试通过存根输入和依赖项来测试组件。

我想如果您从上到下阅读测试文档一次,您就会在其中找到问题的答案。

【讨论】:

  • 集成测试应该测试应用程序的不同部分是否协同工作,因此有人可能会争辩说测试组件(它是类和模板/DOM的组合)实际上是集成测试。你真的可以说一个测试是一个单元测试,因为正在测试一个单元吗?单元测试不应该测试尽可能小的单元吗?组件绝对不是最小的单位。那么,单位的大小/范围是主观的吗?什么是单位?模块是一个单元吗?
  • 是的,模块在某些情况下是一个单元。通过查看测试的基本原理而不是单元的大小或复杂性,可以更好地理解测试是单元还是集成,即测试的重点是单元的功能还是单元之间传递的消息。我猜你被 pure functions 是唯一可能的合法 unit 测试的想法所困扰。看看how wikipedia tries to define units covering different possibilities
  • 感谢您的回复,我阅读了维基百科的文章。如果一个模块可以是一个单元,而一个组件可以是一个单元(它是模块的一部分),那么以验证其功能为目标的测试模块也将测试组件(也是单元)之间的消息传递。因此,如果您不测试最小单元,您将始终测试较小单元之间的通信。
  • 我猜想将模块视为单元是在不同的编程语言中,而不是在 JavaScript 中做出这样的选择是微不足道的。不适用于 Angular 模块。
【解决方案2】:

更多信息来自Test Driven Development Wikipedia page

对于 TDD,一个单元最常被定义为一个类,或一组通常称为模块的相关功能。据称,保持相对较小的单位可以提供重要的好处 [...]

所以单元测试不一定测试最小的单元。

由于大量使用单元测试,测试驱动开发在需要完整功能测试来确定成功或失败的情况下无法执行足够的测试。[21]这些示例包括用户界面、与数据库一起使用的程序,以及一些依赖于特定网络配置的程序。 TDD 鼓励开发人员将最少数量的代码放入此类模块中,并最大限度地利用可测试库代码中的逻辑,使用 fakes 和 mocks 来表示外部世界。[22]

UI 可以通过单元测试进行测试,直到某个收益递减点,此时功能测试/e2e 测试很有用。

单元测试之所以如此命名,是因为它们每个测试一个代码单元。一个复杂的模块可能有一千个单元测试,而一个简单的模块可能只有十个。用于 TDD 的单元测试不应该跨越程序中的进程边界,更不用说网络连接了。这样做会引入延迟,使测试运行缓慢并阻止开发人员运行整个套件。引入对外部模块或数据的依赖也会将单元测试变成集成测试。如果一个模块在一系列相互关联的模块中出现异常行为,则无法立即明确到哪里寻找故障原因。

我想我现在将集成测试定义为同时测试应用程序外部部分的测试,例如数据库或服务器 API 等其他进程。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-11-19
    • 2018-05-21
    • 2016-10-07
    • 1970-01-01
    • 2020-05-09
    • 1970-01-01
    • 2019-01-02
    • 1970-01-01
    相关资源
    最近更新 更多