11月阅读周·编写可测试的JavaScript代码:单元测试之编写测试篇

举报
叶一一 发表于 2024/11/21 18:32:31 2024/11/21
【摘要】 背景去年下半年,我在微信书架里加入了许多技术书籍,各种类别的都有,断断续续的读了一部分。没有计划的阅读,收效甚微。新年伊始,我准备尝试一下其他方式,比如阅读周。每月抽出1~2个非连续周,完整阅读一本书籍。这个“玩法”虽然常见且板正,但是有效,已经坚持阅读十个月。已读完书籍:《架构简洁之道》、《深入浅出的Node.js》、《你不知道的JavaScript(上卷)》、《你不知道的JavaScri...

背景

去年下半年,我在微信书架里加入了许多技术书籍,各种类别的都有,断断续续的读了一部分。

没有计划的阅读,收效甚微。

新年伊始,我准备尝试一下其他方式,比如阅读周。每月抽出1~2个非连续周,完整阅读一本书籍。

这个“玩法”虽然常见且板正,但是有效,已经坚持阅读十个月。

已读完书籍《架构简洁之道》、《深入浅出的Node.js》、《你不知道的JavaScript(上卷)》、《你不知道的JavaScript(中卷)》、《你不知道的JavaScript(下卷)》、《数据结构与算法JavaScript描述》、《WebKit技术内幕》、《前端架构:从入门到微前端》、《秒懂算法:用常识解读数据结构与算法》、《JavaScript权威指南》、《JavaScript异步编程设计快速响应的网络应用》

当前阅读周书籍编写可测试的JavaScript代码

编写测试

必须编写单元测试了,所以停止空想,开始实战。以如下代码作为开始:

function sum(a, b) {
  return a + b;
}

单元测试只关注隔离代码的测试,并且只对被测试的代码块进行测试编写。听上去很简单,像上述代码中的sum函数的确很简单:

YUI({
  logInClude: { testRunner: true },
}).use('test', 'test-console', function (Y) {
  var testCase = new Y.test.case({
    name: 'Sum Test',
    testSimple: function () {
      Y.Assert.areSame(sum(2, 2), 4, '2+2 does not equal 4?');
    },
  });
  // load it up
  Y.Test.Runner.add(testCase);
  new Y.Test.Console({
    newestOnTop: false,
  }).render('#log');
  // Run it
  Y.Test.Runner.run();
});

这是最简单的测试用例,所以要确保可以理解它。创建一个新的Y.Test.Case,并提供一个名称和一组测试函数。每个函数都运行在假设条件中:一个或多个Y.Assert函数被调用,并对实际结果进行测试。测试用例被加载到局部Y.Test.Runner中,然后执行所有的测试。
对给定的代码进行测试,依然达不到效果,因为我们需要实际运行测试并查看结果。在一些服务器端测试框架(如Vows)中,测试完服务器端代码之后就结束了,但对于客户端JavaScript,其需要和HTML文件绑定在一起:

<html>
  <head>
    <title>sum tests</title>
  </head>
  <body>
    <div id="log" class="yui3-skin-sam"></div>
    <script src="http://yui.yahooapis.com/3.7.3/build/yui/yui-min.js"></script>
    <script src="sum.js"></script>
    <script src="sumtests.js"></script>
  </body>
</html>

上述HTML试图将YUI3 Test和被测试的代码以及测试代码联系在一起。在浏览器中加载该HTML,将会执行所有的测试并将测试结果输出到<div>里。其表示了客户端单元测试所需要的必要部分:被测代码、测试代码以及将其联系在一起的HTML。

还是有一些内容遗忘了——即代码覆盖率和命令行式的测试执行。我们只能稍后重新审视这些内容了;首先,我们必须确定如何编写好的测试。还好,后面我们还会将这部分内容补充进来,但是,现在让我们先专注于测试本身。

可惜的是,我们很少要求测试像sum这样没有副作用(side effect)的函数,这种函数的返回值只依赖于函数参数。但是,即便是这样一个简单的sum函数,如果传了两个字符串进去,会发生什么结果?如果它的参数是一个字符串和一个整数,其结果又如何?同理,传null、undefined或者NaN值时,结果又怎么样?即便最简单的函数,也需要一些测试进行真正的运行验证。

更糟糕的是,对于单一单元测试度量,代码覆盖率,可以轻易从单一单元测试中得出100%的代码覆盖率报告。很明显,单一测试并不是函数的有效测试,但管理器可能会通过代码覆盖率报告得出错误的结论,因为该函数100%的代码覆盖率,使得人们以为进行了充分测试并且是可靠的。单元测试提供了价值,而代码覆盖率在某种程度上可以衡量该价值,当然,它们不能,也不可能完成整件事情。

总结

必须编写单元测试了,所以停止空想,开始实战。

怎样编写一个好的单元测试?下一篇我将介绍如何编写好的单元测试。


作者介绍
非职业「传道授业解惑」的开发者叶一一。
《趣学前端》、《CSS畅想》等系列作者。华夏美食、国漫、古风重度爱好者,刑侦、无限流小说初级玩家。
如果看完文章有所收获,欢迎点赞👍 | 收藏️ | 留言📝

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。