Vue组件测试测什么

原文:https://laylawang17.github.io/2020/03/19/Vue%E7%BB%84%E4%BB%B6%E6%B5%8B%E8%AF%95%E6%B5%8B%E4%BB%80%E4%B9%88/

学习了一段时间 Vue 组件单元测试相关知识,感觉比起用什么测试框架、怎么写测试更重要的是搞明白组件测试应该测什么,这里就总结一下自己的一些思考。

组件测试不应该测什么

  1. 单纯测试组件模板中的 HTML

    比如,测试组件模板中有几个 divinputbutton,以及元素的 classid 属性等与业务逻辑无关的纯 UI 测试。这里并非说我们不需要关注组件的 UI,而是出于以下几个考量:

    • 使用单元测试测试组件的 UI 会导致测试非常繁琐,为了测试覆盖的全面会导致针对一个组件写出大量的测试,不但降低了开发效率还体验非常差
    • 这种单纯的 UI 测试是非常脆弱的,这类测试和组件模板是强耦合的,一旦我们对 HTML 结构进行调整,测试就会挂掉,这就造成了测试非常难以维护。而实际上我们往往并不关心组件模板中的具体 HTML 结构是怎样的,我们只关心组件呈现出来的样子
    • 像 Jest 等前端测试框架已经提供了快照测试来帮助我们对比修改引起的 UI 变化,并且我们也可以使用Storybook这类工具实现可视化的 UI 测试
  2. 测试组件的内部方法

    如果一些方法只是在组件内部调用其他方法而没有任何暴露给外部的行为(比如更改了组件的 UI、请求外部 API 等),那这些方法是不需要测试的。我们希望一个组件就像一个黑盒一样,我们不关心其内部的处理逻辑而只关注其外部呈现。

    You should test your component's public interface and side effects.

组件测试应该测什么

这里以 Vue 组件来总结一下组件测试需要测什么。

  1. 测试组件是一个 Vue 实例

    test("is a Vue instance", () => {
      const wrapper = shallowMount(MyComponent);
      expect(wrapper.isVueInstance()).toBeTruthy();
    });
    

    这个测试应该置于该组件所有其他单元测试之前,以保证该组件能够正常挂载

  2. 测试组件实例的数据

    由于组件的渲染是依赖propsdata以及计算属性computed的,因此需要针对这些数据进行测试,如

    • 给定 props下,初始的 data是否正确
    • 给定 propsdata后,计算属性的值是否正确
    • 在父组件中测试 props是否正确传递给子组件
  3. 测试组件实例的渲染结果

    同样因为组件的渲染依赖propsdatacomputed这些数据,因此需要 mock 这些数据来测试不同数据作用下的渲染结果是否符合预期,如

    • 测试本文内容是否与数据一致

    • 测试条件渲染的结果

      元素或子组件的存在性是否随数据的变化而变化

    • 测试循环渲染的结果

      元素或子组件的数量是否与数据一致

  4. 测试组件实例的事件

    用户与 UI 的交互是通过事件完成的,因此需要针对事件进行测试,如

    • 触发clickinput等事件后组件上的自定义事件是否被触发

      比如 Todo List App 的add-todo等一系列自定义事件能否被触发

    • 触发事件后对应的处理方法是否被调用,以及是否使用预期的参数调用

      需要注意的是,这里主要测试的是一些对外的方法,比如调用 API 等

    • 触发事件后data是否按预期更新

    • 触发事件后组件是否按预期渲染

      如果已经有测试用例测试过事件能更新data、且组件能根据data渲染,则无需再测试组件能根据事件渲染

使用 Vuex 管理数据的组件应该怎么测

使用 Vuex 管理数据流后,我们需要额外针对gettersmutationsactions等进行测试,以保证组件的数据和行为是符合我们预期的。针对 Vuex 的测试有两个要点:

  • 由于gettersmutationsactions实际上都是普通的函数,因此我们可以通过测试这些函数在给定输入下是否有预期输出来保证它们的正确性

  • 结合Vuex 的作用原理,我们可以按照 Vuex 中数据的流向设计测试用例

    一个由 Vuex 管理数据流的 App 大致是按照如下的方式工作的:

    1. 用户与 UI 交互触发事件
    2. 事件的监听函数 dispatch 相应的action
    3. action提交包含类型和数据的mutation
    4. mutation负责处理具体的业务逻辑,更新 App 的state
    5. getters进而会根据state重新计算
    6. 组件监听到state的变化而重新渲染

在理解上述要点的情况下,我们可以总结出针对 Vuex 的一些测试方法:

  1. 模拟事件的触发,测试是否 dispatch 相应的action
  2. mock 掉commit方法,测试action函数是否能使用正确的参数 commitmutation
  3. 测试给定参数下,mutations能否正确修改state
  4. 测试给定state时,getters的计算结果是否正确
  5. 给定 stategetters下,测试组件接收到的props是否正确
  6. 给定props下组件能否正确渲染

怎么使用快照测试

上述总结的单元测试方法主要测试的是组件的行为是否与预期相符,为了更全面的测试组件 UI,我们可以使用快照测试。

快照测试带来的好处是可以清晰的对比出 UI 的变化,让开发人员确认是必要的改变还是引入的 bug,避免了为测试 UI 导致单元测试过于陷入细节和脆弱。

需要注意的是,快照测试是不能够替代单元测试的,因为它只是对 UI 历史版本的记录,无法用于描述所期望的 App 的行为,因而不能够像传统的单元测试一样做为所开发的 App 的“使用文档”,它应该和单元测试一起互为补充。

参考

  • Five Traps to Avoid While Unit Testing Vue.js
  • Vue Test Utils - 常用技巧
  • Testing with Jest Snapshots: First Impressions

你可能感兴趣的:(Vue组件测试测什么)