• 0
  • 0
分享
  • 如何用JavaScript编写你的第一个单元测试——软件测试圈
  • 饼干 2024-11-25 11:36:03 字数 4704 阅读 10 收藏 0

  前言

  测试代码是使代码安全的第一步。做到这一点的最好方法之一是使用单元测试,确保应用程序中的每个小功能都能发挥其应有的作用--特别是当应用程序处于边缘情况,比如无效的输入,或有潜在危害的输入。

  为什么要单元测试

  说到单元测试,有许多不同的方法。单元测试的一些主要目的是:

  验证功能:单元测试确保代码做正确的事情,不做不应该做的事情--这是大多数错误发生的地方。

  防止代码混乱:当我们发现一个bug时,添加一个单元测试来检查这个场景,可以保证代码的更改不会在将来重新引入这个bug。

  文档化代码:有了正确的单元测试,一套完整的测试和结果提供了一个应用程序应该如何运行的规范。

  代码更安全:单元测试可以检查可被利用的漏洞(比如那些可以实现恶意SQL注入的漏洞)。

  确定范围

  使用单元测试框架使我们能够快速编写和自动化我们的测试,并将它们集成到我们的开发和部署过程中。这些框架通常支持在前端和后端的JavaScript代码中进行测试。

  下面是一些帮助你编写性能单元测试和可测试代码的一般准则。

  保持简短

  不要让你的单元测试冗余。测试应该只有几行代码,检查应用程序的代码块。

  同时考虑正反面

  编写一个测试来确认一个函数的正确执行是有帮助的。然而,编写一套更广泛的测试,检查一个函数在被误用时或在边缘情况下是否会失败,会更有效果。这些负面测试甚至更有价值,因为它们有助于预测意外情况。例如一个函数什么时候应该抛出异常,或者它应该如何处理接收到的畸形数据。

  分解复杂功能

  含有大量逻辑的大型函数很难测试;包括太多的操作,无法有效测试每个变量。如果一个函数过于复杂,可以将其分割成较小的函数进行单独测试。

  避免网络和数据库连接

  单元测试应该快速且轻量,但是函数会发出网络请求,或者连接其他程序并花很长时间执行。这使得同时运行许多操作具有挑战性,并可能产生更脆弱的代码。你可以在单元测试中造假数据来实现模拟的网络或数据库调用,这可以让你测试函数的其余部分。你可以在不同的测试过程中包含真正的网络和数据库连接,这称为集成测试。

  如何编写单元测试

  现在,我们已经回顾了一些单元测试的最佳实践,你已经准备好在JavaScript中编写你的第一个单元测试。

  本教程使用了Mocha框架,它是最流行的单元测试之一。每个测试框架都略有不同,但足够相似,学习基本概念将使你能够在它们之间切换自如。

  要跟着示例,请确保电脑上已经安装了Node.js。

  创建新项目

  首先,打开终端窗口或命令提示符到一个新的项目文件夹。然后,通过输入npm init -y在其中创建一个新的Node.js项目。

  这会在文件夹内创建package.json文件,使你能够使用npm install -D mocha将Mocha安装为开发依赖。

  接着,在编辑器中打开package.json文件,用mocha替换占位符测试脚本:

  "scripts": {
      "test": "mocha"
   },

  实现一个类

  接下来,编写一个简单的交通灯系统,进行单元测试。

  在项目的目录内,创建traffic.js文件,并为TrafficLight类添加如下代码:

  class TrafficLight {
      constructor() {
          this.lightIndex = 0;
      }
      static get colors() {
          return [ "green", "yellow", "red" ];
      }
      get light() {
          return TrafficLight.colors[ this.lightIndex ];
      }
      next() {
          this.lightIndex++;
          // This is intentionally wrong!
          if( this.lightIndex > TrafficLight.colors.length ) {
              this.lightIndex = 0;
          }
      }
  }
  module.exports = TrafficLight;

  该类包含了四部分:

  · TrafficLight.colors:交通灯颜色的常量属性。

  · lightIndex:追踪当前交通灯颜色索引变量。

  · light:将当前交通灯颜色作为字符串返回的类的属性。

  · next():更改交通灯为下个颜色的函数。

  添加单元测试

  是时候为代码添加单元测试了。

  在项目的目录下创建名为test的文件夹。这里是Mocha默认检查单元测试的地方。在test文件夹下添加traffic.test.js文件。

  接着,在文件顶部导入TrafficLight:

  const TrafficLight = require( "../traffic" );

  我们要用到测试的assert模块,因此也需要导入:

  const assert = require( "assert" );

  在Mocha的帮助下,我们可以使用describe()函数将单元测试分组。因此我们可以为这个类设置一个顶级组,如下所示:

  describe( "TrafficLight", function () {
  });

  然后,我们在子组中添加校验交通灯颜色的单元测试,位于TrafficLight集合内部,并称为colors:

  describe( "TrafficLight", function () {
      describe( "colors", function () {
      });
  });

  对于第一个单元测试,我们可以检查colors仅有三个状态:绿色、黄色和红色。该测试在describe()组内部,使用it()函数定义。因此可以这样编写测试用例:

  describe( "TrafficLight", function () {
      describe( "colors", function () {
          it( "has 3 states", function () {
              const traffic = new TrafficLight();
              assert.equal( 3, TrafficLight.colors.length );
          });
      });
  });

  现在,让我们试着运行单元测试,看看是否可以通过。

  在终端窗口中运行npm test,如果一切正常,Mocha会打印出单元测试运行的结果。

1-1.png

  添加更多单元测试

  我们的项目现在已经准备好运行单元测试了,因此可以添加更多的单元测试,确保代码正确运行。

  首先,添加一个单元测试到colors组,验证交通信号灯的颜色是否正确,是否符合顺序。下面是实现测试的一种方式:

  it( "colors are in order", function () {
      const expectedLightOrder = [ "green", "yellow", "red" ];
      const traffic = new TrafficLight();
      for( let i = 0; i < expectedLightOrder.length; i++ ) {
          assert.equal( expectedLightOrder[ i ], TrafficLight.colors[ i ] );
      }
  });

  其次,测试next()函数,看看信号灯是否可以正确切换。创建一个新的子组,并添加两个单元测试:一个用来检查灯是否按顺序正确切换,另一个用来检查在循环到红色后是否返回到绿色。

  按照如下方式编写单元测试:

  describe( "next()", function () {
      it( "changes lights in order", function () {
          const traffic = new TrafficLight();
          for( let i = 0; i < TrafficLight.colors.length; i++ ) 
              assert.equal( traffic.light, TrafficLight.colors[ i ] );
              traffic.next();
          }
      });
      it( "loops back to green", function () {
          const traffic = new TrafficLight();
          // Change the light 3x to go from green -> yellow -> red -> green
          for( let i = 0; i < 3; i++ ) {
              traffic.next();
          }
          assert.equal( traffic.light, TrafficLight.colors[ 0 ] );
      });
  });

  现在,当我们重新运行测试时,我们会看到其中一个测试失败了。这是因为TrafficLight类中有一个错误。

1-2.png

  修复bug

  再次打开TrafficLight类的代码,找到next()函数内的注释,其内容为// This is intentionally wrong!。

  从我们的单元测试中,我们知道这个函数没有正确地返回到绿色。我们可以看到,目前的代码在lightIndex值超过交通灯颜色的数量时进行检查,但索引是从0开始的。相反,我们必须在该索引值达到颜色数量时返回到绿色。让我们更新代码,当lightIndex值等于交通灯颜色列表的长度时,将其重置为0:

  // This is intentionally wrong!
  if( this.lightIndex === TrafficLight.colors.length ) {
      this.lightIndex = 0;
  }

  现在你所有的单元测试都应该通过。最重要的是,即使TrafficLight类被重构或大量修改,我们的单元测试也会在它触达用户之前捕获这个错误。

1-3.png

  总结

  单元测试很容易设置,是软件开发的有效工具。它们有助于早期消除错误,并防止它们返回。这使项目更易于管理和维护,即使它们变得更大和更复杂,特别是在更大的开发团队中。像这样的自动化测试也使开发人员能够重构和优化他们的代码,而不必担心新代码的行为是否正确。

  单元测试是开发流程中的一个关键部分,对于帮助你构建更好、更安全的JavaScript应用至关重要。


作者:chuckQu    

来源:http://www.51testing.com/html/26/n-7795026.html

  • 【留下美好印记】
    赞赏支持
登录 后发表评论
+ 关注

热门文章

    最新讲堂

      • 推荐阅读
      • 换一换
          • 现在docker分布式部署的的方式是非常流行的,开发将新版本整体打包好之后丢给测试人员,测试人员便可以在测试环境部署新版本了,其实部署安装也是测试内容之一,这个步骤是完全模拟了运维人员在客户那边部署的操作,如果这个时候出什么问题,开发还可以进行解决或者兼容,下面就先罗列一下docker部署常用的命令:# 创建一个名为myubuntu的容器# -t:分配一个伪终端  -i:让容器的标准输入保持打开$ docker run --name=myubuntu -t -i ubuntu /bin...
            1 0 2753
            分享
          • 1.编写测试用例有哪几种方法?答:大刚法、等价类、边界值、因果图、场景法、正交法、错误推断法、正则表达式2.测试的六条基本法则是什么?答:功能、可靠性、易用性、效率、可维护性、可移植性3.软件测试分类有哪些?(从是否关心软件内部结构的角度划分)答:白盒、灰盒、黑盒4.软件测试的测试流程是什么?答:分析需求文档-需求评审-编写测试计划-计划评审-编写测试用例-用例评审-执行测试用例-迭代测试轮次-提交阶段性测试报告-验收测试-提交测试总结性报告5.编写测试用例的原则是什么?答:100%的覆盖需求规格说明书6.软件测试过程中必须经历哪些阶段?答:单元测试集成测试系统测试验收测试7.黑盒测试包含哪些...
            13 15 13280
            分享
          • 软件测试职业发展方向,大体上可以分为管理路线、技术路线、管理+技术路线。软件测试,是技术主导的职业;不管选择哪条发展路线,都是需要一定的技术沉淀,只是相对来说,管理路线对技术方面要求不高而已。那么我们就先挑重头的技术路线展开讨论。一般来说,一个普通的测试工程师刚入行,3个月左右熟悉企业的工作流程和模式,那么今后的工作内容趋于平稳。然而社会是残酷的!如果单单停留在测试工程师的阶段,若干年后,相信你再也竞争不过那个时候的应届毕业生,当你的工作技能和职业素质趋于与那些朝气蓬勃的年轻人相当时,企业会毫不留情的选择他们,而release你,因为你的成本消耗要比他们高,这是大实话!然而现实又是公平的!因为...
            15 15 1286
            分享
          • 前言现在很多公司写后端代码和前端代码已经分工很明确了,前后端把接口定义好,然后各自写各自的代码就可以了。那么对于服务端的开发人员来说,写好了代码后,对外提供了API,这时候没有页面可以调用调试,如果等着客户端写完代码再测试的话,那样工作的效率是及其低下的。那么服务端要学会模拟客户端的调用,来调试自己的代码,提早发现问题,这样后续跟客户端进行联调的时候,就大大提高了效率。我们今天讲讲Postman模拟客户端调试工具,这是我平时工作中最常用的工具之一。Postman是一款功能强大的网页调试与发送网页HTTP请求的Chrome插件。它只要在Chrome里安装一个插件即可完成强大的功能。但是由于201...
            0 0 1050
            分享
          • selenium的安装当前确保系统已经装了Python和pip检查方法:python检查 : cmd进入直接输入Python,回车可以系统会给出当前系统已经装好的Python版本号等相关信息,pip查看:cmd进入系统输入pip -version回车系统会给出已经装好的pip 版本相关信息,安装selenium,进入cmd,输入pip install selenium开始安装(这里强烈推荐pip安装,如果不懂没装pip或不懂pip安装请自行查找信息)查看Chrome浏览器版本,打开Chrome浏览器,搜索框输入Chrome://version即可查看本机装的Chrome浏览器版本的详细信息下载...
            0 0 1416
            分享
      • 51testing软件测试圈微信