首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Nightmare.js和代码覆盖

Nightmare.js和代码覆盖
EN

Stack Overflow用户
提问于 2014-11-26 18:06:16
回答 2查看 1.1K关注 0票数 2

简短版本:

我无法从我使用nightmare.js和mocha编写的测试中看到代码覆盖率。到目前为止,我已经尝试使用伊斯坦布尔和_mocha而没有运气。

大版本:

我有个小项目:

/public/index.html

代码语言:javascript
复制
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>My Website</title>
  <script src="./js/hello.js"></script>
</head>
<body>
  <h1>My Website</h1>
</body>
</html>

/public/js/hello.js

代码语言:javascript
复制
window.hello = function hello(){
  return 'world';
};

该网站正在运行使用快车和永远。

当我试图使用nightmare.js测试它时。

/test/test.js

代码语言:javascript
复制
var path = require('path');
var Nightmare = require('nightmare');
var should = require('should');

/*global describe */
/*global it */

describe('Simple demo', function () {
  this.timeout(15000);
  var url = 'http://localhost:9000';

  it('check hello world result', function (done) {
    new Nightmare()
      .goto(url)
      .evaluate(function () {
        /*global hello */
        return hello();
      }, function (value) {
        var expected = "world";
        if (value === null) {
          false.should.equal(true);
          return done();
        }
        value.should.equal(expected);
        return done();
      })
      .run();
  });

  it('should get the index title', function (done) {
    var expected = 'My Website';
    new Nightmare()
      .goto(url)
      .title(function (title) {
        title.should.equal(expected);
        done();
      })
      .run();
  });
});

测试通过了

代码语言:javascript
复制
$ mocha


  Simple demo
    ✓ check hello world result (2089ms)
title =  Alexandria
    ✓ should get the index title (1947ms)


  2 passing (4s)

但是,我无法从测试中获得代码覆盖率报告。

我已经尝试过一些命令,比如:

代码语言:javascript
复制
$ istanbul cover _mocha -- test/test.js -u exports -R spec
No coverage information was collected, exit without writing coverage information

$ istanbul cover --hook-run-in-context _mocha -- -R spec
No coverage information was collected, exit without writing coverage information

那么,有人能够创建nightmare.js测试的代码覆盖率报告吗?如果不是的话,用另一种工具就有接近它的东西?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-07-13 14:08:02

我的项目中也有同样的问题。我找不到任何简单地解决这个问题的库或配置,但是通过一些实现和Grunt配置,您可以从Grunt流程获得代码覆盖率。

我在项目中使用的依赖项:

代码语言:javascript
复制
"chai": "^3.5.0",
"grunt": "^0.4.5",
"grunt-contrib-clean": "^0.7.0",
"grunt-contrib-copy": "^0.8.2",
"grunt-express-server": "^0.5.3",
"grunt-istanbul": "^0.7.1",
"grunt-mocha-test": "^0.12.7",
"istanbul": "^0.4.4",
"nightmare": "^2.2.0"

我的项目结构:

代码语言:javascript
复制
public/     -- public folder for index.html
src/        -- source folder for hello.js
test/       -- mocha tests implementation
server/     -- express implementation for server.js
coverage/   -- HTML report from code coverage
report/     -- HTML report from mocha tests    
dist/       -- folder which is used by express server to get content, generated by Grunt

您必须从Grunt运行的步骤:

代码语言:javascript
复制
grunt.registerTask('test_hello', [
    'clean',            // clean dist/ folder
    'copy:public',      // copy public files from public/ (ex. index.html) to dist/ 
    'instrument',       // generate instruments (ex. hello.js) for code coverage from src/ by istanbul
    'express',          // run express server from dist/ folder
    'mochaTest',        // run mocha tests with nightmare and generate HTML report to report/ folder
    'report_coverage'   // generate HTML report from code coverage to coverage/ folder
]);

咕噜声配置:

代码语言:javascript
复制
module.exports = function (grunt) {

    grunt.loadNpmTasks('grunt-contrib-clean');
    grunt.loadNpmTasks('grunt-contrib-copy');
    grunt.loadNpmTasks('grunt-express-server');
    grunt.loadNpmTasks('grunt-istanbul');
    grunt.loadNpmTasks('grunt-mocha-test');

    grunt.initConfig({
        clean: {
            dist: ['dist/', 'report/', 'coverage/']
        },
        copy: {
            public: {
                expand: true,
                cwd: 'public/',
                src: ['**'],
                dest: 'dist/'
            }            
        },
        instrument: {
            files: ['**/*.js'],
            options: {
                cwd: 'src/',
                lazy: true,
                basePath: 'dist/'
            }
        },
        express: {
            dev: {
                options: {
                    port: 9000,
                    script: 'server/server.js',
                    background: true
                }
            }
        },
        mochaTest: {
            hello: {
                options: {
                    timeout: 10000,
                    captureFile: 'report/results.txt', // Optionally capture the reporter output to a file
                    quiet: false, // Optionally suppress output to standard out (defaults to false)
                    clearRequireCache: false // Optionally clear the require cache before running tests (defaults to false)
                },
                src: ['test/*.js']
            },
        }
    });

    grunt.registerTask('report_coverage', function () {
        var coverage = require('./test/utils/coverage');
        coverage.generateReport();
    });

    grunt.registerTask('test_hello', [
        'clean',            // clean dist/ folder
        'copy:public',      // copy public files from public/ (ex. index.html) to dist/ 
        'instrument',       // generate instruments (ex. hello.js) for code coverage from src/ by istanbul
        'express',          // run express server from dist/ folder
        'mochaTest:hello',  // run mocha tests with nightmare and generate HTML report to report/ folder
        'report_coverage'   // generate HTML report from code coverage to coverage/ folder
    ]);

}

我还创建了一个类,它允许我从每个噩梦实例收集代码覆盖率:

代码语言:javascript
复制
var istanbul = require('istanbul');
var reporter = new istanbul.Reporter(),
    sync = true;

var Coverage = function () {

    this.loadCodeCoverage = function (dom, done) {
        dom
            .evaluate(function () {
                return window.__coverage__;  // this variable store all information about code coverage
            })
            .then(function (coverageDate) {
                if (coverageDate) {
                    this.getCollector().add(coverageDate);
                }
                done();
            }.bind(this))
            .catch(function (error) {
                done(error);
            });
    }

    // load page by nightmare
    this.getCollector = function () {
        if (!this.collector) {
            this.collector = new istanbul.Collector();
        }
        return this.collector;
    }

    this.generateReport = function () {
        reporter.add('text');
        reporter.addAll(['lcov', 'clover']);
        reporter.write(this.collector, sync, function () {
            console.log('All reports generated');
        });
    }

}

module.exports = new Coverage();

对于上面的配置文件test/test.js应该具有以下结构:

代码语言:javascript
复制
var should = require('should');
var coverage = require('./utils/coverage');

/*global describe */
/*global it */

describe('Simple demo', function () {
    this.timeout(15000);
    var url = 'http://localhost:9000';

    before(function (done) {
        global.dom = new Nightmare()
            .goto(url)
            .evaluate(function () {
                return 'test';
            })
            .then(function(result) {
                done();
            })
            .catch(function(error) {
                done(error);
            });

    });

    after(function (done) {
        coverage.loadCodeCoverage(dom, done);
    });

    it('check hello world result', function (done) {
        dom.evaluate(function () {
                /*global hello */
                return hello();
            })
            .then(function(value) {
                var expected = "world";
                if (value === null) {
                  false.should.equal(true);
                  return done();
                }
                value.should.equal(expected);
                return done();
            })
            .catch(function(error) {
                done(error);
            });         
    });

    it('should get the index title', function (done) {
        var expected = 'My Website';
        dom.title(function (title) {
            title.should.equal(expected);
            done();
        });
    });

});

如果一切正常,您应该在控制台上获得信息,并在文件夹覆盖率/中生成HTML形式的代码覆盖率报告。

代码语言:javascript
复制
Running "report_coverage" task
------------------------------------|----------|----------|----------|----------|----------------|
File                                |  % Stmts | % Branch |  % Funcs |  % Lines |Uncovered Lines |
------------------------------------|----------|----------|----------|----------|----------------|
 js/                                |      100 |      100 |      100 |      100 |                |
  hello.js                          |      100 |      100 |      100 |      100 |                |
------------------------------------|----------|----------|----------|----------|----------------|
All files                           |      100 |      100 |      100 |      100 |                |
------------------------------------|----------|----------|----------|----------|----------------|

我仍然存在的问题是,对于每个测试描述,我必须添加方法beforeafter。最好只在一个地方实现这些实现,例如在Grunt配置中的某个地方,在进行新的测试描述时,我不需要记住这些实现。

如果有人能为beforeafter方法找到更通用的解决方案,我们将非常感激。

票数 1
EN

Stack Overflow用户

发布于 2017-08-12 15:29:21

我想提出另一种办法。基本上可以归结为

  1. 用伊斯坦布尔测试应用程序代码
  2. 从浏览器中获取覆盖率数据并将其传递给测试过程(这样我们就可以提取它)
  3. 运行报告

下面是这样做的代码片段

代码语言:javascript
复制
nightmare
  .evaluate(() => window.__coverage__) // this executes in browser scope
  .end() // terminate the Electron (browser) process
  .then((cov) => {
    // this executes in Node scope
    // handle the data passed back to us from browser scope
    const strCoverage = JSON.stringify(cov);
    const hash = require('crypto').createHmac('sha256', '')
      .update(strCoverage)
      .digest('hex');
    const fileName = `/tmp/coverage-${hash}.json`;
    require('fs').writeFileSync(fileName, strCoverage);

    done(); // the callback from the test
  })
.catch(err => console.log(err));

有关实际提交的详细信息和链接,请访问我的博客:http://atodorov.org/blog/2017/08/12/code-coverage-from-nightmarejs-tests/

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27156047

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档