`

mocha、chai、sinon和istanbul实现100%单元测试覆盖率

阅读更多

敏捷软件开发中,最重要实践的就是测试驱动开发,在单元测试层面,我们试着实现一个重要的指标就是测试覆盖率。测试覆盖率衡量我们的代码是否已经全部被测试到了。

但是指标本身不是目的,借助测试覆盖率检查,我们希望发现那些未被测试覆盖的代码,从而去思考如何测试那些代码的逻辑,进而更好的设计重构代码,让代码有更高的质量。

谈到测试,正好最近在看《数学之美》,书中谈到的关于信息的一段话。我们要把代码的行为从不确定性,变成确定性,也是一样。从黑盒变成白盒,没有什么神奇的力量,唯有提供足够的信息,而测试中的断言就是信息,测试覆盖率也是信息,测试覆盖率可以认为是一种间接的信息,可以消除一部分不确定性,而充分的断言,则提供了更直接的信息。加上测试覆盖率检查,就能够提供足够的信息,来断言代码的行为是否符合期望。

测试的相关技术

IstanbulJavaScript程序的代码覆盖率工具,以土耳其最大城市伊斯坦布尔命名。Istanbul会对代码进行转换,生成语法树,然后在相应位置注入统计代码,执行之后根据注入的全局变量的值,统计代码执行的次数;在对代码的转换完成之后,Istanbul会调用test runner,例如mocha,执行转换之后的代码的测试,生成测试报告。

Mocha是一种测试框架,也就是运行测试的工具,类似Jasmine、Karma和Ava。跟JUnit的注解一样,mocha作为执行器,用descibeit方法,来定义test suit,为不同的测试分组。mocha本身并不提供assert断言,所以要提供更加有表现力的断言,可以搭配chai使用,当然也可以使用nodejs提供的assert模块

在我们的代码中,总会有一些复杂的逻辑或者依赖io、网络的异步代码,用直接的方法难以测试,这时可以通过sinon简化复杂代码的测试。Sinon通过创建Test Double也就是测试替身,将我们代码中依赖的一些函数或者类,替换成测试替身,而我们可以对测试替身的行为进行设置,模拟我们的代码需要的结果,从而让难以测试的代码逻辑被执行。

为nodejs项目配置测试环境

1 安装相应的依赖包

mocha和istanbul可以全局安装,也可以只在当前项目安装。

npm install --save-dev mocha chai sinon istanbul

安装完成之后,在package.json文件的scripts下,添加执行测试和测试覆盖率检查的命令

{
  ...
  "scripts":{
    "coverage": "istanbul cover _mocha -- -R spec --timeout 5000 --recursive",
    "coverage:check": "istanbul check-coverage",
  }
  ...
}

运行npm run coveragenpm run coverage:check,就可以生成测试报告,前者生成测试报告,后者则是检查测试覆盖率是否达到要求。

<iframe id="iframe_0.48200238053686917" style="margin: 0px; padding: 0px; border-style: none; width: 592px; height: 289px;" src="data:text/html;charset=utf8,%3Cstyle%3Ebody%7Bmargin:0;padding:0%7D%3C/style%3E%3Cimg%20id=%22img%22%20src=%22http://upload-images.jianshu.io/upload_images/1400900-2fd5d2f1edc17fd6.png?imageMogr2/auto-orient/strip%257CimageView2/2/w/1240&amp;_=7146503%22%20style=%22border:none;max-width:669px%22%3E%3Cscript%3Ewindow.onload%20=%20function%20()%20%7Bvar%20img%20=%20document.getElementById('img');%20window.parent.postMessage(%7BiframeId:'iframe_0.48200238053686917',width:img.width,height:img.height%7D,%20'http://www.cnblogs.com');%7D%3C/script%3E" frameborder="0" scrolling="no"></iframe>

2 配置Istanbul

istanbul相关的执行参数,可以在命令行下执行时传递参数来制定,也可以在yaml格式的.istanbul.yml文件中配置。简单贴出一些重要的配置项

instrumentation:
  root: .   # 执行的根目录
  extensions:
    - .js   # 检查覆盖率的文件扩张名
  excludes: ['**/benchmark/**']

  ... ...

reporting:
  print: summary
  reports: [lcov, text, html, text-summary] # 生成报告的格式
  dir: ./coverage   # 生成报告保存的目录
  watermarks:       # 在不同覆盖率下会显示使用不同颜色
    statements: [80, 95]
    ... ...
check:
  global:
    statements: 100
    branches: 100
    lines: 100
    functions: 100

最后的check是项目要通过覆盖率检查需要达到的测试覆盖率,测试覆盖率包括四个维度,分别是语句覆盖率、分支覆盖率、行覆盖率和函数覆盖率。如果达不到设定的指标,在执行的时候会报错,项目的测试就无法通过自动化的持续集成。

编写测试代码

敏捷软件开发中的测试驱动开发,意在通过先写测试,根据调用者的契约,设计如何实现代码,从而写出更加容易测试的代码,提高代码的质量。也是我们练习测试的应该考虑的方向。

1 一段简单的mocha测试代码

利用chai提供的expect断言,我们可以用BDD的方式,写出更加符合代码预期行为的测试用例。

var chai = require('chai')

chai.should()
var expect = chai.expect
var assert = chai.assert

describe('basic test', function () {
  describe('simple', function () {
    it('data check', function () {
      var data = { name: "test" }

      assert.isNotNull(data, 'data should not be null')
      expect(data).to.be.an('object')
      expect(data).to.have.all.keys(['name'])
      expect(data).to.deep.include({name: 'test'});
    });
  });
});

2 用Sinon模拟文件读写

... 同上 ...
var sinon = require('sinon')
var fs = require('fs')

describe('sinon', function () {
  it("should mock readFile", function(done){
    sinon.stub(fs, 'readFile').callsFake(function (path, callback) { callback(new Error('read error')) })

    fs.readFile("any file path", function(err,data){
      assert.isNotNull(err)
      done()
    })
    assert(fs.readFile.calledOnce)
  });
});

在mocha测试框架中,如果我们调用的是异步的代码,那么需要显示的调用it回调函数的done方法,告诉mocha异步调用什么时候结束。否则的话,测试会挂起,直到设置的超时时间结束。

Sinon将测试替身分为spy、stub和mock,其中:

  • Spy, 可以提供函数调用的信息,但不会改变函数的行为
  • Stub, 提供函数的调用信息,并且可以像示例代码中一样,让被stubbed的函数返回任何我们需要的行为。
  • Mock, 通过组合spies和stubs,使替换一个完整对象更容易。

本文的讨论篇幅有限,暂时不详细介绍各种sinon的使用方法,以后再通过其他文章专门介绍。

持续集成

完成所有代码之后,我们可以将代码发布到github,然后使用持续集成工具travis检查代码,将生成的测试报告上传到coverall上,这样就可以在项目中显示项目状态和测试覆盖率的badges。

具体使用方法,可以参看官方网站,使用coveralls需要在项目中安装依赖包npm i -D coveralls。并且添加package.json执行脚本istanbul cover ./node_modules/mocha/bin/_mocha --report lcovonly -- -R spec && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js

通常的nodejs项目.travis.yml配置如下:

language: node_js
node_js:
  - "7.6.0"
install:
  - npm install
script:
  - npm test
after_script:
  - npm run coverall

 

 

原文地址:http://www.51test.space/archives/2543

更多软件测试相关信息: www.51test.space
欢迎关注公众号 
分享到:
评论

相关推荐

    Testing-with-Mocha-Chai-and-Sinon

    在这个项目中,我们关注的是JavaScript生态系统中的三个关键工具:Mocha、Chai和Sinon,它们是用于编写单元测试、集成测试以及模拟函数的强大工具。 **Mocha** 是一个流行的JavaScript测试框架,它提供了灵活的结构...

    前端项目-sinon.js.zip

    Sinon.js 可以与诸如Istanbul之类的代码覆盖率工具配合使用,帮助开发者了解测试覆盖了多少代码行,从而发现可能未被测试的角落。 5. **集成测试框架** Sinon.js 与其他前端测试框架如Mocha、Jasmine、Chai等兼容...

    mocha-portfolio:这是一个演示使用 Mocha 和 Chai 测试前端 JavaScript 的应用程序

    5. **测试覆盖率**:为了确保测试的全面性,可以集成Istanbul这样的工具来计算测试覆盖率,帮助识别未被测试到的代码。 6. **自定义报告器**:Mocha允许自定义报告器,可以根据需要生成不同格式的测试结果,比如...

    mochaTesting:用 mocha 和 chai 学习 Javascript

    除了基本的断言,Mocha 和 Chai 还支持异步测试、模拟函数(sinon)、覆盖率报告(istanbul)等高级特性。异步测试可以通过在测试用例中返回一个 Promise 或使用 `done` 回调来实现。模拟函数可以用来隔离和控制依赖...

    前端开源库-cake-mocha

    4. **测试覆盖率**:结合Istanbul这样的工具,你可以生成测试覆盖率报告,了解代码的测试覆盖情况。 5. **集成持续集成**:将Cake和Mocha的测试流程集成到CI/CD工具(如Jenkins、Travis CI或GitHub Actions)中,...

    mocha-example:使用 mocha、grunt 和 node 模块进行单元测试的示例

    - **覆盖率报告**:可结合 Istanbul 等工具生成代码覆盖率报告,了解测试的覆盖情况。 - **持续集成**:将测试集成到持续集成(CI)流程,如 Jenkins、Travis CI 或 GitHub Actions,确保每次代码提交都通过测试。 ...

    JavaScript_快速,简单和可靠的测试任何在浏览器中运行.zip

    8. **测试覆盖率**:测试覆盖率工具,如Istanbul,可以帮助开发者了解测试覆盖了多少代码,识别未被测试的区域,确保测试的全面性。 9. **模拟和间谍(Spies & Stubs)**:Sinon.js是一个流行的JavaScript库,用于...

    Testing_in_node:使用mocha和chai运行自动化测试并显示结果

    Mocha可以与模拟库如`sinon`、覆盖率工具如`istanbul`、代码覆盖率报告器`nyc`等配合使用,提升测试的全面性和质量。 10. **持续集成**: 将Mocha测试集成到持续集成(CI)工具如Jenkins、Travis CI、GitHub ...

    JavascriptUnitTesting-英文原版.zip

    8. **持续集成(CI)与持续部署(CD)**:学习如何将单元测试集成到CI/CD流程中,如Jenkins、Travis CI或GitHub Actions,以实现自动化测试和部署。 9. **最佳实践与陷阱**:文档可能会分享一些常见的单元测试最佳实践...

    一份有关测试Vue组件和应用程序的指南

    2. 测试覆盖率:通过工具如Istanbul获取测试覆盖率报告,确保测试覆盖了大部分代码。 3. 无状态组件测试:对于无状态组件,主要测试其props和事件处理,确保它们按预期工作。 4. 有状态组件测试:需考虑组件的状态...

    hello-ts-mocha:TypeScript和Mocha入门

    6. **测试覆盖率**:了解如何集成如Istanbul这样的覆盖率工具,以确保测试的全面性。 7. **持续集成与持续部署(CI/CD)**:学习如何配置Git工作流,使用如Travis CI或Jenkins等服务,自动运行测试并构建项目。 ...

    vuetest.zip

    8. **测试覆盖率报告**:为了确保测试的全面性,可以使用istanbul或nyc等工具生成测试覆盖率报告,帮助开发者识别未被测试到的代码。 9. **测试配置**:在项目中,通常会有专门的配置文件(如jest.config.js或mocha...

    Node.js-教你如何测试Node.js应用程序的workshoprepo

    6. **覆盖率报告**:代码覆盖率工具如Istanbul或nyc可以帮助我们了解测试覆盖了多少代码,这对于提高测试质量非常有用。通常,我们需要确保关键路径和异常处理都得到了充分的测试。 7. **持续集成(CI)与持续部署...

    模块测试笔记1

    3. 测试覆盖率工具:如JaCoCo(Java)、coverage.py(Python)、Istanbul(JavaScript),评估测试覆盖了源代码的多少部分。 五、模块测试的最佳实践 1. 早测试:尽早进行模块测试,能在开发早期发现和修复问题。 2...

    vue2单元测试环境搭建

    phantomjs-launcher karma-phantomjs-shim karma-chrome-launcher karma-sourcemap-loader mocha karma-mocha sinon chai sinon-chai karma-sinon-chai karma-spec-reporter karma-coverage istanbul-instrumenter-...

    Packtpub.JavaScript.Testing.Beginners.Guide.Aug.2010.rar

    7. **测试覆盖率**:书中可能会讲解如何使用istanbul等工具来度量代码覆盖率,确保大部分代码都经过了测试。 8. **异步测试**:由于JavaScript的异步性质,处理异步操作的测试方法也是必不可少的。书中会教读者如何...

    JavaScript测试工具

    2. **Mocha**:提供灵活的异步测试结构,支持BDD、TDD和QUnit风格的断言,可与Chai和Sinon等库配合使用,增强测试能力。 3. ** Jasmine**:专注于行为驱动开发(BDD),提供丰富的匹配器和异步测试支持,常用于...

    关于Vue Webpack2单元测试示例详解

    在 `specs` 目录下编写测试用例,使用 Mocha 和 Chai 框架,结合 Sinon.js 和 Sinon-Chai 提供的断言,可以有效地测试组件和业务逻辑。 总结来说,Vue Webpack2 单元测试涉及的主要知识点包括: 1. Vue.js 项目结构...

    全面详尽的JavaScript Nodejs测试最佳实践2023年7月.zip

    5. **覆盖率报告**:代码覆盖率工具如Istanbul可以帮助开发者了解测试覆盖了多少代码,确保没有遗漏的部分。 6. **异步测试**:由于JavaScript的非阻塞特性,异步操作的测试需要特别处理。使用async/await或者...

    BuildTools测试用例

    4. **代码覆盖率工具**:如JaCoCo(Java)、Codecov或Istanbul,帮助开发者了解测试覆盖了多少源代码,以确保没有遗漏的测试。 5. **静态代码分析工具**:如SonarQube、PMD或ESLint,可以在代码执行前检查潜在的...

Global site tag (gtag.js) - Google Analytics