Open factoidforrest opened 6 years ago
I don't know it is an expected answer, but it worked for me by following that mocha-webpack guide and adding the loader to vue.config.js.
You can check whether the rule is successfully added with vue inspect --mode test module.rules
:
...
{
test: /\.(js|ts)$/,
include: '/Users/yahatakeiji/work/d3ledger/back-office/src',
loader: 'istanbul-instrumenter-loader',
query: {
esModules: true
}
}
...
Also, I changed test:unit
script to use nyc as below:
- "test:unit": "vue-cli-service test:unit",
+ "test:unit": "nyc --reporter=lcov --reporter=text vue-cli-service test:unit",
Me too! I feel that coverage should be part of vue-cli. I can look at how challenging this would be to add in a PR
Here's how I made test coverage work for both apollo-server
and src
directory:
UPDATE: This comment is outdated, please check out @stephsavoie's solution below.
babel-plugin-istanbul
+ configure it in babel.config.js
yarn add --dev babel-plugin-instanbul
# or
npm install --save-dev babel-plugin-istanbul
// babel.config.js
module.exports = {
presets: ["@vue/app"],
plugins: ["istanbul"]
};
istanbul-instrumenter-loader
+ configure it in vue.config.js
yarn add --dev istanbul-instrumenter-loader
# or
npm install --save-dev istanbul-instrumenter-loader
// vue.config.js
// ...
chainWebpack: config => {
if (process.env.NODE_ENV !== "production") {
config.module
.rule("istanbul")
.test(/\.(js|vue)$/)
.enforce("post")
.include.add("apollo-server")
.add("src")
.end()
.use("istanbul-instrumenter-loader")
.loader("istanbul-instrumenter-loader")
.options({ esModules: true })
.end();
}
// ...
nyc
+ configure it in package.json
yarn add --dev nyc
# or
npm install --save-dev nyc
// package.json
// ...
"nyc": {
"check-coverage": true,
"per-file": true,
"lines": 90,
"statements": 90,
"functions": 90,
"branches": 90,
"include": [
"apollo-server/**/*.js",
"src/**/*.{js,vue}"
],
"exclude": [
"apollo-server/*.js",
"src/*.js",
],
"reporter": [
"lcov",
"text",
"text-summary"
],
"extension": [
".js"
],
"cache": true,
"all": true
}
nyc vue-cli-service test:unit
nodemon --exec nyc vue-cli-service test:unit
PS: I also recommend adding coverage
and .nyc_output
to your .gitignore
.
@caugner
Hi,
I followed your steps but something gone wrong. I'm getting Unable to lookup source:
error. src/components
showed twice in paths so i couldn't preview coverage report.
What is your istanbul-instrumenter-loader
version and babel-plugin-istanbul
version?
Also, my package.json
{
"name": "tempus",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
"test:unit": "nyc vue-cli-service test:unit",
"test:e2e": "vue-cli-service test:e2e"
},
"dependencies": {
"bulma": "^0.7.1",
"bulma-timeline": "^3.0.0",
"register-service-worker": "^1.0.0",
"vue": "^2.5.16",
"vue-router": "^3.0.1",
"vuex": "^3.0.1"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^3.0.0-rc.9",
"@vue/cli-plugin-e2e-nightwatch": "^3.0.0-rc.9",
"@vue/cli-plugin-eslint": "^3.0.0-rc.9",
"@vue/cli-plugin-pwa": "^3.0.0-rc.9",
"@vue/cli-plugin-unit-mocha": "^3.0.0-rc.9",
"@vue/cli-service": "^3.0.0-rc.9",
"@vue/eslint-config-airbnb": "^3.0.0-rc.9",
"@vue/test-utils": "^1.0.0-beta.20",
"babel-plugin-istanbul": "^4.1.6",
"chai": "^4.1.2",
"istanbul-instrumenter-loader": "^3.0.1",
"node-sass": "^4.9.0",
"nyc": "^12.0.2",
"sass-loader": "^7.0.1",
"vue-template-compiler": "^2.5.16"
},
"nyc": {
"check-coverage": true,
"per-file": true,
"lines": 90,
"statements": 90,
"functions": 90,
"branches": 90,
"include": [
"src/**/*.{js,vue}"
],
"exclude": [
"src/*.js"
],
"reporter": [
"lcov",
"text-summary"
],
"extension": [
".js"
],
"cache": true,
"all": true
}
}
And my vue.config.js
module.exports = {
chainWebpack: (config) => {
if (process.env.NODE_ENV !== 'production') {
config.module
.rule('istanbul')
.test(/\.(js|vue)$/)
.enforce('post')
.include.add('src')
.end()
.use('istanbul-instrumenter-loader')
.loader('istanbul-instrumenter-loader')
.options({ esModules: true })
.end();
}
},
};
@caugner thanks, your solution works for me if I use this as babel.config.js
:
module.exports = {
presets: [
'@vue/app'
],
plugins: [
'babel-plugin-istanbul'
]
}
Thanks @caugner , That solution worked for me as well.
I ran across the same issue as @yusufkaracin and setting config.devtool('eval')
in my vue.config.js
, just above config.module
seems to have fixed the source-mapping for vue components.
I got that from this issue.
@caugner can you make example repository on github ? i can't make it work. Very frustrated. I can't find where vue.config.js locate in. Should have use Jest for testing instead of waste time configure this.
I know that coverage is included in Jest by default, should we generate the coverage configuration described above when creating a new Vue app with the Mocha+Chai test options?
I have updated to vue-cli 3.0.4 and nothing is working. @caugner Do you still have a working setup ?
Does anyone have a working example project for test coverage for vue-cli 3.0.x with vue-cli-mocha-plugin? There are very little examples and the snippets we found do not work.
In later version of webpack (shipped in vue-cli) the include.add('src')
will resulted in errors, here is my work around:
const path = require('path')
if (process.env.NODE_ENV !== 'production') {
config.devtool('eval')
config.module
.rule('istanbul')
.test(/\.(js|vue)$/)
.enforce('post')
.include
.add(path.resolve(__dirname, '/src'))
.end()
.use('istanbul-instrumenter-loader')
.loader('istanbul-instrumenter-loader')
.options({ esModules: true })
}
I had similar problems and neither @oimou nor @caugner solutions worked.
I finally could track down the mistake:
I put my tests next to my sources, rather than having all tests inside another folder.
When I added the istanbul-instrumenter-loader
to my webpack config via vue.config.js
I only tested for /\.js$/
which also would include my test files.
Because my test also includes (require) the subject component, obviously, it would be loaded twice. I found this line which causes the
Module build failed (from ./node_modules/istanbul-instrumenter-loader/dist/cjs.js):
TypeError: Cannot read property 'fileCoverage' of undefined
error messages.
I can not get this working and I have the same issue as @jdoubleu when i created a project using vue-cli@3.2 . It produces a coverage folder but there is no line coverage in the report. just the same as the out put of the cli below.
I have the same nyc config in my package.json as @yusufkaracin
My vue.config.js file
const path = require('path')
module.exports = {
chainWebpack: (config) => {
var test = path.resolve(__dirname, 'test');
var src = path.resolve(__dirname, 'src');
var nodes = path.resolve(__dirname, 'node_modules');
config.module
.rule('istanbul')
.test(/\.(js)$/)
.enforce('post')
.include.add(test).add(src)
.end()
.exclude.add(nodes)
.end()
.use('istanbul-instrumenter-loader')
.loader('istanbul-instrumenter-loader')
.options({ produceSourceMap: true, esModules: true });
}
}
one error printed
WEBPACK Failed to compile with 1 error(s)
Error in ./src/components/HelloWorld.vue?vue&type=script&lang=js&
Module build failed (from ./node_modules/istanbul-instrumenter-loader/dist/cjs.js):
TypeError: Cannot read property 'fileCoverage' of undefined
ERROR mocha-webpack exited with code 1.
=============================== Coverage summary ==================
Statements : Unknown% ( 0/0 )
Branches : Unknown% ( 0/0 )
Functions : Unknown% ( 0/0 )
Lines : Unknown% ( 0/0 )
================================================================
I could finally fix the issue for me and it slightly differs from @caugner solution.
Disclaimer: My environment might differ from yours:
src/renderer/index.js
)Assuming you have already install the mocha plugin.
Install the istanbul-instrumenter-loader
webpack plugin since we are using the webpack build system.
I think there is no need to install the babel-plugin-istanbul
because we are already using the webpack plugin. However they might also work together somehow.
Add the istanbul-instrumenter-loader
to your webpack config using vue-cli's chainWebpack
option:
module.exports = {
...
chainWebpack: config => {
...
if (isTesting) {
config.module.rule('js')
.use('istanbul')
.loader('istanbul-instrumenter-loader')
.options({ esModules: true })
.before('babel-loader')
config.output
.devtoolModuleFilenameTemplate('[absolute-resource-path]')
.devtoolFallbackModuleFilenameTemplate('[absolute-resource-path]?[hash]')
config.devtool('inline-cheap-module-source-map')
}
}
}
Important: Insert the istanbul-instrumenter-loader
before the babel-loader
! This caused the
TypeError: Cannot read property 'fileCoverage' of undefined
~~error messages. I guess it had something todo with babel's transformation and he probable reuse of modules inside webpack (as describe in my earlier comment).
I'm not 100% sure if this breaks code coverage for modules written in ES6+ which are transpiled by babel after the istanbul-instrumenter-loader
. So far all my modules looked okay.~~
Update your test command to include all files (even vue). This is required so the instrument loader will also take non tested files into account. Also wrap the test command with nyc
In my case I changed the following scripts in my package.json
:
"test:unit": "vue-cli-service test:unit 'src/renderer/**/*.spec.js'",
"coverage:unit": "nyc vue-cli-service test:unit 'src/renderer/**/*.{js,vue}'"
(optional) Add a nycrc
file:
{
"instrument": false,
"sourceMap": false,
"reporter": [
"lcov",
"text",
"text-summary"
],
"exclude": [
"src/renderer/**/*.spec.js",
"src/renderer/__mocks__/"
]
}
At the end this worked for me and the coverage of normal modules seems to be accurate. However I couldn't get coverage reports of .vue
files to work (there's an issue).
And I don't know if placing the istanbul-instrumenter-loader
before the babel-loader
has any drawbacks.
Update: Using before caused the coverage to fail because of exceeded memory usage (FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
).
A quick test showed, that only the post()
webpack-chain shorthand does not work.
The istanbul-instrument-loader
is included after the babel-loader
now, I guess.
My configuration changed to that (vue.config.js
):
...
config.module.rule('js')
.use('istanbul')
.loader('istanbul-instrumenter-loader')
.options({ esModules: true })
...
I can not get this working and I have the same issue as @jdoubleu when i created a project using vue-cli@3.2 . It produces a coverage folder but there is no line coverage in the report. just the same as the out put of the cli below.
I have the same nyc config in my package.json as @yusufkaracin
My vue.config.js file
const path = require('path') module.exports = { chainWebpack: (config) => { var test = path.resolve(__dirname, 'test'); var src = path.resolve(__dirname, 'src'); var nodes = path.resolve(__dirname, 'node_modules'); config.module .rule('istanbul') .test(/\.(js)$/) .enforce('post') .include.add(test).add(src) .end() .exclude.add(nodes) .end() .use('istanbul-instrumenter-loader') .loader('istanbul-instrumenter-loader') .options({ produceSourceMap: true, esModules: true }); } }
one error printed WEBPACK Failed to compile with 1 error(s) Error in ./src/components/HelloWorld.vue?vue&type=script&lang=js& Module build failed (from ./node_modules/istanbul-instrumenter-loader/dist/cjs.js): TypeError: Cannot read property 'fileCoverage' of undefined ERROR mocha-webpack exited with code 1. =============================== Coverage summary ================== Statements : Unknown% ( 0/0 ) Branches : Unknown% ( 0/0 ) Functions : Unknown% ( 0/0 ) Lines : Unknown% ( 0/0 ) ================================================================
@martinnaughton I had similar problems, did you solve this problem?
I am also getting this error. Couldn't find out any solution...
Module build failed (from ./node_modules/istanbul-instrumenter-loader/dist/cjs.js):
TypeError: Cannot read property 'fileCoverage' of undefined
I can not get this working and I have the same issue as @jdoubleu when i created a project using vue-cli@3.2 . It produces a coverage folder but there is no line coverage in the report. just the same as the out put of the cli below. I have the same nyc config in my package.json as @yusufkaracin My vue.config.js file
const path = require('path') module.exports = { chainWebpack: (config) => { var test = path.resolve(__dirname, 'test'); var src = path.resolve(__dirname, 'src'); var nodes = path.resolve(__dirname, 'node_modules'); config.module .rule('istanbul') .test(/\.(js)$/) .enforce('post') .include.add(test).add(src) .end() .exclude.add(nodes) .end() .use('istanbul-instrumenter-loader') .loader('istanbul-instrumenter-loader') .options({ produceSourceMap: true, esModules: true }); } }
one error printed WEBPACK Failed to compile with 1 error(s) Error in ./src/components/HelloWorld.vue?vue&type=script&lang=js& Module build failed (from ./node_modules/istanbul-instrumenter-loader/dist/cjs.js): TypeError: Cannot read property 'fileCoverage' of undefined ERROR mocha-webpack exited with code 1. =============================== Coverage summary ================== Statements : Unknown% ( 0/0 ) Branches : Unknown% ( 0/0 ) Functions : Unknown% ( 0/0 ) Lines : Unknown% ( 0/0 ) ================================================================
@martinnaughton I had similar problems, did you solve this problem?
Im also having this problem, I'm also using Typescript and followed this tutorial for typescript https://istanbul.js.org/docs/tutorials/typescript/
This config is working for me, sort of :
devtool: 'eval-source-map'
// ...
config.module
.rule('js')
.use('istanbul')
.loader('istanbul-instrumenter-loader')
.options({ esModules: true })
.before('babel-loader')
// and the same for rule('ts')
And I removed babel-plugin-istanbul
For .vue files, the fixWebpackSourcePaths
options of karma-coverage-istanbul-reporter looks promising (it cleans the resource path from vue-loader which contains the loaders string and query parameters)
can anyone help me I'm using
@vue/cli-plugin-unit-mocha and Typescript,
added this in my vue.config.js
const path = require('path')
config.module
.rule('istanbul')
.test(/\.(ts|vue)$/)
.enforce('post')
.include.add(path.resolve(__dirname, '/src'))
.end()
.use('istanbul-instrumenter-loader')
.loader('istanbul-instrumenter-loader')
.options({ esModules: true })
here my nyc config
"nyc": {
"check-coverage": true,
"per-file": true,
"lines": 90,
"statements": 90,
"functions": 90,
"branches": 90,
"include": [
"src/**/*.{ts,vue}"
],
"reporter": [
"lcov",
"text-summary"
],
"extension": [
".ts", "*.vue"
],
"cache": true,
"all": true
}
all tests passing, but no coverage generated.
337 passing (18s)
3 pending
MOCHA Tests completed successfully
=============================== Coverage summary ===============================
Statements : Unknown% ( 0/0 )
Branches : Unknown% ( 0/0 )
Functions : Unknown% ( 0/0 )
Lines : Unknown% ( 0/0 )
================================================================================
@silva96 There are maybe other issues but I'm pretty sure you need to remove the slash from '/src'
. And maybe remove the from `".vue"` too.
thanks @rndmerle I fixed that and then the error decribed by others appeared.
Module build failed (from ./node_modules/istanbul-instrumenter-loader/dist/cjs.js):
TypeError: Cannot read property 'fileCoverage' of undefined
Using a dedicated post-rule never worked for me either. What did work was to plug istanbul before babel-loader/ts-loader and cache-loader:
config.module
.rule('js')
.use('istanbul')
.loader('istanbul-instrumenter-loader')
.options({ esModules: true })
.after('cache-loader')
config.module
.rule('ts')
.use('istanbul')
.loader('istanbul-instrumenter-loader')
.options({ esModules: true })
.after('cache-loader')
Make sure to check the resulting rules with vue inspect
.
Using a dedicated post-rule never worked for me either. What did work was to plug istanbul before babel-loader/ts-loader and cache-loader:
config.module .rule('js') .use('istanbul') .loader('istanbul-instrumenter-loader') .options({ esModules: true }) .after('cache-loader') config.module .rule('ts') .use('istanbul') .loader('istanbul-instrumenter-loader') .options({ esModules: true }) .after('cache-loader')
Make sure to check the resulting rules with
vue inspect
.
@rndmerle that didn't make the trick I believe, can you provide your config nyc in package.json, babel config and vue.config.js ?
Here are the config files. However, I'm not using Mocha at all. I came across this thread while trying to configure the coverage on Cypress tests.
.nyrc.json
{
"include": [
"src/**/*.{ts,js,vue}"
],
"exclude": [
"**/*.{spec,test}.{js,ts}",
"**/*.d.ts",
"*/types/**/*.ts"
],
"extension": [
".ts",
".js",
".vue"
],
"all": true,
"check-coverage": false
}
babel.config.js
module.exports = {
plugins: process.env.COVERAGE === 'true' ? ['istanbul'] : [],
presets: ['@vue/app'],
}
There is nothing relevant anymore in vue.config.js because I switched from istanbul-instrumenter-loader to babel-plugin-istanbul. Both were working tho.
@rndmerle unfortunately it didn't work switching from istanbul-instrumenter-loader to babel-plugin-istanbul
it gives me this error now.
MOCHA Testing...
RUNTIME EXCEPTION Exception occurred while loading your tests
TypeError: Cannot read property 'f' of undefined
at Module.getTimezones (/Users/benja/dev/ventanilla-front/dist/webpack:/src/utils/functions.ts:62:1)
at Module../src/store/modules/settings/getters.ts (/Users/benja/dev/ventanilla-front/dist/webpack:/src/store/modules/settings/getters.ts:35:1)
at __webpack_require__ (/Users/benja/dev/ventanilla-front/dist/webpack:/webpack/bootstrap:25:1)
at Module../src/store/modules/settings/index.ts (/Users/benja/dev/ventanilla-front/dist/main.js:408493:66)
at __webpack_require__ (/Users/benja/dev/ventanilla-front/dist/webpack:/webpack/bootstrap:25:1)
at Module../src/store/index.ts (/Users/benja/dev/ventanilla-front/dist/main.js:372220:75)
at __webpack_require__ (/Users/benja/dev/ventanilla-front/dist/webpack:/webpack/bootstrap:25:1)
at Module../src/utils/functions.ts (/Users/benja/dev/ventanilla-front/dist/main.js:418113:64)
at __webpack_require__ (/Users/benja/dev/ventanilla-front/dist/webpack:/webpack/bootstrap:25:1)
at Module../node_modules/cache-loader/dist/cjs.js?!./node_modules/babel-loader/lib/index.js!./node_modules/ts-loader/index.js?!./node_modules/cache-loader/dist/cjs.js?!./node_modules/vue-loader/lib/index.js?!./src/components/inputs/types/SeatSelectInput.vue?vue&type=script&lang=ts& (/Users/benja/dev/ventanilla-front/dist/main.js:32054:74)
at __webpack_require__ (/Users/benja/dev/ventanilla-front/dist/webpack:/webpack/bootstrap:25:1)
at Module../src/components/inputs/types/SeatSelectInput.vue?vue&type=script&lang=ts& (/Users/benja/dev/ventanilla-front/dist/webpack:/src/components/inputs/types/SeatSelectInput.vue?1a11:1:1)
at __webpack_require__ (/Users/benja/dev/ventanilla-front/dist/webpack:/webpack/bootstrap:25:1)
at Module../src/components/inputs/types/SeatSelectInput.vue (/Users/benja/dev/ventanilla-front/dist/webpack:/src/components/inputs/types/SeatSelectInput.vue?c837:1:1)
at __webpack_require__ (/Users/benja/dev/ventanilla-front/dist/webpack:/webpack/bootstrap:25:1)
at Module../node_modules/cache-loader/dist/cjs.js?!./node_modules/babel-loader/lib/index.js!./node_modules/ts-loader/index.js?!./node_modules/cache-loader/dist/cjs.js?!./node_modules/vue-loader/lib/index.js?!./src/components/inputs/types/SeatMapBuilder.vue?vue&type=script&lang=ts& (/Users/benja/dev/ventanilla-front/dist/main.js:30215:102)
at __webpack_require__ (/Users/benja/dev/ventanilla-front/dist/webpack:/webpack/bootstrap:25:1)
at Module../src/components/inputs/types/SeatMapBuilder.vue?vue&type=script&lang=ts& (/Users/benja/dev/ventanilla-front/dist/webpack:/src/components/inputs/types/SeatMapBuilder.vue?a97d:1:1)
at __webpack_require__ (/Users/benja/dev/ventanilla-front/dist/webpack:/webpack/bootstrap:25:1)
at Module../src/components/inputs/types/SeatMapBuilder.vue (/Users/benja/dev/ventanilla-front/dist/webpack:/src/components/inputs/types/SeatMapBuilder.vue?56f0:1:1)
at __webpack_require__ (/Users/benja/dev/ventanilla-front/dist/webpack:/webpack/bootstrap:25:1)
at Module../tests/unit/components/inputs/types/SeatMapBuilder.spec.ts (/Users/benja/dev/ventanilla-front/dist/main.js:424121:101)
at __webpack_require__ (/Users/benja/dev/ventanilla-front/dist/webpack:/webpack/bootstrap:25:1)
at run (/Users/benja/dev/ventanilla-front/dist/webpack:/node_modules/mocha-webpack/lib/entry.js:3:1)
at Array.forEach (<anonymous>)
at Object../node_modules/mocha-webpack/lib/entry.js (/Users/benja/dev/ventanilla-front/dist/webpack:/node_modules/mocha-webpack/lib/entry.js:10:1)
at __webpack_require__ (/Users/benja/dev/ventanilla-front/dist/webpack:/webpack/bootstrap:25:1)
at /Users/benja/dev/ventanilla-front/dist/webpack:/webpack/bootstrap:116:1
at Object.<anonymous> (/Users/benja/dev/ventanilla-front/dist/main.js:120:10)
at Module._compile (internal/modules/cjs/loader.js:723:30)
at Module.replacementCompile (/Users/benja/dev/ventanilla-front/node_modules/append-transform/index.js:58:13)
at _module2.default._extensions.(anonymous function) (/Users/benja/dev/ventanilla-front/node_modules/mocha-webpack/lib/util/registerRequireHook.js:148:12)
at Object.<anonymous> (/Users/benja/dev/ventanilla-front/node_modules/append-transform/index.js:62:4)
at Module.load (internal/modules/cjs/loader.js:620:32)
at tryModuleLoad (internal/modules/cjs/loader.js:560:12)
at Function.Module._load (internal/modules/cjs/loader.js:552:3)
at Module.require (internal/modules/cjs/loader.js:659:17)
at require (internal/modules/cjs/helpers.js:22:18)
at /Users/benja/dev/ventanilla-front/node_modules/mocha/lib/mocha.js:250:27
at Array.forEach (<anonymous>)
at Mocha.loadFiles (/Users/benja/dev/ventanilla-front/node_modules/mocha/lib/mocha.js:247:14)
at Mocha.run (/Users/benja/dev/ventanilla-front/node_modules/mocha/lib/mocha.js:576:10)
at /Users/benja/dev/ventanilla-front/node_modules/mocha-webpack/lib/runner/TestRunner.js:191:27
at /Users/benja/dev/ventanilla-front/node_modules/mocha-webpack/lib/webpack/compiler/registerReadyCallback.js:26:7
at AsyncSeriesHook.eval [as callAsync] (eval at create (/Users/benja/dev/ventanilla-front/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:63:1)
at AsyncSeriesHook.lazyCompileHook (/Users/benja/dev/ventanilla-front/node_modules/tapable/lib/Hook.js:154:20)
at emitRecords.err (/Users/benja/dev/ventanilla-front/node_modules/webpack/lib/Compiler.js:267:22)
at Compiler.emitRecords (/Users/benja/dev/ventanilla-front/node_modules/webpack/lib/Compiler.js:449:39)
at emitAssets.err (/Users/benja/dev/ventanilla-front/node_modules/webpack/lib/Compiler.js:261:10)
at hooks.afterEmit.callAsync.err (/Users/benja/dev/ventanilla-front/node_modules/webpack/lib/Compiler.js:435:14)
at _err0 (eval at create (/Users/benja/dev/ventanilla-front/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:16:1)
at callback (/Users/benja/dev/ventanilla-front/node_modules/copy-webpack-plugin/dist/index.js:126:17)
at afterEmit (/Users/benja/dev/ventanilla-front/node_modules/copy-webpack-plugin/dist/index.js:220:13)
at AsyncSeriesHook.eval [as callAsync] (eval at create (/Users/benja/dev/ventanilla-front/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:12:1)
at AsyncSeriesHook.lazyCompileHook (/Users/benja/dev/ventanilla-front/node_modules/tapable/lib/Hook.js:154:20)
at asyncLib.forEachLimit.err (/Users/benja/dev/ventanilla-front/node_modules/webpack/lib/Compiler.js:432:27)
at /Users/benja/dev/ventanilla-front/node_modules/neo-async/async.js:2818:7
at done (/Users/benja/dev/ventanilla-front/node_modules/neo-async/async.js:3522:9)
at MemoryFileSystem.writeFile (/Users/benja/dev/ventanilla-front/node_modules/memory-fs/lib/MemoryFileSystem.js:328:9)
at writeOut (/Users/benja/dev/ventanilla-front/node_modules/webpack/lib/Compiler.js:415:30)
at asyncLib.forEachLimit (/Users/benja/dev/ventanilla-front/node_modules/webpack/lib/Compiler.js:426:7)
at objectIteratorWithKey (/Users/benja/dev/ventanilla-front/node_modules/neo-async/async.js:3509:9)
at timesSync (/Users/benja/dev/ventanilla-front/node_modules/neo-async/async.js:2297:7)
at Object.eachLimit (/Users/benja/dev/ventanilla-front/node_modules/neo-async/async.js:3463:5)
at emitFiles (/Users/benja/dev/ventanilla-front/node_modules/webpack/lib/Compiler.js:321:13)
at Immediate._onImmediate (/Users/benja/dev/ventanilla-front/node_modules/memory-fs/lib/MemoryFileSystem.js:288:4)
at processImmediate (timers.js:632:19)
ERROR mocha-webpack exited with code 1.
=============================== Coverage summary ===============================
Statements : Unknown% ( 0/0 )
Branches : Unknown% ( 0/0 )
Functions : Unknown% ( 0/0 )
Lines : Unknown% ( 0/0 )
================================================================================
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! ventas-frontend@0.1.0 test:unit: `nyc vue-cli-service test:unit --require ./tests/unit/setup.js --timeout 10000`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the ventas-frontend@0.1.0 test:unit script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! /Users/benja/.npm/_logs/2019-06-26T15_44_03_366Z-debug.log
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! ventas-frontend@0.1.0 test: `npm run test:unit`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the ventas-frontend@0.1.0 test script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! /Users/benja/.npm/_logs/2019-06-26T15_44_03_396Z-debug.log
Based on @caugner 's answer, I made it work in a simpler way (by skipping the step 2 and enhanced a bit the nyc configuration in package.json) I'm using Vue CLI-3 with Mocha-webpack as my tests runner.
Here's my current configuration:
npm install --save-dev babel-plugin-istanbul
// babel.config.js
module.exports = {
presets: [
'@vue/app'
],
env: {
test: {
plugins: [
['istanbul', {
useInlineSourceMaps: false
}]
]
}
}
};
nyc
+ configure it in nyc.config.jsnpm install nyc --save-dev
// nyc.config.js
module.exports = {
'check-coverage': false,
'per-file': true,
'skip-full': true,
all: true,
include: [
'src/**/*.{js,vue}'
],
exclude: [
'src/*.js',
'**/index.js'
],
reporter: [
'lcov',
'text',
'text-summary'
],
extension: [
'.js',
'.vue'
]
};
nyc vue-cli-service test:unit --require tests/setup.js
No more errors or anything else. I'm not sure if I am missing something but at first sight, coverage report seems to represent the reality of tests scenarios I've created so far.
EDIT: Updated configuration to fix wrong .vue file paths in the coverage report and enhance it to my personal taste
@stephsavoie Your solution is worked, Thanks a lot.
@stephsavoie with that solution my nyc
output is only showing one .vue
file, not all of them.
None of the solutions on here worked for me (either Vue files were excluded, or the line numbers and highlighting in all files was thrown off in the coverage reports). Basically, setting devtool
to eval
throws off line numbers, but setting it to cheap-module-eval-source-map
results in duplication in Vue file paths, throwing Istanbul off.
There's an (admittedly hacky) way to fix this, and it involves just changing one line in one of Istanbul/nyc's dependencies. From the directory containing your vue.config.js
file and node_modules
directory, you can run this to change the line:
sed -i '' 's/source: pathutils.relativeTo(start.source, origFile),/source: origFile,/' node_modules/istanbul-lib-source-maps/lib/get-mapping.js
Of course, that's annoying to have to do every time the file gets changed (I'm looking at you, yarn), so you can automate running that script every time you go to run your tests.
Just for the sake of completeness, I wrote up a short gist that details everything you need to do to add tests (with coverage) to a Vue project: https://gist.github.com/lsapan/3bfd0ffc0fb3d4a036fce84f6eea142e
@stephsavoie thank you, your solution worked for me, but I'm wondering about the idea behind using tests/setup.js, what's the purpose of it as you did not post the content of this file?
@stephsavoie This works great, however once I upgraded from vue cli3 to version 4, it no longer works. Have you had any luck with the newer version of the cli?
I tried a bunch of things but still nyc report is not loading with vue files. Did anyone succeed with vue-cli-4?
@batuhantozun did you try my guide above? Itβs a bit hacky, but it works.
https://gist.github.com/lsapan/3bfd0ffc0fb3d4a036fce84f6eea142e
Hello for me juste work with
Script in package.json
nyc vue-cli-service test:unit
.nycrc:
{
"extension": [
".js",
".vue"
],
"instrument": false,
"sourceMap": false
}
vue.config.js:
module.exports = {
chainWebpack: (config) => {
if (process.env.NODE_ENV === 'test') {
config.module.rule('js')
.test(/\.js$/)
.use('istanbul-instrumenter-loader')
.loader('istanbul-instrumenter-loader')
.options({
esModules: true,
});
}
},
};
Packages: @vue/cli: 4.3.0 @vue/test-utils: 1.0.0-beta.32 vue: 2.6.11 istanbul-instrumenter-loader: 3.0.1 nyc: 15.0.1
Edit:
Like sayed @lsapan in gist istanbul duplicate the path for .vue
files because in source maps the path of source looks like
{
"source": ["file.vue"],
"sourceRoot": ["/src/components/" ]
}
This path it's computed in /src/components/file.vue
and istanbul build path of file with
path.resolve(path.dirname(origFile), file)
origFile
it's the absolute path of vue file and file
it's path from source map.
So this produce path like /absolute/path/src/components/src/components/file.vue
The js files doesn't have this problems becauses the source it's absolute path (ex: /absolute/path/src/plugins/file.js
).
I don't find the option to custom the source for vue file to obtain the absolute path in source,
The generation of source map seems correct for me. For me the problem is in istanbul.js so I have comment this issue to correct the build path in this case. https://github.com/istanbuljs/istanbuljs/issues/464#issuecomment-610258911
@sebtiz13 config worked for me!
Hey, @arielj which version of vue-cli are you using? Are you sure that in your coverage html report it generates you are seeing vue components not test files.
@stripathix I see code coverage information for the components (not the test files) but I do have that problem on the duplicated src/components
string on the path so I can't see the code coverage details line by line on each component (it looks like the data is inside the json report, though), only the table with statements, branches, functions, lines %.
I have vue 2.6.11 and vue-cli-service 4.2.0 inside packages.json
Hi all, sorry if it's an obvious question, but I'm new to the Vue. I have followed some of the examples here and now I am getting the coverage for all .vue components, but .js files just show 100 percent coverage, regardless If test exists or not. I must be missing something obvious?
I've tried a few of the solutions here on a Vue CLI (version 4.4.6
, uses TypeScript) project with no luck - either I get 0% coverage across the board or it shows coverage for .js
and/or .ts
files but not .vue
files - maybe that's just me being an idiot and expecting something that's not supposed to be there? Is it going to show the .vue
files as .js
or something like that?
Have a repro up here of the 0% coverage cropping up: https://github.com/Jack-Barry/vue-with-istanbul
Not really sure where to go from here. Feels like I'm in the right neighborhood but walked into the wrong building or something.
Edit: with some tweaks to the config in the demo repo, I've been able to get closer to the goal but still seeing 0% coverage
HelloWorld.vue
β renders props.msg when passed
1 passing (30ms)
MOCHA Tests completed successfully
----------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------------|---------|----------|---------|---------|-------------------
All files | 0 | 0 | 0 | 0 |
HelloWorld.vue | 0 | 0 | 0 | 0 |
----------------|---------|----------|---------|---------|-------------------
Is there anyone who could get it working with TypeScript so far π’?
Another comment here to bump this every other month π
@undergroundwires: @rndmerle's comment works for code coverage when using typescript. I got it working with Vue 2.6 as follows:
npm install nyc istanbul-instrumenter-loader cross-env --save-dev
// ... other options
,
chainWebpack: config => {
if (process.env.coverage === "true") {
config.module
.rule("ts")
.use("istanbul")
.loader("istanbul-instrumenter-loader")
.options({ esModules: true })
.before("ts-loader");
}
}
module.exports = {
all: true,
instrument: false,
sourceMap: false,
include: ["src/**/*.{ts,vue}"],
reporter: ["lcov", "text", "text-summary"],
extension: [".ts", ".vue"]
};
"scripts": {
"test:unit": "cross-env coverage=true nyc vue-cli-service test:unit",
},
Hi @bingnz , thanks for your time and effort into compiling such a nice solution ππΏ It works cleanly and reports in a pretty way.
However the problem I find with this and other solutions is that they do not report untested classes. So the coverage result is always so high which in fact is not so useful. So all: true
in nyc.config.js
is not working π’
Bump for a way to view coverage on Mocha test suite. Going to try Wallaby for now. EDIT: Even Wallaby runs coverage via Jest. This may as well be the only option for testing if you want coverage reports. EDIT 2: I may have spoken too soon. The auto config is for Jest. Will report my findings on Manual configs. EDIT 3: It works well. Support is good too. Even better than a test frameworks as it offers IDE-integrated hot reloading. Easily worth the subscription.
I am having an issue with sinon.js ounce I added the configuration for Istanbul the following started to happen and some tests are failing.
Warning in .node_modules/sinon/pkg/sinon-esm.js critical dependency: require function is used in a way which dependencies cannot be statically extracted.
Any examples of usage with nuxt ?
However the problem I find with this and other solutions is that they do not report untested classes.
Facing the same issue.
Is there an alternative unit test framework that has coverage built-in that is known to work with Vue? I've tried every iteration of this setup and can't get it to read anything other than js files.
What problem does this feature solve?
Coverage reporting for unit tests
What does the proposed API look like?
Is there a way to enable coverage for the mocha plugin? When set up manually on another project, you add the istanbul coverage instrumenter as a webpack loader like this:
And then you need to add
lcov
as a reporter.This explanation is pretty comprehensive: https://github.com/zinserjan/mocha-webpack/blob/master/docs/guides/code-coverage.md