Skip to content

test_runner: coverage reports the largest block count as the function call count (FNDA) #67319

Closed

Description

@trackoor

Version

v26.13.0, also v28.0.0-nightly20261107a43bfb5bb2

Platform

Linux 6.1.0-54-cloud-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.190-1 (2026-10-16) x86_64 GNU/Linux

Subsystem

test_runner

What steps will reproduce the bug?

// math.js
function sum(n) {
  let s = 0;
  for (let i = 0; i < n; i++) s += i;
  return s;
}
module.exports = { sum };
// math.test.js
const test = require('node:test');
const { sum } = require('./math.js');
test('sum', () => { sum(10); });
node --test --experimental-test-coverage --test-reporter=lcov --test-reporter-destination=stdout math.test.js

How often does it reproduce? Is there a required condition?

Always, when a block inside a function runs more often than the function is called.

What is the expected behavior? Why is that the expected behavior?

sum is called once:

FN:1,sum
FNDA:1,sum

In LCOV, FNDA is the number of times the function was called, and the test:coverage docs describe functions[].count as the number of times the function was called.

What do you see instead?

TN:
SF:math.js
FN:1,sum
FNDA:10,sum
FNF:1
FNH:1
BRDA:1,0,0,1
BRDA:1,1,0,1
BRDA:3,2,0,10

The same value appears in summary.files[].functions[].count of the test:coverage event.

Additional information

In TestCoverage.summary() (lib/internal/test_runner/coverage.js), the function report uses count: maxCountPerFunction, the maximum over all block ranges, instead of ranges[0].count, the function range's own count.

Found with a differential-testing tool; the report was drafted with AI assistance and reviewed and edited by me.

Credit: https://ucsbplse.github.io/

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions