Skip to content
This repository was archived by the owner on Dec 8, 2024. It is now read-only.

is there a way to limit what code can be covered per test? #159

Open
unstoppablecarl opened this issue Feb 21, 2014 · 4 comments
Open

is there a way to limit what code can be covered per test? #159

unstoppablecarl opened this issue Feb 21, 2014 · 4 comments

Comments

@unstoppablecarl
Copy link

I have a module "foo.js" that uses module "bar.js". When I generate code coverage from my tests for foo.js (test/foo.js) I want to be able to limit the code coverage reporting from the execution of test/foo.js to the foo.js file. I do not want execution of test/foo.js to report any code coverage of the dependency bar.js. Limiting coverage will tell you how much of the code your are testing is covered only by the relevant test excluding coverage reported as a side effect of using/mocking dependent module code. This helps improve the quality of tests. The desired effect can be accomplished by running test files individually, but then there isn't one comprehensive coverage report there is one for each test file.I have leveraged this a lot when using PHPUnit but I have not been able to find a way to do this in any node.js unit testing workflows.

I know this isn't explicitly istanbul relevant. I am using mocha and istanbul in my testing/coverage workflow. Any advice would be much appreciated.

Example

foo.js
bar.js
test/foo.js

    var expect = require('expect.js');
    var foo = require('../foo.js');
    var bar = require('../bar.js');

     describe('Foo', function() {
        it('can do something relying on bar', function() {
            foo.doSomethingWith(bar, 'blam');
        });
    });
@gotwarlost
Copy link
Owner

I understand the problem perfectly - thanks for the detailed explanation. However, I don't (yet) have a good solution for it.

Could you explain a bit more about how phpunit works and the dev workflow that you use to get a single report the way you want it? For example, when you are running a test for foo.php how do you indicate to phpunit that bar.php must not be covered and so on...

@unstoppablecarl
Copy link
Author

PHPUnit has annotation you put in comments before a test function to configure the test behavior. The comments are parsed when the test file is run. One of them is @Covers which sets what the class(s) and method(s) the test coverage should be limited to. This is simple to implement in php where Class::function is strictly maintained.

/**
 * @covers BankAccount::getBalance
 */
public function testBalanceIsInitiallyZero()
{
    $this->assertEquals(0, $this->ba->getBalance());
}

Relevant docs for phpunit:
http://phpunit.de/manual/current/en/phpunit-book.html#appendixes.annotations.covers

In the case of node I think annotating one or more modules to be covered by a test file would be sufficient. In the following example coverage data reported by /test/foo.js would limitied to the "./foo.js" module. It could be done per test function as well but I do not know if that is feasible to implement.

/* file: /test/foo.js */
/* istanbul covers[require.resolve('../foo.js')] */
var expect = require('expect.js');
    var foo = require('../foo.js');
    var bar = require('../bar.js');

describe('Foo', function() {
    it('can do something relying on bar', function() {
        foo.doSomethingWith(bar, 'blam');
    });
});

If you looked for comments matching "istanbul covers.." like you do for the "istanbul ignore..." you could then parse the [require.resolve('./foo.js')] to get the list of files to covered by the current test file. Then before storing the coverage data filter it by the covered files removing any coverage data for files not in the list.

@unstoppablecarl
Copy link
Author

A less elegant but much simpler solution:

/* file: /test/foo.js */
require('istanbul').CoverageFilter.add(__filename, [require.resolve('../foo.js')]);
var expect = require('expect.js');
    var foo = require('../foo.js');
    var bar = require('../bar.js');

describe('Foo', function() {
    it('can do something relying on bar', function() {
        foo.doSomethingWith(bar, 'blam');
    });
});

@silkentrance
Copy link

@unstoppablecarl this problem is the same for all coverage gathering tools, be it C, C++ or JS. And people have been able to deal with this in the past based on common sense alone.

@gotwarlost I do not think that this is an issue that should be dealt with.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants