如何在基于Express的API上设置代码覆盖率?

时间:2021-07-12 07:25:18

I've been at this problem for a while and I cannot make the existing solutions work for me.

我已经研究这个问题有一段时间了,我不能让现有的解决方案为我工作。

I have a Node.js API written in Express.js. I have been writing tests for the API using Mocha, Chai, and Supertest. These test are mostly integration tests.

我有一个节点。用Express.js编写的js API。我一直在使用Mocha、Chai和Supertest编写API测试。这些测试主要是集成测试。

One test may look like:

一种测试可能是:

it('should fail to register a new user without the proper information', function(done) {
  api.post('/user')
  .send({})
  .expect(400)
  .expect('Content-Type', /json/)
  .end(function(err, res) {
    should.exist(res.body);
    should.exist(res.body.error);
    should.not.exist(err);
    res.body.error.should.contain('Username');
    res.body.error.should.contain('password');
    done();
  });
});

The actual tests work great, but now I need to be able to view the code coverage of these tests. I have to know what I am not adequately testing. I have tried using Mocha's test coverage:

实际的测试工作得很好,但是现在我需要能够查看这些测试的代码覆盖率。我必须知道我在测试什么。我尝试过使用Mocha的测试覆盖:

mocha -R html-cov --coverage > coverage.html

and Istanbul's:

和伊斯坦布尔的:

istanbul cover _mocha -- -R spec --timeout 5000

Both of which suffer from the same issue:

两者都面临着同样的问题:

如何在基于Express的API上设置代码覆盖率?

You see, this is an example route (user registration). My tests definitely cover it, but since they do not call this method directly, the coverage tools assume it is never called. This is the problem - the code coverage tools aren't capturing the code that is eventually executed.

这是一个示例路由(用户注册)。我的测试肯定会涉及到它,但是由于它们不直接调用这个方法,所以覆盖率工具假定从来没有调用过它。这就是问题所在——代码覆盖工具没有捕获最终执行的代码。

I tried another solution - the Istanbul Middleware, which actually seemed to capture the information better (although it was hacky). However the same route here looks like:

我尝试了另一种解决方案——伊斯坦布尔中间件,它实际上似乎更好地捕获了信息(尽管它很陈腐)。然而,这里的相同路线是:

如何在基于Express的API上设置代码覆盖率?

Which clearly is not desirable either. Surely other applications have run into this issue, how do they go about doing it?

这显然也不可取。其他应用程序肯定也遇到过这个问题,他们如何着手去做呢?

Note: I've installed jscoverage as well to get all this to work.

注意:我还安装了jscoverage以使所有这些工作正常。

Sources I've looked at:
https://brianstoner.com/blog/testing-in-nodejs-with-mocha/
http://boycook.wordpress.com/2013/03/29/automated-javascript-testing-with-mocha-and-js-coverage-for-nodejs/
Code coverage with Mocha

我看过的资源:https://brianstoner.com/blog/testinginnodejs-with- mocha/ http://boycook.wordpress.com/2013/03/29/automated javascript- javascript- javascript- testwith- Mocha -and- coverage- nodejs/ Mocha的代码覆盖

2 个解决方案

#1


10  

I just had this same exact situation and I found it has to do the way I was using supertest:

我遇到了同样的情况,我发现它必须按照我使用supertest的方式进行:

  • Before I was testing my app directly against my running server, like this.

    在我直接在运行的服务器上测试我的应用之前,像这样。

    var request = require('supertest')
    var api = request('http://127.0.0.1:3000')
    
  • I fix it by requiring my express app instead:

    我通过要求我的快递应用来解决这个问题:

    var request = require('supertest')
    var app = require('../../../')
    var api = request(app)
    

#2


1  

Based on my experience with istanbul, I think there might be a logic error in terms of what route is actually being used. Please set that test to use it.only and then look at the istanbul coverage. (There's no need to use the istanbul middleware, since your developers have access to the html output being written to the local filesystem.)

根据我在伊斯坦布尔的经验,我认为在实际使用的路线上可能存在逻辑错误。请设置测试来使用它。然后再看看伊斯坦布尔的报道。(没有必要使用伊斯坦布尔中间件,因为您的开发人员可以访问被写入到本地文件系统的html输出)。

Please show what route is actually being covered, because istanbul is very clever in how it follows if statements.

请显示实际覆盖的路线,因为伊斯坦布尔在如何遵循if语句方面非常聪明。

If you have found a bug in istanbul, I encourage you to post a bug there.

如果你在伊斯坦布尔发现了一个bug,我建议你在那里发布一个bug。

#1


10  

I just had this same exact situation and I found it has to do the way I was using supertest:

我遇到了同样的情况,我发现它必须按照我使用supertest的方式进行:

  • Before I was testing my app directly against my running server, like this.

    在我直接在运行的服务器上测试我的应用之前,像这样。

    var request = require('supertest')
    var api = request('http://127.0.0.1:3000')
    
  • I fix it by requiring my express app instead:

    我通过要求我的快递应用来解决这个问题:

    var request = require('supertest')
    var app = require('../../../')
    var api = request(app)
    

#2


1  

Based on my experience with istanbul, I think there might be a logic error in terms of what route is actually being used. Please set that test to use it.only and then look at the istanbul coverage. (There's no need to use the istanbul middleware, since your developers have access to the html output being written to the local filesystem.)

根据我在伊斯坦布尔的经验,我认为在实际使用的路线上可能存在逻辑错误。请设置测试来使用它。然后再看看伊斯坦布尔的报道。(没有必要使用伊斯坦布尔中间件,因为您的开发人员可以访问被写入到本地文件系统的html输出)。

Please show what route is actually being covered, because istanbul is very clever in how it follows if statements.

请显示实际覆盖的路线,因为伊斯坦布尔在如何遵循if语句方面非常聪明。

If you have found a bug in istanbul, I encourage you to post a bug there.

如果你在伊斯坦布尔发现了一个bug,我建议你在那里发布一个bug。