前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >手把手,带你编写你的第一个单元测试

手把手,带你编写你的第一个单元测试

原创
作者头像
zayyo
发布2023-11-14 21:30:49
1720
发布2023-11-14 21:30:49
举报
文章被收录于专栏:zayyo前端zayyo前端

相信有很多人遇到过这种情况,就是在入职公司后,开始接手公司的老项目,给公司的老项目修修改改。当我们在一个系统里边修改了很多代码时,但又不确定改动是否影响在核心逻辑时,是否会导致项目原来的功能出现bug时。我们就可以使用单元测试来帮助我们来进行测试。所以软件开发者编写单元测试,就成了很重要的事情。

那我们为什么要编写单元测试? 单元测试的优点是什么?

  • 必要性:JavaScript 缺少类型检查,编译期间无法定位到错误,单元测试可以帮助你测试多种异常情况。(现在可以使用TypeScript来弥补类型检查的缺点)。
  • 验证功能:单元测试可以确保我们的代码正常运行,并且不出现异常输出以及副作用————这是很多bug产生的原因。
  • 防止错误再次发生:当我们发现错误时,添加单元测试来检查场景错误,可以防止代码在后期重构和优化中错误的再次发生。
  • 自动化、效率高:通过 console 虽然可以打印出内部信息来检查错误。但是这是效率十分低的操作,;每次测试都得打印一次,效率不能得到保证。通过编写测试用例,可以做到一次编写,多次自动运行,效率高。
  • 保护您的应用程序:单元测试可以检查可利用的漏洞(例如启用恶意 SQL 注入的漏洞用来检查代码的可靠性)。
  • 更利于后期代码的维护:互联网行业产品迭代速度很快,迭代后必然存在代码重构的过程,那怎么才能保证重构后代码的质量呢?有测试用例做后盾,就可以大胆的进行重构。

编写单元测试的一些规范

单元测试框架的使用,让我们能够快速编写和自动执行我们的测试,并且将它们集成到我们的开发和部署过程中。

以下是一些常见编写测试的规范。

保持单元测试的功能单一和代码简洁

不要让你的单元测试过于复杂,本末倒置。尽量让你的单元测试代码简单明了,责任单一。

全面的考虑函数运行的结果

我们不仅仅要考虑函数正常运行时的情况,还要考虑函数错误运行时的情况。对代码进行单元测试,我们不仅仅要确保函数在输入正确的值时,有正确的输出,还要确保函数在输入错误参数时,运行的结果是失败的。这些对错误的检查更有利于我们预测引发错误的原因以及场景。

拆分复杂的函数

对功能逻辑复杂的函数,编写单元测试是十分困难的。我们要把复杂的函数拆分为相对较小的函数来进行单元测试。

避免测试时涉及数据的请求(数据库and网络请求)

单元测试应该是快速和轻量级的。但如果测试过程中涉及到网络数据的请求,或者对数据库的操作这就需要很长的时间来进行响应。这会使我们的单元测试变得很臃肿和重量级。但如果无法避免数据请求的话,我们一般会模拟请求结果来减轻我们的测试压力。

如何编写单元测试

现在我们都已经对单元测试有了一定的了解了,那我们就着手开始编写我们的第一个单元测吧!!!

这次我将带着大家使用Mocha框架--市面上比较主流的测试框架之一。来编写我们的单元测试,虽然市面上每个框架都不同,但是他们大体是相似的。只要我们掌握了其中一种框架,其他的框架也能够很快的上手。

在编写单元测试之前,请确保你的电脑上已经安装的Node.JS环境。因为我们的Mocha是运行在node环境下的。所以我默认你的node环境已经安装好了。

创建一个新的项目

首先创建了一个新的文件夹(必须是以英文命名) ,然后在文件夹里打开你的终端窗口或命令行窗口。然后输入npm init?-y

然后你的项目里面就会生成一个package.json文件

(我这里文件夹命名为UNIT-TEST)

然后我们就可以再在我们的项目里面安装Moche框架了。在我们的终端窗口输入我们的npm install?-D?mocha命令(如果安装速度慢的建议用cnpm)

然后打开我们的package.json文件,把脚本里的test命令修改成mocha

编写我们的被测试文件

这里我们编写一个简单的红绿灯系统,来用于我们待会的单元测试。

我们在项目中创建我们traffic,js文件以及编写我们的TrafficLight

代码语言:javascript
复制
class TrafficLight {

  constructor() {
    // 对所有实例的lightIndex都赋值为0
    this.lightIndex = 0;
  }
  // 定义我们的静态函数colors,只要一调用就返回函数
  static get colors () {
    return ["green", "yellow", "red"];
  }
  get light () {
    return TrafficLight.colors[this.lightIndex];
  }

