通过写测试用例来学习是一种高效的学习方法

为什么可以通过测试用例来学习

学习的过程,是了解输入输出的过程。学习语法,就是学习支持怎样的写法(即输入),能达到怎样的效果(即输出)。学习 API,就是学习 API 支持哪些输入,会有怎样的对应的输出。

写测试用例,就是给定输入,判断输出和预期是否一致。这个过程和学习的过程是一致的。比如:学习数组的 unshift 的方法,可以写如下的测试用例:

  1. describe('unshift:添加一个或多个元素到开头', () => {
  2. test('添加一个元素到开头', () => {
  3. const arr = [1, 2]
  4. arr.unshift(0)
  5. expect(arr).toEqual([0, 1, 2])
  6. })
  7. test('添加多个元素到开头', () => {
  8. const arr = [1, 2]
  9. arr.unshift(-2, -1, 0)
  10. expect(arr).toEqual([-2, -1, 0, 1, 2])
  11. })
  12. test('返回值是添加后的数组长度', () => {
  13. const arr = ['a', 'b']
  14. const res = arr.unshift('c')
  15. expect(res).toBe(3)
  16. })
  17. })

为什么是高效的

在学习中的过程中,付出的努力越多,学习效果越好。

普林斯顿大学的 Pam A. Mueller 学者和 UCLA 的 Daniel Oppenheimer 联合做了一项实验,他们让两组大学生分别用电脑和手写做笔记,然后对他们观看的讲座内容进行测试,看看到底如何记笔记效果更好。

实验的结果是:手写笔记好。用电脑记笔记的人,由于打字速度快,只是无脑的记。手写的,由于他们不能快速记录,必须提炼记录的内容。这是个思考的过程。

用测试来学,需要设计测试用例。设计测试用例的过程,是一个思考,加深印象的过程。比如,学习 Flex 布局,有个特性是:主轴是行的的 Flex 容器下,子项在一行。我设计了这样如下的用例:

  1. const posYArr = await page.evaluate(() => {
  2. const items = document.querySelectorAll('.ly>.item')
  3. return [
  4. items[0].getBoundingClientRect().top,
  5. items[1].getBoundingClientRect().top,
  6. items[2].getBoundingClientRect().top,
  7. ]
  8. })
  9. expect(posYArr[0]).toBe(posYArr[1])
  10. expect(posYArr[1]).toBe(posYArr[2])

示例

我建了个有丰富内容的测试用例项目: https://github.com/iamjoel/learn-by-test。目前内容有: 数字,字符串,正则,数组,对象,函数,枚举,Set,this,Promise,async/await,解构赋值,DOM,选择器优先级,Flex 布局,Node 的 fs 和 path,React,Lodash,moment 等。

欢迎大家 Star,Fork 和 PR~