前几天写了一篇博客:《使用 JavaScript 批量获取微博评论》 。今天我们来学习如何测试我们之前编写的代码。从本质上来说,我们今天要学习的是如何测试 DOM 操作类的 JS 代码。你可以在这里获取测试代码:
https://github.com/lewis617/practical-js/blob/master/src/weiboBackup.test.js
选择测试框架 我使用过很多测试框架,比如 Karma、Mocha、Jest 等,但因为对 Facebook 开源项目的偏爱,我选择了 Jest 来测试,事实证明,Jest 确实最为简单,无需进行繁琐的浏览器环境模拟,就可以直接使用浏览器环境的各种 API,让我们一睹为快!不过先安装 Jest:
处理被测试文件 被测试文件原来是这样的:
weiboBackup.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 var nodeArray = Array .from (document .querySelectorAll ('.list_con .WB_text' ));var textArray = nodeArray.map (function (node ) { return Array .from (node.childNodes ).map (function (childNode ) { var value; if (childNode.nodeName === '#text' ) value = childNode.nodeValue ; else if (childNode.nodeName === 'IMG' ) value = childNode.alt ; else if (childNode.nodeName === 'A' ) value = childNode.lastChild .nodeValue ; return value.replace (/(\s+$)|(^\s+)/g , '' ); }).join ('' ); }); console .log (textArray.join ('\n' ));
为了方便测试,我们在底部添加一行代码,将其导出,方便测试。另外,为了让测试报告更纯净,我们把 console 注释掉:
1 2 3 4 module .exports = textArray;
编写测试文件 前面说了 Jest 自带浏览器模拟环境,无需手动配置。所以我们直接添加用于测试的 html 即可:
这段 html 字符串相当于模拟数据,即假数据。在这里,相当于模拟一个微博评论。模拟数据你可以随意编写,但是通常需要和真实数据保持结构和规律上的一致,而且需要覆盖所有的情况,这样才能测试到所有的边界。
weiboBackup.test.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 document .body .innerHTML = '\ <div class="list_con">\ <div class="WB_text">\ <a target="_blank" href="//weibo.com/2809324184" usercard="id=2809324184">Geo橙子</a>:在过一阵子是不是要翻成英文,走出国门了\ </div>\ <div class="WB_text">\ <a target="_blank" href="//weibo.com/2497287343" usercard="id=2497287343">dev_zk</a>\ <a target="_blank" suda-data="key=pc_apply_entry&value=feed_icon" href="http://club.weibo.com/intro">\ <i title="微博达人" class="W_icon icon_club" node-type="daren"></i>\ </a>\ :现在好了\ <img render="ext" src="//img.t.sinajs.cn/t4/appstyle/expression/ext/normal/58/mb_org.gif" title="[太开心]" alt="[太开心]" type="face">\ <img render="ext" src="//img.t.sinajs.cn/t4/appstyle/expression/ext/normal/58/mb_org.gif" title="[太开心]" alt="[太开心]" type="face">\ </div>\ <div class="WB_text">\ <a target="_blank" href="//weibo.com/2497287343" usercard="id=2497287343">dev_zk</a>\ <a target="_blank" suda-data="key=pc_apply_entry&value=feed_icon" href="http://club.weibo.com/intro">\ <i title="微博达人" class="W_icon icon_club" node-type="daren"></i>\ </a>\ :哈哈\ </div>\ </div>' ;
然后直接调用被测试文件 weiboBackup.js,相当于运行了它:
1 var textArray = require ('./weiboBackup' );
现在评论文本已经被保存到数组 textArray
中了,然后我们直接编写断言即可:
1 2 3 4 5 expect (textArray).toEqual ([ "Geo橙子:在过一阵子是不是要翻成英文,走出国门了" , "dev_zk:现在好了[太开心][太开心]" , "dev_zk:哈哈" , ]);
关于断言等测试的基础知识,如果你不了解,请看我之前写的 《Jest 单元测试入门》 。
最后我们将上述代码包在 test
函数中,这个函数用于打包一个测试用例,并附带测试用例说明:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 test ('getweiboBackup' , () => { document .body .innerHTML = '\ <div class="list_con">\ <div class="WB_text">\ <a target="_blank" href="//weibo.com/2809324184" usercard="id=2809324184">Geo橙子</a>:在过一阵子是不是要翻成英文,走出国门了\ </div>\ <div class="WB_text">\ <a target="_blank" href="//weibo.com/2497287343" usercard="id=2497287343">dev_zk</a>\ <a target="_blank" suda-data="key=pc_apply_entry&value=feed_icon" href="http://club.weibo.com/intro">\ <i title="微博达人" class="W_icon icon_club" node-type="daren"></i>\ </a>\ :现在好了\ <img render="ext" src="//img.t.sinajs.cn/t4/appstyle/expression/ext/normal/58/mb_org.gif" title="[太开心]" alt="[太开心]" type="face">\ <img render="ext" src="//img.t.sinajs.cn/t4/appstyle/expression/ext/normal/58/mb_org.gif" title="[太开心]" alt="[太开心]" type="face">\ </div>\ <div class="WB_text">\ <a target="_blank" href="//weibo.com/2497287343" usercard="id=2497287343">dev_zk</a>\ <a target="_blank" suda-data="key=pc_apply_entry&value=feed_icon" href="http://club.weibo.com/intro">\ <i title="微博达人" class="W_icon icon_club" node-type="daren"></i>\ </a>\ :哈哈\ </div>\ </div>' ; var textArray = require ('./weiboBackup' ); expect (textArray).toEqual ([ "Geo橙子:在过一阵子是不是要翻成英文,走出国门了" , "dev_zk:现在好了[太开心][太开心]" , "dev_zk:哈哈" , ]); });
运行测试 测试文件写好了,我们需要运行它,首先在 package.json 中添加:
1 2 3 "scripts" : { "test" : "jest" }
然后在命令行中运行:
最后就会看测试报告了:
1 2 3 4 5 6 7 PASS ./weiboBackup.test.js ✓ getweiboBackup (27ms) Test Suites: 1 passed, 1 total Tests: 1 passed, 1 total Snapshots: 0 total Time: 0.907s, estimated 1s
尝试改变 html 中的测试文本,或断言中的预期文本,看看预期与结果不一致的情况。比如,将断言改为:
1 expect (textArray).toEqual ([]);
结果测试报告变为这样:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 FAIL ./weiboBackup.test.js ✕ getweiboBackup (310ms) ● getweiboBackup expect(received).toEqual(expected) Expected value to equal: [] Received: ["Geo橙子:在过一阵子是不是要翻成英文,走出国门了" , "dev_zk:现在好了[太开心][太开心]" , "dev_zk:哈哈" ] Difference: - Expected + Received - Array [] + Array [ + "Geo橙子:在过一阵子是不是要翻成英文,走出国门了" , + "dev_zk:现在好了[太开心][太开心]" , + "dev_zk:哈哈" , + ] at Object.<anonymous>.test (weiboBackup.test.js:25:21) at new Promise (<anonymous>) at <anonymous> at process._tickCallback (internal/process/next_tick.js:188:7) Test Suites: 1 failed, 1 total Tests: 1 failed, 1 total Snapshots: 0 total Time: 0.897s, estimated 1s Ran all test suites. npm ERR! Test failed. See above for more details.
总结 编写测试还是很重要的,可以保证你的代码质量,而你的代码质量关系到你的 KPI,所以我建议大家还是养成编写测试的好习惯。
发布时间:
2017年11月9日 - 11时11分