  next () {
    this.lightIndex++;
    // 这里故意设置了一个错误,this.lightIndex为3时是?developer/article/2358353/undefined
    if (this.lightIndex > TrafficLight.colors.length) {
      this.lightIndex = 0;
    }
  }
}

module.exports = TrafficLight;

这个class由4部分组成

TrafficLight.colors:一个关于交通灯的颜色的数组常量。

lightIndex:一个指示当前交通灯颜色的Index的变量。

light():一个返回当前交通灯颜色的函数。

next():一个改变当前交通灯颜色的函数,使交通灯指向下一个颜色。

接下来开始着手编写我们的第一个变量

首先,在项目文件夹中创建一个名为test的文件夹。testMocha默认存放单元测试代码的文件夹。然后我们在test项目下再新建一个traffic.test.js文件来编写我们的单元测试

接下来开始编写我们的traffic.test.js单元测试,首先导入我们的被测试的TrafficLight模块。

代码语言:javascript
复制
const TrafficLight = require( "../traffic" );

我们还需要在代码中使用assert模块进行测试,所以我们要导入assert模块

代码语言:javascript
复制
const assert = require( "assert" );

Mocha中我们可以使用describe()函数来帮我们进行单元测试的分组。所以我们应该先定义一个顶层分组。

代码语言:javascript
复制
describe( "TrafficLight", function () { 
});

然后我们就可以在这个分组下进行一些子功能的测试定义与分组。首先我们先定义一个对colors的测试。看colors是否和我们预期的相同。

代码语言:javascript
复制
describe( "TrafficLight", function () { 
    describe( "colors", function () {
        //测试内容
    });
});

我们默认交通灯的colors只是三种颜色green、yellow、red。所以我们可以去验证它的长度是否符合我们的要求。我们需要用到Mocha框架里定义的it()函数语法。它要编写在describe()函数里。

代码语言:javascript
复制
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分组中添加一个对红绿灯颜色顺序是否正确的测试。

代码语言:javascript
复制
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()函数进行测试,看他是否可能正确的改变红绿灯的颜色,使其按照正确的顺序执行。对next()的测试不应该属于color分组。所以我们应该为它新建一个分组。并且在这个分组里编写两个测试,一个是测试交通灯的颜色是否按正确的顺序改变,一个是测试交通灯是否可以正确的循环执行。

代码语言:javascript
复制
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();
        // 颜色变化的循环顺序是 green -> yellow -> red -> green
        for( let i = 0; i < 3; i++ ) {
            traffic.next();
        }
        assert.equal( traffic.light, TrafficLight.colors[ 0 ] );
    });
});

当我们运行单元测试时,我们可以看到有一个测试失败的提示。这因为我们在编写TrafficLight类时,故意设置的一个错误,当this.lightIndex为3时结果是?developer/article/2358353/undefined。无法正确循环执行从red回到green

代码语言:javascript
复制
  next () {
    this.lightIndex++;
    // 这里故意设置了一个错误,this.lightIndex为3时是?developer/article/2358353/undefined
    if (this.lightIndex > TrafficLight.colors.length) {
      this.lightIndex = 0;
    }

那么其实修改这个错误也十分简单,我们只需要把我们的>改为===,当lightIndex的值超过我们的color数组长度时,它就会自动被赋值为0,回到初始值。这样就可以使我们的代码正常执行。

代码语言:javascript
复制
if( this.lightIndex === TrafficLight.colors.length ){ 
    this.lightIndex = 0; 
}

总结

单元测试的编写是比较简单的,它是提高我们软件开发的工具。它的使用有助于帮我更早的发现错误。并防止我们后期重构代码时再次产生同样的错误。它可以让我们的项目后期更易于管理和维护,即使我们的项目代码体积结构变得更大更复杂——尤其是在更大的开发团队中。而且自动化单元测试还能够让开发人员在够重构和优化代码时,不必担心新代码的是否会影响旧的功能。

单元测试是开发过程的关键部分,对于帮助您构建更好、更安全的 JavaScript 应用程序至关重要。?

我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 那我们为什么要编写单元测试? 单元测试的优点是什么?
  • 编写单元测试的一些规范
    • 保持单元测试的功能单一和代码简洁
      • 全面的考虑函数运行的结果
        • 拆分复杂的函数
          • 避免测试时涉及数据的请求(数据库and网络请求)
          • 如何编写单元测试
            • 创建一个新的项目
              • 编写我们的被测试文件
                • 这个class由4部分组成
                  • 接下来开始着手编写我们的第一个变量
                    • 编写更多的单元测试
                      • 总结
                      领券
                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
                      http://www.vxiaotou.com