-
Notifications
You must be signed in to change notification settings - Fork 10
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
Code Coverage #33
Comments
I don't have a great solution but I have something that is better than nothing. TL;DRFor those that just want some sort of coverage information even if it's a hack. Add the following as an esbuild plugin: const { Buffer } = require('buffer')
const { createInstrumenter } = require('istanbul-lib-instrument')
const coveragePlugin = {
name: 'code-coverage',
setup(build) {
coverageInstrumenter = createInstrumenter({ esModules: true })
build.onEnd((result) => {
const js = result.outputFiles.find(f => f.path.match(/\.js$/))
const sourceMap = result.outputFiles.find(f => f.path.match(/\.js\.map$/))
const sourceMapObject = JSON.parse(sourceMap.text)
sourceMapObject.sourceRoot = '/'
const instrumented = coverageInstrumenter.instrumentSync(js.text, null, sourceMapObject)
js.contents = Buffer.from(instrumented)
})
}
} You'll need to add I do this conditionally only in Karma and only if a Then continue to use karma-coverage to actually generate the report. You don't need to use its preprocessor just the report. This will get you a coverage report that is not great but at least something you can work with. It will include your test file as well as your node_modules files which will drive down your coverage percent. To determine the correct percent we are just going to run some JS within the report screen to only count the lines we are interested in. For me all the files that are runtime code have
This results in the return value of: { covered: 3141, total: 3365 } Some quick math and I know that is a bit over 93% coverage. The DetailsFor those interested in moving the ball forward writing up what I have learned in hopes it is helpful in getting a proper solution. Using Istanbul as our code coverage tool (which is what karma-coverage is using), there are really two phases to generating a code coverage report:
Let's look at step 2 first. If you add Step 1 is where we have a problem. Instrumenting the code with istanbul is what will populate that variable. There are two ways we can instrument the code and neither work with karma-esbuild.
babel-plugin-istanbul doesn't really meet our needs for two reasons:
I'm not completely clear on the reason for that but I think relates to the comment in the plugin API limitations section of the documentation. It says:
While I think webpacker and other bundlers like rollup are more like a shell pipe where the content output of one plugin can then feed into the next one allowsing a plugin that transforms JS (like babel) to process Vue files by having a Vue plugin convert to JS and then feed that to babel. I could be wrong on all this. Therefore my solution is to use the onEnd hook to modify the entire bundled JS file. I provide istanbul that bundled JS as well as the sourcemap allowing it to map back to the original file (including transformed files like Vue code). I did find I had to modify that sourcemap a bit. All the sources in the sourcemap had the name To correct this I provided a source root of sourceMapObject.sourceRoot = '/' All this got me a working report although as I mentioned in the TL;DR section it included files I didn't want to include in the report. I'm not sure how to either tell instanbul not to instrument those parts of the bundle (based on the sourcemap paths) or tell the report to skip outputting those paths. Therefore I wrote a quick bit of JS that extracts the stats I need for the relevant files. SolutionsWhat is a real solution to all this? Maybe allow custom transformations to be defined for the JS loader. esbuild has built-in transformations. If there was a hook where I could provide my own custom transformation. I don't need to be necessarily given the AST of the JS. It might be sufficient to be just given the JS and I return modified JS, leaving the parsing of the JS up to the plugin (and in this case istanbul provides that parsing and modification of the source). Another solution might be to modify istanbul to be able to include/exclude paths from instrumentation. But the key thing is it would need to abide by input sourcemap. This would allow me to drop the JS I need to run on the report directly. |
Is there a development pattern for getting code coverage when using karma-esbuild? I've previously used karma-coverage with karma-webpack but that isn't working with karma-esbuild. I noticed the definition of a
COVERAGE
global in your advanced example but wasn't sure what library that could be referencing.The text was updated successfully, but these errors were encountered: