aspect-build / aspect-build/rules_jest

[FR]: Use jest-monocart-coverage with v8 and lcov instead of c8

Open
#288 1 comment 0 reactions 0 assignees View on GitHub
engagement note enhancement
Dominant language
Starlark
Stars
24
Forks
31
PR merge metrics
No merged PRs in 30d

Description

### What is the current behavior?

The current coverage reporters are not accurate enough and lead to bad line assignments and incorrect coverage values.

### Describe the feature

The current coverage behavior is actually kind of buggy and I've spent a month debugging it so I figured I'd ask for this to be added. On our end, we've patched our way out of the coverage collection because it just doesn't do what we want and it has been cumbersome to get right.

How I fixed this on my end:

1. I needed to add flags around https://github.com/aspect-build/rules_jest/blob/940a9fe3c319e1351352e2ffa889e05db790343e/jest/private/jest_config_template.mjs#L152-L165 that let's me eject from this so I can set these variables myself. That may not be necessary for this feature. The main thing is not to set `coverageReporters` if one is provided. I also removed https://github.com/aspect-build/rules_jest/blob/940a9fe3c319e1351352e2ffa889e05db790343e/jest/private/jest_config_template.mjs#L174-L179 as it never worked right and messed up split coverage in our case.
2. Set `coverageReporters` to ` coverageReporters: ['none'],`
3. Add the following to `reporters`

```javascript
[
'jest-monocart-coverage',
{
name: 'Coverage Report',
outputDir: `${process.env.COVERAGE_DIR}/jest_mcr_temp`,
reports: [['v8'], ['lcovonly']],
sourceFilter: '**/*.{ts,tsx}',
},
],
```

4. Create a `globalTeardown` script with the following
```
import fs from 'fs'
import path from 'path'

const outputDir = `${process.env.COVERAGE_DIR}/jest_mcr_temp`

export default async function globalTeardown() {
// If bazel coverage is being run, otherwise don't do this
if (process.env.COVERAGE_DIR) {
/**
* generate the lcov report by merging all the existing
* lcov info files from the coverage dir generated
* by each test
*/
const filePath = path.join(outputDir, 'lcov.info')

/**
* We nest in a dir because otherwise we will gather
* json files that bazel itself generates and we wish to avoid
* gathering.
*/
if (!fs.existsSync(path.dirname(filePath))) {
fs.mkdirSync(path.dirname(filePath), { recursive: true })
}
// If the lcov file doesn't exist, make one otherwise
// coverage fails. This applies to non standard file types like
// html, json, etc.
if (!fs.existsSync(filePath)) {
fs.writeFileSync(filePath, '', {
encoding: 'utf8',
})
}
// Following is taken from https://github.com/aspect-build/rules_jest/blob/940a9fe3c319e1351352e2ffa889e05db790343e/jest/private/jest_config_template.mjs#L151C1-L162
let coverageFile = path.basename(process.env.COVERAGE_OUTPUT_FILE as string)
let coverageDirectory = path.dirname(
process.env.COVERAGE_OUTPUT_FILE as string
)
if (process.env.SPLIT_COVERAGE_POST_PROCESSING === '1') {
// in split coverage post processing mode bazel assumes that the COVERAGE_OUTPUT_FILE
// will be created by lcov_merger which runs as a separate action with everything in
// COVERAGE_DIR provided as inputs. so we'll just create the final coverage at
// `COVERAGE_DIR/split_coverage.dat` which then later moved by merger.sh to final location.
coverageDirectory = process.env.COVERAGE_DIR as string
coverageFile = 'coverage.dat'
}
// end of rules_js code

// Write coverage data to a file that Bazel knows how to handle
await fs.promises.copyFile(
path.join(outputDir, 'lcov.info'),
path.join(coverageDirectory, coverageFile)
)
}
}
```

5. add the teardown to the config
```javascript
globalTeardown: path.resolve(__dirname, 'globalTeardown.js'),
```

Contributor guide

Open the contributing guide

Research direction

Start by reviewing jest/private/jest_config_template.mjs at the linked coverage configuration and post-processing sections. Compare those entry points with the proposed jest-monocart-coverage reporters and globalTeardown configuration. Done means Bazel coverage uses the v8 and lcov outputs without the current reporter and split-coverage behavior problems.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, typescript
Domain
build-system, testing-qa
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.