[译] 复用 JavaScript 测试用例

983 阅读3分钟

本文主要讲述在增加测试用例有效性的同时,降低测试用例的开发成本。

原文链接:Reusing JavaScript Tests

大多数人都觉得写测试用例实在是太难了~ 😤

首先思考一下我们为什么会需要测试用例呢?🤔

代码定义了一组执行特定操作的指令。下面这个函数被视为执行定义明确的数学运算: y = a + b.

如果开发人员了解它的基本原理,就可以使用代码编写它的正确实现:

//seems about right
function Add(a,b) {
 return a + b;
}

但是,人为错误、系统约束或一些 bug 引起的异常可能会让代码执行出错:

function Add(a,b){
 return a + ‘ ’ + b; //woops!
}

这种情况就需要测试用例来大显身手了。✨

测试用例真实地映射代码的执行及输出。错误代码在将导致测试用例执行失败:

import Add;
test(‘add should return the sum of two numbers’, () => {
  expect(Add(2,3)).toBe(5); //error! it is actually ‘2 3’!
});

##降低成本的同时提高有效性

从数学上讲,“正常”代码是一个连续函数,而测试是同一操作的离散样本。 编写足以确保正确性以的样本量,可能与编写“正常”代码一样困难😞

那么,我们为什么不像使用“正常”代码那样复用现有的测试用例呢?😃

复用测试用例

我知道,复用测试用例是一种不好的体验。

不管测试用例编写得多么好,用现有的无穷无尽的交织代码进行开发都非常困难。如果您尝试过这么做,我打赌您在短时间内就会头疼不已。

但是,我想至少有一个用例是具有普适性的:

interface IFileSystem {
  writeFile(path, content);
  unlink(path)
  …
}
//common file-system implementation:
class NodeFs implements IFileSystem {
  …
}

为 NodeFS 编写的大多数测试,几乎不需要经过修改就可以为 IFileSystem 所用!😯

另一个文件系统可以有另一个实现,但是仍然使用相同的测试用例!

// memory-filesystem
//———————————————
// in memory file system for fast short and isolated uses.
class NodeFs implements IFileSystem {
 …
}
//memory-filesystem.test
//———————————————
import FileSystemTests
import MemFs
FileSystemTests.validate(MemFs);

现在我们可以做到吗?

当然可以! 🥳 代码隔离的成本正在逐渐下降,写测试用例是值得的。

1.写好测试用例:

import expect from ’chai’; //you gotta get it somewhere
import { IBinaryOperation } from ’math-functions’;
import { toPairs } from ’combinatorics’;
function validateAssociativity<T>(
  operation: IBinaryOperation<T>,
  values: T[]) {
  toPairs(values).forEach((x, y) => {
      expect(binaryOperation(x, y))
    .toEqual(binaryOperation(y, x));
  }
}
export validateAssociativity;
  1. 使用 bit 将测试隔离到原子组件中:
§ bit add AssociativeTests.Ts —-id math/tests/associativity
§ bit add -c bit.envs/compilers/typescript
§ bit tag math/tests/associativity
  1. 将您的组件推送到 bit.dev 中的集合:(在此处学习如何 创建 Bit 集合))
§ bit export collection.name math/tests/associativity
  1. 现在,我们可以轻松地复用我们共享的可复用测试组件:
import add from ’./add.js’;
import { validateAssociativity } from ’@bit/collection.name.math.tests.associativity’;
test(‘add associativity’, () => {
const sample = [1, 5, 3, 1000, 0.3, -17];
  // or maybe.. math/samples/realNumbers ..?
validateAssociativity(add, sample);
}

看起来挺整洁的! 🤯

pngSnapshot 组件会成为下一个热门话题吗?🔮

您是怎么看的,我的老伙计? 😍