Incorrect branch coverage when loaders used
See original GitHub issuec8
shows uncovered lines, but the whole file is covered.
Version: output of node -v
16.9.0
Platform: output of uname -a
Darwin
- Version: latest
- Platform: mac os
Repository https://github.com/coderaiser/c8-reproduce
When I’m using loaders to mock imports
the coverage I see is broken.
Code:
import {
readFile,
} from 'fs/promises';
import {
execSync,
} from 'child_process';
export default (a, b, c) => {
if (a)
return readFile();
if (c)
return execSync();
return 'd';
};
Tests:
import {createMockImport} from 'mock-import';
import {
test,
stub,
} from 'supertape';
const {mockImport, reImport, stopAll} = createMockImport(import.meta.url);
test('changelog: a', async (t) => {
mockImport('fs/promises', {
readFile: stub().returns('a'),
});
const fn = await reImport('./changelog.js');
stopAll();
t.equal(fn.default(1), 'a');
});
test('changelog: c', async (t) => {
mockImport('child_process', {
execSync: stub().returns('c'),
});
const fn = await reImport('./changelog.js');
stopAll();
t.equal(fn.default(0, 0, 1), 'c');
});
test('changelog: d', async (t) => {
const fn = await import('./changelog.js?count=4');
t.equal(fn.default(0, 0, 0, 1), 'd');
});
What mock-import does is converts source to:
const {
readFile: readFile
} = global.__mockImportCache.get('fs/promises');
import {
execSync,
} from 'child_process';
export default (a, b, c) => {
if (a)
return readFile();
if (c)
return execSync();
return 'd';
};
And imports
it as ./changelog.js?count=1
on first test, then on second test:
import {
readFile
} from 'fs/promises'
const {
execSync,
} = global.__mockImportCache.get('fs/promises');
export default (a, b, c) => {
if (a)
return readFile();
if (c)
return execSync();
return 'd';
};
File imported
as ./changelog.js?count=2
, and then on third assertion code isn’t changed.
Issue Analytics
- State:
- Created 2 years ago
- Comments:14 (14 by maintainers)
Top Results From Across the Web
Test coverage: import statements not covered - Stack Overflow
The problem is, I have uncovered import statements saying else path not taken" and "branch not covered". The uncovered imports vary across ...
Read more >What Is Branch Coverage & What Does It Really Tell You?
What's it used for? Branch coverage is a metric that indicates whether all branches in a codebase are exercised by tests. A "branch"...
Read more >Test coverage reporting — nose2 0.12.0 documentation
The coverage and mp plugins may be used in conjunction to enable multiprocess testing with coverage reporting. Special instructions: Due to the way...
Read more >Problem with coverage test . IntelliJ Idea.
Looks like your TEMP directory path contains spaces, so IDEA tries to save a temporary file used by coverage to some place which...
Read more >Configuring Jest
The bail config option can be used here to have Jest stop running tests after n ... If the file path matches any...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Yes I’d be open to adding this functionality, the only issue is it does draw attention to the fact that merging multiple istanbul reports is a bit buggy.
The function and line coverage should be pretty accurate, I think, but as demonstrated by the yellow blocks in the report I shared, branch coverage is a bit off.
All I did was stop dropping the
?
suffix:The approach should be fleshed out more with tests, and using a helper rather than repeated code – also it fails if no source is found right now, since
v8-to-istanbul
will try to loadcoverage.js?=foo.bar
from disk (this should probably be fixed in v8-to-istanbul, with it dropping the suffix perhaps there?).I hacked together an approach that merges three coverage reports at the end, rather than merging the
v8
output at the start, it kind of works:However, it has trouble merging branches, this isn’t unexpected because SourceMaps provide sparse data, so trying to combine two source maps can be like comparing apples and oranges.
A better way to fix your problem, I think, would be to figure out where the 30 byte discrepancy is happening in
loader-3
, vs.,loader-2
andloader-1
. If you can get these byte ranges to correlate, c8 will start working – my guess is a header is being injected by 1/2 but is not being injected for3
… perhaps a different function wrapper?