如何用 JavaScript 编写你的第一个单位测试

打印 上一主题 下一主题

主题 981|帖子 981|积分 2943



媒介

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

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


  • 验证功能:单位测试确保代码做正确的事情,不做不应该做的事情--这是大多数错误发生的地方。
  • 防止代码混乱:当我们发现一个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:
  1. const TrafficLight = require( "../traffic" );
复制代码
我们要用到测试的assert模块,因此也必要导入:
  1. 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会打印出单位测试运行的结果。

 添加更多单位测试
我们的项目现在已经准备好运行单位测试了,因此可以添加更多的单位测试,确保代码正确运行。
起首,添加一个单位测试到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类中有一个错误。

修复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类被重构或大量修改,我们的单位测试也会在它触达用户之前捕获这个错误。

 总结

单位测试很轻易设置,是软件开发的有效工具。它们有助于早期消除错误,并防止它们返回。这使项目更易于管理和维护,纵然它们变得更大和更复杂,特别是在更大的开发团队中。像如许的主动化测试也使开发人员可以或许重构和优化他们的代码,而不必担心新代码的行为是否正确。
单位测试是开发流程中的一个关键部分,对于帮助你构建更好、更安全的JavaScript应用至关紧张。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

小秦哥

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表