像我这样优秀的猿,本该代码敲一生,怎么我的 Github 上,还是没有一个好项目:sob:。
像我这样的人,遇见不爽,一言不合就要造轮子,开了好多的坑,很多临时的项目,为了 A 而诞生 B,所以也就只能保正在相关项目中可用,如果有另一个项目要调用时,都是提心吊胆的,生怕越写越不好收场。
最近决定,把自己的代码都好好整理一下,能发布的也别让它就安息了,怎么说它也是我思想逻辑的延续,亲生的啊。
这篇也算是我 blog 的第一篇文章了,为什么写了这个题目,因为这是我遇到的第一个问题,参观了一些知名项目的单元测试,看的我泪流满面的,这工作量可是感人啊,还有简单看了现在比较流行的单元测试库,API 也太丰富了吧,并且也太不好用了吧,所以我这脾气怎么能忍,当时就决定造新轮子。
我理解的单元测试功能,小项目友好的,能让你知道修改了代码后,是否还能正常运行就可以了,仅此而已,没有更多,那就开始介绍我的新坑吧, hi-test 单元测试库。
安装
$ npm install hi-test
项目 github 地址: github.com/wl879/hi-te…
API 我就不在这理堆列了,也没什么功能,直接介绍使用。
使用
0. 查看项目的API
$ hi-test scan <path>
这条命令会扫描目录中所有 js 文件的 exports, 并列出来,算是一个辅助功能
1. 开始写测试代码
var test = require('hi-test'); test('No.1', (t) => { setTimeout(() => { t.log('Hello, Iam No.1'); }, 1000); }); test('No.2', (t) => { t.log('Hello, Iam No.2'); });
输出: [Test 7956] No.1 at example/test_sync.js line 3:1 [Test log.] "Hello, Iam No.1" [Test DONE] No.1 (c13171) [Test d038] No.2 at example/test_sync.js line 9:1 [Test log.] "Hello, Iam No.2" [Test DONE] No.2 (e893ed)
这里的工作逻辑是,输出你想要测试的结果, t.log
不同于 console.log
输出,会更详细,还有 t.logp
会更详细一点,包括变量的类型也会有标注,所以代码的变化,例如类名称的改变也会影响输出结果,提示:如果变量中包含随机数或时间戳,会有点麻烦,原因请往下看。
这里还要特殊的说明一点,test 间是阻塞执行的,只有上一个 done
之后,后面的才会执行,而 t.done()
是可以自动调用的,是通过监听 process.on('beforeExit')
来实现,所以一般情况下可以不用手动调用,这样它会在对的时间点被调用。
还有一种情况,如果调用的 func 是 aync function
, 这将会在 func 结束时自动调用 t.done()
, 这种情况适用于以下例子:
var test = require('../')//.enable().enableGC(); let timing = setInterval(()=>{ console.log('Hi, See you again!'); }, 1000); test('start', 'e893ed', async (t) => { t.log('Hello, Start'); }); test('end', 'd41d8c', (t) => { clearInterval(timing); t.log('Hello, End'); starr);t}
例子中,如果不手动调用 t.done
,或用 async function
隐式调用,程序会一直的输出 See you again
。
如果你需要并行执行测试,可以这样写:
var test = require('hi-test'); test('No.1').run((t) => { setTimeout(() => { t.log('Hello, Iam No.1'); }, 1000); }); test('No.2').run((t) => { t.log('Hello, Iam No.2'); });
输出: [Test 7956] No.1 at example/test_async.js line 3:1 [Test d038] No.2 at example/test_async.js line 9:1 [Test log.] "Hello, Iam No.2" [Test log.] "Hello, Iam No.1" [Test DONE] No.1 (c13171) [Test DONE] No.2 (e893ed)
2. 如果输出是对的,还须要把 hash 码还给我
到这里,测试所写的代码以完成 99% 了,是不是没有那些 equal
/ deepEqual
的API,感觉不像测试的正确用法,是不是上当了,这不就是普通调试时写的代码吗,对与错,基本靠瞅。
是的,很可惜,还不够智能,第一次的输出只能靠瞅来判断对错,好在你只需要瞅一次,如果输出结果是对的,你还须要这样做。
var test = require('hi-test').enable();
再执行输出: [Test OK] No.1 (da9f9e) at example/test_sync.js line 3:1 [Test OK] No.2 (67319d) at example/test_sync.js line 9:1
开启 hi-test 后会有以下改变, 1.屏蔽掉无用的输出 。 2.自动添加 hash 码 。What?? 什么是 hash 码。
查看一下,上面的示例中的输出,在 [Test Done]...
那一行中,在 Title 后面会跟着一串 hash 码,这是由捕获到的输出生成的 md5 值, hi-test
也就是通过它来判断测试是否正确的。
如果程序正确,它的每次输出应该是一致的,所以反过来,通过判断两次输出是否一致,也就可以判断程序是否正确。当然这不能适用所有场景,但对于简单的测试还是基本靠谱的(相较于感人的测试代码量)。
手动添加 hash 码
var test = require('hi-test') test('No.1', 'da9f9e', (t)=>{ .... })
只需要将 hash 码做为第二个参数加到 test 函数中即可
筛选输出
每一个 test 的输出中,都会有一个标识,看这里
[Test 7956] No.1 at example/test_sync.js line 3:1
其中 7956
就是标识,它是由 md5(title) 得来的,所以当你只想查看某一项测试输出时,你可以用它来筛选,像这样
$ node ./test.js | grep '7956'
$ hi-test ./tset.js -df 'No.1'
3. 测试垃圾回收
这里有一个实用的小功能,可以测试某一个变量是否被回收
var test = require('hi-test').enableGC(); var num = [1, 2, 3]; test('CG', (t)=>{ t.gc(num, 'num'); // num = null; }); test('Next', (t) => { console.log(num); });
如果变量 num
被回收则输出
[Test GC ] [Yes] >> num
未被回收的话
[Test GC ] [No] >> num
4. 开始测试吧
最后介绍一下 hi-test 的命令行,直接看帮助
Usage: hi-test <files> [-d] [-a] [-f <title>] Options: +scan <path> Scan module exports -f, --filter <title> Filter the output -d, --debug Display all output -a, --auto Automation -v, --version Display version -h, --help Display help
在 package.json 中添加上这些一段
"scripts": { "test": "hi-test tests/test-*.js -a", }
收工!!
注:本文内容来自互联网,旨在为开发者提供分享、交流的平台。如有涉及文章版权等事宜,请你联系站长进行处理。