mocha、chai、sinon、istanbul は単体テスト カバレッジ 100% を達成

PHP中文网
リリース: 2017-07-10 18:10:36
オリジナル
1489 人が閲覧しました

アジャイル ソフトウェア開発では、最も重要な実践はテスト駆動開発であり、単体テスト レベルで達成しようとする重要な指標はテスト カバレッジです。テストカバレッジは、すべてのコードがテストされたかどうかを測定します。

しかし、テストカバレッジチェックの助けを借りて、テストでカバーされていないコードを見つけて、それらのコードのロジックをテストする方法を考え、より良い設計と改善を行うことが目的ではありません。コードの品質が高くなるようにコードを再構築します [1]。

テストといえば、最近たまたま『数学の美しさ』を読んでいたのですが、その本の中に情報についての一節がありました。コードの動作を非決定的なものから決定的なものに変更する場合も同様です。ブラック ボックスからホワイト ボックスへは、十分な情報しか提供できません。テスト カバレッジも一種の間接的な情報と考えることができます。 、これにより一部の情報の不確実性が排除されますが、完全なアサーションはより直接的な情報を提供します。テスト カバレッジ チェックと組み合わせることで、コードが期待どおりに動作するかどうかを確認するのに十分な情報を提供できます。

テスト用関連テクノロジー

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 はグローバルにインストールすることも、現在のプロジェクトにのみインストールすることもできます。

リーリー

インストールが完了したら、package.jsonファイルのスクリプトの下に、テストとテストカバレッジチェックを実行するコマンドを追加します

リーリー

Runnpm run coveragenpm run coverage:check を実行してテスト レポートを生成します。前者はテスト レポートを生成し、後者はテスト カバレッジが要件を満たしているかどうかを確認します。

2 配置Istanbul

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

<code class="yaml"><span class="hljs-attr">instrumentation:
<span class="hljs-attr">  root: .   <span class="hljs-comment"># 执行的根目录
<span class="hljs-attr">  extensions:
<span class="hljs-bullet">    - .js   <span class="hljs-comment"># 检查覆盖率的文件扩张名
<span class="hljs-attr">  excludes: [<span class="hljs-string">'**/benchmark/**']

  ... ...

<span class="hljs-attr">reporting:
<span class="hljs-attr">  print: summary
<span class="hljs-attr">  reports: [lcov, text, html, text-summary] <span class="hljs-comment"># 生成报告的格式
<span class="hljs-attr">  dir: ./coverage   <span class="hljs-comment"># 生成报告保存的目录
<span class="hljs-attr">  watermarks:       <span class="hljs-comment"># 在不同覆盖率下会显示使用不同颜色
<span class="hljs-attr">    statements: [<span class="hljs-number">80, <span class="hljs-number">95]
    ... ...
<span class="hljs-attr">check:
<span class="hljs-attr">  global:
<span class="hljs-attr">    statements: <span class="hljs-number">100
<span class="hljs-attr">    branches: <span class="hljs-number">100
<span class="hljs-attr">    lines: <span class="hljs-number">100
<span class="hljs-attr">    functions: <span class="hljs-number">100</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
ログイン後にコピー

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

编写测试代码

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

1 一段简单的mocha测试代码

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

<code class="javascript"><span class="hljs-keyword">var chai = <span class="hljs-built_in">require(<span class="hljs-string">'chai')

chai.should()
<span class="hljs-keyword">var expect = chai.expect
<span class="hljs-keyword">var assert = chai.assert

describe(<span class="hljs-string">'basic test', <span class="hljs-function"><span class="hljs-keyword">function (<span class="hljs-params">) {
  describe(<span class="hljs-string">'simple', <span class="hljs-function"><span class="hljs-keyword">function (<span class="hljs-params">) {
    it(<span class="hljs-string">'data check', <span class="hljs-function"><span class="hljs-keyword">function (<span class="hljs-params">) {
      <span class="hljs-keyword">var data = { <span class="hljs-attr">name: <span class="hljs-string">"test" }

      assert.isNotNull(data, <span class="hljs-string">'data should not be null')
      expect(data).to.be.an(<span class="hljs-string">'object')
      expect(data).to.have.all.keys([<span class="hljs-string">'name'])
      expect(data).to.deep.include({<span class="hljs-attr">name: <span class="hljs-string">'test'});
    });
  });
});</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
ログイン後にコピー

2 用Sinon模拟文件读写

<code class="javascript">... 同上 ...
var sinon = <span class="hljs-built_in">require(<span class="hljs-string">'sinon')
<span class="hljs-keyword">var fs = <span class="hljs-built_in">require(<span class="hljs-string">'fs')

describe(<span class="hljs-string">'sinon', <span class="hljs-function"><span class="hljs-keyword">function (<span class="hljs-params">) {
  it(<span class="hljs-string">"should mock readFile", <span class="hljs-function"><span class="hljs-keyword">function(<span class="hljs-params">done){
    sinon.stub(fs, <span class="hljs-string">'readFile').callsFake(<span class="hljs-function"><span class="hljs-keyword">function (<span class="hljs-params">path, callback) { callback(<span class="hljs-keyword">new <span class="hljs-built_in">Error(<span class="hljs-string">'read error')) })

    fs.readFile(<span class="hljs-string">"any file path", <span class="hljs-function"><span class="hljs-keyword">function(<span class="hljs-params">err,data){
      assert.isNotNull(err)
      done()
    })
    assert(fs.readFile.calledOnce)
  });
});</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
ログイン後にコピー

在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配置如下:

<code class="yaml"><span class="hljs-attr">language: node_js
<span class="hljs-attr">node_js:
<span class="hljs-bullet">  - <span class="hljs-string">"7.6.0"
<span class="hljs-attr">install:
<span class="hljs-bullet">  - npm install
<span class="hljs-attr">script:
<span class="hljs-bullet">  - npm test
<span class="hljs-attr">after_script:
<span class="hljs-bullet">  - npm run coverall</span></span></span></span></span></span></span></span></span></span></code>
ログイン後にコピー

 

 

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

以上がmocha、chai、sinon、istanbul は単体テスト カバレッジ 100% を達成の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!