5

Vue 应用单元测试的策略与实践 01 - 前言和目标

 3 years ago
source link: https://blog.jimmylv.info/2018-09-19-vue-application-unit-test-strategy-and-practice-01-introduction/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Vue 应用单元测试的策略与实践 01

本文主要尝试解决三个问题:

  1. 在 TDD 做完 Tasking 列完实例化数据之后,完全没有 UT 基础不知道该怎么写单元测试?
  2. 在 Vue 应用的单元测试中,对 UI 组件和 vuex store 等测试的区别有何不同?颗粒度该细到什么程度?
  3. Vue 项目中测试收益如何最大化,如何配置高性价比的测试策略,即什么地方最该花力气测试,什么地方又可以暂且放一放?
  4. 在 Vue 项目中如何推动整个团队循序渐进地采取单元测试策略?逐步提高代码质量和测试覆盖率?

不谈论的包括:

  • ATT 验收测试 或 E2E 端到端测试,这个是我想进一步探索的话题,特别是在 TDD 的语境下。#322
  • 为什么要 TDD?但是我会讲为什么要 UT 单元测试。测试和 TDD 是两码事,而光是自动化测试的好处就已经足够多,但是如何做到更好的自动化和持续集成,那就需要 TDD 来指引方向。
  • Snapshot Testing 快照测试,其实我是很认可快照这种形式,但需要改进其工作流,至少结合 Image Snapshot 和 Storybook 等工具,甚至更应该放到 CI 上去。#311

下面我就来结合具体场景,进一步实例化这些问题,举几个 🌰:

1. 在 TDD 做完 Tasking 列完实例化数据之后,完全没有 UT 基础不知道该怎么写单元测试?

// Given
一个完全没有 UT 基础的新人 🚶
// When
当他 🚶 阅读和练习本文的 Jest 的部分
// Then
他能够把 Given/When/Then 的套路学会
他能够学会 Jest 的基本用法,包括测试 suite 和断言等语法
他能够学会 Jest 中测试异步的几种方式

2. 在 Vue 应用的单元测试中,对 UI 组件和 vuex store 等测试的区别有何不同?颗粒度该细到什么程度?

// Given
一个有基本的 UT 知识但没写过 Vue 测试的新人 🚶
// When
当他 🚶 阅读和练习本文的 Vue 单元测试的部分
// Then
当然,他能够学会 Vue 组件在测试当中的几种渲染方式
他能够学会 UI 组件的分类,特别是交互行为的测试方式
他能够对 Vuex 概念的理解更加深入,且知道 `Redux-like` 架构的好处
他能够合理测试 vuex store 的 mutation 和 getter 中的业务逻辑
他能够测试组件如何正确 dispatch action 以及 action 中如何做异步操作

3. Vue 项目中测试收益如何最大化,如何配置高性价比的测试策略,即什么地方到底该花力气测试,什么地方又可以暂且放一放?

// Given
一个具备 UT 基础但找不到着力点的求索之徒 🐒
// When
当他 🚶 阅读本文的 Vue 应用测试策略部分
// Then
他能够找到测试的重点,重新燃起对 UT 的热情 🔥
他能够在项目背景下合理配置单元测试的测试策略

于是乎,这就是本系列文章的大纲,先放出来给大家一个对于 Vue 应用单元测试的全局观:

## 单元测试基础

### 为什么选择 Jest

### Jest 的基本用法

### 该如何测试异步代码?

### 单元测试与自动化的意义

## Vue 单元测试

### Vue 组件的渲染方式

### Wrapper `find()` 方法与选择器

### UI 组件交互行为的测试

## Vuex 单元测试

### CQRS 与 `Redux-like` 架构

### 如何对 Vuex 进行单元测试

### Vue 组件和 Vuex store 的交互

## Vue 应用测试策略

### 单元测试的特点及其位置

### 单元测试的关注点

### 应用测试的测试策略

😯 哦豁,正文终于开始……


为什么要有单元测试?

引用好友鲜明的观点就是:写不好是能力问题,不写则是态度问题。单元测试客观上可以让开发者的工作更高效,Vue 应用的单元测试是一定要的。

单元测试的上下文

谈任何东西都一定要有个上下文。你的论述不能是「因为单元测试有这些好处,所以我们要做单元测试」,而应该是「不做单元测试我们会遇到什么问题」,这样才能回答「为什么要写单元测试」的问题。那么我们谈论单元测试的上下文是什么呢?不做单元测试我们会遇到什么问题呢?

agile

上图为一个产品从 idea 分析、设计、开发、测试到交付并获取市场反馈的过程。

单元测试的上下文就是存在于「敏捷」当中。敏捷为的是更快地交付有价值的可工作的软件。为此,它有一个指标来度量这个「更快」,那就是 lead time,它度量的是一个 idea 从提出被验证,到最终上生产环境面对用户的时间。显然,这个时间越短,软件获得反馈的时间就越短,对价值的验证就越快发生。

单元测试的意义

这个结论对我们写不写单元测试有什么影响呢?答案是,不写单元测试,你就快不起来。为啥呢?因为每次发布,你都要投入人力来进行手工测试;因为没有测试,你倾向于不敢随意重构,这又导致代码逐渐腐化,复杂度使得你的开发速度降低。

那么在这个上下文中来谈要不要单元测试,我们就可以很有根据了,而不是“开发爽了就用,不爽就不用”这样含糊的答案:

  • 如果你说我的业务部门不需要频繁上线,并且我有足够的人力来覆盖手工测试,那你可以不用单元测试
  • 如果你说我不在意代码腐化,并且我也不做重构,那你可以不用单元测试
  • 如果你说我不在意代码质量,好几个没有测试保护的 if-else 裸奔也不在话下,脑不好还做什么程序员,那你可以不用单元测试
  • 如果你说我确有快速部署的需求,但我们不 care 质量问题,出回归问题就修,那你可以不用单元测试

除此之外,你就需要写单元测试。如果你想随时整理重构代码,那么你需要写单元测试;如果你想有自动化的测试套件来帮你快速验证提交的完整性,那么你需要写单元测试。

单元测试与自动化的关系

综上,我们用来谈论单元测试的「透镜」是什么呢?一言以蔽之,两点:反馈速度自动化

自动化回答的是要不要自动化的单元测试这个问题。测试是重构的唯一保障,也就是说,没有测试,基本上就没法重构代码(重构指的是 不改变软件可观测行为的前提下改善代码内部设计或实现 ),基本上就只能看着代码腐化。那么,基本上只要你的系统需要持续发展,你就需要单元测试。

反馈速度回答的是要不要 TDD、测试先行还是后补这个问题。答案是,需要 TDD,最好先行,因为可以提高反馈速度,缩短反馈周期,与此同时减少不必要的浪费。

再考虑到以下两大事实:人员会流动,应用会变大。人员一定会流动,需求一定会增加,直至再也没有一个人能够了解应用的所有功能,那时对应用做出修改的成本将变得很高。因此,意图依赖人、依赖手工的方式来应对响应力的挑战首先是低效的,从时间维度上来讲也是不可能的。因此,为了服务于“高响应力”这个目标,随时重构整理代码是必须的,这就需要我们有一套自动化的测试套件,它能帮我们提供快速反馈,做质量的守卫者。唯解决了人工、质量的这一环,开发效率才能稳步提升,团队和企业的高响应力才可能达到。

至此,回答了「为什么我们需要写单元测试」的问题。下面让我们来谈谈如何写好 JavaScript 代码和 Vue 应用框架的单元测试。

如何选择一个测试框架?

众所周知,JavaScript 世界里最不缺的就是轮子,测试框架也是如此。其实这里的子标题就是为什么选择 Jest?有时候安于现状,只不过是因为我们没有见过理想的模样。只有当我们见过更好的世界和更好的测试框架,才会惊呼“原来世界是这样美好呀!我怎么都没有想到呢?”

引自技术雷达:Jest 是一个“零配置”的前端测试工具,具有诸如模拟和代码覆盖之类的开箱即用特性,主要用于 React 和其他 JavaScript 框架。

我们团队对采用 JEST 做前端测试的结果非常满意。它提供了一种“零配置”的开发体验,并具备诸多开箱即用的功能,比如 Mock 和代码覆盖率等。你不仅可以将此测试框架应用于 React.js 应用程序,也可以应用于其他 JavaScript 框架。Jest 经常被炒作的功能之一是用户界面的快照测试。快照测试可以作为测试金字塔上层一个很好的补充,但请记住,单元测试仍然是坚实的基础。

一个好的测试框架,Jest 的几大好处可以涵盖为:

  • Fast 天下武功,唯快不破。确实很快,虽然实测下来跟 Mocha 新版本还是慢了些,以后找个机会再测一次。
  • Opinionated 不需要你做出选择和配置,就能提供所有的东西,比如 Mock(干掉 Sinon)、Test Runner(干掉 Karma)、Matcher(干掉 Chai)、Test Coverage(内置 istanbul)
  • Watch Mode 守护模式。非常注重开发者体验,能够在编码的时候帮助我们快速获得测试结果的反馈。
  • Snapshot Testing 快照测试。这是值得争议的一点,前文也提到过会专门开个 issue 来讨论,在此不再赘述。

最后,总结一下 Jest

Jest 作为一个测试框架,其最大的特点就在于它是一个非常有效的解决方案,不需要与其他测试库交互来执行它的工作。与此同时 Jest 非常注重开发者体验,这一点也是特别值得欣赏,现在市面上关注开发者(“人”)体验的开发框架和工具实在不多,而 Jest Watch 模式的核心就在于快速获得反馈,虽然我没在命令行使用而是 WebStorm 但亦可以与之结合。

ps: 除此之外,还有很多开发者体验亦值得细细品味与发现,特别是 Jest 本身来自 Facebook 的工程化支持也是特别棒的,这个讲述如何开发 Jest 的官方视频值得一看:Building High-Quality JavaScript Tools

未完待续……

## 单元测试基础

  • ### 为什么选择 Jest
  • ### Jest 的基本用法
  • ### 该如何测试异步代码?
  • ### 单元测试与自动化的意义

## Vue 单元测试

  • ### Vue 组件的渲染方式
  • ### Wrapper find() 方法与选择器
  • ### UI 组件交互行为的测试

## Vuex 单元测试

  • ### CQRS 与 Redux-like 架构
  • ### 如何对 Vuex 进行单元测试
  • ### Vue 组件和 Vuex store 的交互

## Vue 应用测试策略

  • ### 单元测试的特点及其位置
  • ### 单元测试的关注点
  • ### 应用测试的测试策略

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK