-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implicit branches are not considered in coverage #2239
Comments
This is duplicate of #1887. @bencelang so even though there is no // Source code
export const fn = y => {
if (true) {
console.log('#1')
}
console.log('#2')
}
// Instrumented
coverageMap.s[0]++;
export const fn = y => {
coverageMap.f[0]++;
coverageMap.s[1]++;
if (true) {
coverageMap.b[0][0]++;
coverageMap.s[2]++;
console.log('#1');
} else {
coverageMap.b[0][1]++;
}
coverageMap.s[3]++;
console.log('#2');
}
// Coverage map
"s": {
"0": 1,
"1": 1,
"2": 1,
"3": 1
},
"f": {
"0": 1
},
"b": {
"0": [
1,
0 // <-- else-branch
]
} Now that we map the coverage back to sources, the "s": {
"0": 1,
"1": 1,
"2": 1,
"3": 1
},
"f": {
"0": 1
},
"b": { // Notice how branch count drops
"0": [
1
]
} Two more test cases to demonstrate this. 100% branch coverage since all lines are covered1 | export const fn = () => {
2 | if (true) {
3 | console.log('#1')
4 | }
5 | console.log('#2')
6 | }
/*
% Coverage report from istanbul
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
cov.js | 100 | 100 | 100 | 100 |
----------|---------|----------|---------|---------|-------------------
*/ 75% coverage, unreached lines are not covered:1 | export const fn = () => {
2 | if (false) {
3 | console.log('#1')
4 | }
5 | console.log('#2')
6 | }
/*
% Coverage report from istanbul
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 75 | 0 | 100 | 75 |
cov.js | 75 | 0 | 100 | 75 | 3
----------|---------|----------|---------|---------|-------------------
*/ |
I debugged this a bit further and found out why In vitest codebase we can apply a work-around for this. I'll set up PR later and write a bit more about the root cause.
|
@AriPerkkio I see why you indicated this as a duplicate and I'm sorry for not catching it earlier. This example is the other way around though - always reaching the branch body - and I think better represents why this is misleading.
Depends on what you say branch count is. My point of view (as seem to align with the I think it makes more sense to count the actual paths of execution (a standalone if statement as 2) instead of the blocks present. |
@bencelang you are completely right. I read this thread to understand the implicit I think example below highlights the importance of branch coverage. It has 100% line coverage but only 50% branch coverage. function get(condition) {
let output;
if(condition) {
output = 'text';
}
return output;
}
// Test
expect(get(true)).toBe('text');
// Production code
get(usuallyTruthyCondition).toString() Now the untested branch may actually cause NPE in production code. It's not covered by tests due to partial branch coverage. const usuallyTruthyCondition = false;
get(usuallyTruthyCondition).toString()
// ^^^^^^^^^^^ NPE |
Describe the bug
Code with implicit branches is not detected in coverage. Consider the following code:
If test code is only executing
fn
with a truthy parameter the implicit else branch is never tested, thus should not count towards covered branches. Interestingly enough, coverage still reports 100% for branch coverage.This impacts both coverage providers but in case of c8 it is a known issue. With istanbul it is expected to report the correct 50% branch coverage metric, yet running under vitest the problem persists. Read reproduction for details.
Reproduction
Consider the following code (origin):
The coverage report using
@vitest/coverage-c8
reports this as 100% branch coverage, due to a known issue with v8 (bcoe/c8#227 and this v8 ticket). However, running a sligthly different version of this code from the gist I linked above in commonjs syntax throughnyc node cov.cjs
prints 50%, correctly. (ESM code causesnyc
to have a blank output but that is also already a known issue).Interestingly, switching the coverage provider to
@vitest/coverage-istanbul
is still impacted, showing full coverage mistakenly.System Info
Used Package Manager
pnpm
Validations
The text was updated successfully, but these errors were encountered: