vuejs / vue-jest

Jest Vue transformer
MIT License
748 stars 157 forks source link

Source map files disappear from coverage report #32

Closed eddyerburgh closed 3 years ago

eddyerburgh commented 6 years ago

Hi,

I'm getting coverage issues with Jest. When I set mapCoverage: true, some files disapear from the coverage report.

Example:

# mapCoverage:true
src/api                |      100 |      100 |      100 |      100 |                |
  index.js             |      100 |      100 |      100 |      100 |                |
  linkHeaderParser.js  |      100 |      100 |      100 |      100 |                |
  repositories.js      |      100 |      100 |      100 |      100 |                |
src/components         |     7.84 |     2.94 |     5.88 |    11.76 |                |
  FileExplorer.vue     |        0 |        0 |        0 |        0 |... 51,52,53,54 |
  MenuUserRepoList.vue |        0 |        0 |        0 |        0 |... 32,33,34,35 |
  Profile.vue          |        0 |        0 |        0 |        0 |... 57,58,59,60 |
  Readme.vue           |       80 |       50 |       50 |       80 |             23 |

# mapCoverage:false
src/api                |    92.86 |    84.21 |      100 |    92.86 |                |
  index.js             |    84.62 |    66.67 |      100 |    84.62 |          10,26 |
  linkHeaderParser.js  |      100 |      100 |      100 |      100 |                |
  repositories.js      |      100 |      100 |      100 |      100 |                |
  users.js             |      100 |      100 |      100 |      100 |                |
src/components         |     53.4 |    29.73 |    40.74 |    51.61 |                |
  FileExplorer.vue     |        0 |        0 |        0 |        0 |... 51,52,53,54 |
  FooterBar.vue        |    92.86 |       50 |      100 |      100 |        4,5,6,7 |
  MenuNavBar.vue       |      100 |       50 |      100 |      100 |       20,21,22 |
  MenuUserRepoList.vue |        0 |        0 |        0 |        0 |... 32,33,34,35 |
  Profile.vue          |        0 |        0 |        0 |        0 |... 57,58,59,60 |
  Readme.vue           |    94.74 |    57.14 |       80 |    92.86 |             25 |
  RepoListItem.vue     |      100 |       50 |    66.67 |      100 |       45,46,47 |

(I remove some file for a better readability. See full coverage report (link to travis build):

All sources files are available here: https://github.com/maxpou/gitvub and jest config here

Thank you

tmy commented 6 years ago

I created simple example: https://github.com/tmy/vue-jest-map-coverage-issue-sample

  1. Run vue init webpack vue-jest-map-coverage-issue-sample
    (https://circleci.com/gh/tmy/vue-jest-map-coverage-issue-sample/1)

    ----------------- ---------- ---------- ---------- ---------- ---------------- File % Stmts % Branch % Funcs % Lines Uncovered Lines
    All files 6.25 0 25 9.09
    src 0 0 0 0
    App.vue 0 0 0 0 ... 27,28,29,30
    src/components 100 100 100 100
    HelloWorld.vue 100 100 100 100
    ----------------- ---------- ---------- ---------- ---------- ----------------
  2. Edit src/components/HelloWorld.vue (https://circleci.com/gh/tmy/vue-jest-map-coverage-issue-sample/2)

    ---------- ---------- ---------- ---------- ---------- ---------------- File % Stmts % Branch % Funcs % Lines Uncovered Lines
    All files 0 0 0 0
    App.vue 0 0 0 0 ... 27,28,29,30
    ---------- ---------- ---------- ---------- ---------- ----------------
tsauvajon commented 6 years ago

I've had some issues aswell:

1/ Using an older version of vue-jest and the vue-cli webpack template, my colleague and I had different files listed on the code coverage with the same code (maybe some slight changes but definitely the same components, and imports)

2/ We migrated the source code to a more recent vue-cli webpack template that has jest "support" from scratch, and while we now have every single file listed contrary to before, it now displays a bunch of inexisting Uncovered lines, as @tmy 's coverage points out.

maxpou commented 6 years ago

Hi,

I'm the original author of this PR on vue-template/webpack repo

I think the problem come from Jest itself. I tried to switch to jest-vue-preprocessor (witch is an equivalent)... and I get similars issues. I'm not the only one who get issue with this coverage (example: https://github.com/vire/jest-vue-preprocessor/issues/41)

tsauvajon commented 6 years ago

I've got some updates on this issue: my coverage report is bugged on my Windows 10 machine (even with a fresh install of my repo), but testing inside Docker or on CircleCI provides a coverage report that seem correct.

EDIT: This is maybe a different issue as I have all of my files listed on the coverage, but with some inexisting Uncovered lines for every single .vue file...

maxpou commented 6 years ago

@tsauvajon are you sure about this? Configurations are the same? I can reproduce the same errored coverages on MacOS / Ubuntu (and also travis).

nirkki commented 6 years ago

Looks like the missing files lack the data property. If the component doesn't have the data segment it is dropped from the coverage report. Adding an empty segment is enough to get it included.

export default {
  name: 'HelloWorld',
  props: {
    msg: { type: String, default: 'Welcome to Your Vue.js App' }
  },
  data () {
    return {}
  }
}
tsauvajon commented 6 years ago

@maxpou 100% sure ! Yes the configs are the same.

@nirkki Ok, that seems very counter intuitive ! I'll try that, but no matter what I had different results on different machines with the same configuration...

I'll try to spend some time on this on the following weeks and will update this Issue.

gudatcomputers commented 6 years ago

@nirkki: I can confirm this fixed the exact same issue I had. Just added the data property back and coverage came in properly.

ycmjason commented 6 years ago

I have a problem with mapCoverage too. I have some components with no logic at all in it, only html. Something like the following:

GameInstruction.vue:

<template>
  <p>This game ... blah blah blah</p>
</template>

<script>
export default { }
</script>

<style></style>

And looks like Jest is picking up the coverage with this config:

module.exports = {
  'moduleFileExtensions': [
    'js',
    'json',
    'vue',
  ],
  'transform': {
    '.*\\.(vue)$': '<rootDir>/node_modules/vue-jest',
    '^.+\\.js$': '<rootDir>/node_modules/babel-jest',
  },
  'collectCoverage': true,
  'collectCoverageFrom': [
    'src/**/*.{js,vue}',
    '!**/node_modules/**',
  ],
  'coverageReporters': ['text', 'html', 'lcov'],
  'mapCoverage': true,
  'moduleDirectories': ['node_modules'],
  'moduleNameMapper': {
    '^@/(.*)$': '<rootDir>/src/$1',
  },
};

And the resulting coverage is 0%. 😢

I saw the comment mentioning about the absence of data() in component. So I tried adding the data() attribute and the coverage become 100%.

Is this the expected behaviour? Are we not suppose to have empty components that only have template?

nirkki commented 6 years ago

Definately not expected behaviour. I just happened to notice it when comparing files that were present in coverage and those which were not. As a temporary workaround I added the empty data segment and now the coverage works well! Well, I had to cleanup some scss files as well, but that is another story. Hope this gets fixed in some point, but I'm happy with the workaround until that.

ycmjason commented 6 years ago

Ok, coz I am new to testing in vue. I was just following the steps on the documentation on here and thought I was doing something wrong.

Alright, now at lease I now I am not the only one. I will just add data() as a work around then.

maxpou commented 6 years ago

Hi, Good spot @ycmjason ! As you mention, I added data() and it increase my coverage!

All files                 |    12.24 |     6.38 |     9.64 |    17.14 |                |
 src                      |        0 |        0 |        0 |        0 |                |
  App.vue                 |        0 |        0 |        0 |        0 |... 60,61,62,63 |
 src/api                  |      100 |      100 |      100 |      100 |                |
  index.js                |      100 |      100 |      100 |      100 |                |
  linkHeaderParser.js     |      100 |      100 |      100 |      100 |                |
  repositories.js         |      100 |      100 |      100 |      100 |                |
 src/components           |      6.9 |     1.47 |    13.16 |    11.76 |                |
  FileExplorer.vue        |        0 |        0 |        0 |        0 |... 59,60,61,62 |
  MenuLateral.vue         |        0 |        0 |        0 |        0 |      1,4,5,6,7 |
  MenuNavBar.vue          |       20 |        0 |    33.33 |       20 |    42,47,48,49 |
  MenuUserRepoList.vue    |        0 |        0 |        0 |        0 |... 32,33,34,35 |
  NotFound.vue            |        0 |        0 |        0 |        0 |... 33,34,35,36 |
  OfflineNotification.vue |       20 |        0 |       50 |       20 |    25,26,28,29 |
  Profile.vue             |        0 |        0 |        0 |        0 |... 58,59,60,61 |
  Readme.vue              |    83.33 |       50 |    66.67 |    83.33 |             31 |
  RepoList.vue            |       50 |      100 |       50 |       50 |             57 |
  RepositoryHeader.vue    |        0 |        0 |        0 |        0 |... 48,49,50,51 |
// ...

Now this 3 component got better coverage. That's cool. But there is still some missing files 😢

--------------------------|----------|----------|----------|----------|----------------|
File                      |  % Stmts | % Branch |  % Funcs |  % Lines |Uncovered Lines |
--------------------------|----------|----------|----------|----------|----------------|
All files                 |    30.85 |    20.75 |    25.93 |    35.06 |                |
 src                      |        0 |        0 |        0 |        0 |                |
  App.vue                 |        0 |        0 |        0 |        0 |... 60,61,62,63 |
 src/api                  |    92.31 |    84.21 |      100 |    92.31 |                |
  index.js                |    81.82 |    66.67 |      100 |    81.82 |          10,26 |
  linkHeaderParser.js     |      100 |      100 |      100 |      100 |                |
  repositories.js         |      100 |      100 |      100 |      100 |                |
  users.js                |      100 |      100 |      100 |      100 |                |
 src/components           |    33.68 |    20.63 |    26.92 |    36.84 |                |
  FileExplorer.vue        |        0 |        0 |        0 |        0 |... 59,60,61,62 |
  MenuLateral.vue         |        0 |        0 |        0 |        0 |      1,4,5,6,7 |
  MenuNavBar.vue          |    62.96 |    33.33 |       50 |    66.67 |    49,54,55,56 |
  MenuUserRepoList.vue    |        0 |        0 |        0 |        0 |... 32,33,34,35 |
  NotFound.vue            |        0 |        0 |        0 |        0 |... 33,34,35,36 |
  OfflineNotification.vue |       80 |       40 |       75 |    63.64 |    27,28,30,31 |
  Profile.vue             |        0 |        0 |        0 |        0 |... 58,59,60,61 |
  Readme.vue              |    94.74 |    57.14 |       80 |    92.86 |             25 |
  RepoList.vue            |       50 |    36.36 |    42.86 |     87.5 |             64 |
  RepositoryHeader.vue    |        0 |        0 |        0 |        0 |... 48,49,50,51 |

Now the file src/api/users.js appear (with 100% cc). But if I check in detail the HTML report created by Jest, everything is wrong in the .vue files (I mean the highlighted lines).

Ps: I also tried to put data() in every .vue files (even if there are no tests on these files) but it didn't change anything.

ycmjason commented 6 years ago

@maxpou I find removing collectCoverageFrom in the jest config can be useful as well for now before vue-jest fix the issue. Some components really contain no logic and should not write tests on it, then the coverage should not be collected.

maxpou commented 6 years ago

Hi, FYI I recently switch my project (the one with the examples above) under the new vue-cli architecture (v3 still in beta). and....everything works perfectly! :heart_eyes:

See related pull request and comments from the @codecov bot https://github.com/maxpou/gitvub/pull/43

The only thing that worry me is I don't know what's happened. Maybe Jest team works on mapCoverage option and fix this issue... see https://github.com/facebook/jest/pull/5177

ycmjason commented 6 years ago

Sounds awesome! I will try it out later. I though Jest has remove the option mapCoverage?

maxpou commented 6 years ago

yes this option is now deprecated!

nirkki commented 6 years ago

Still something strange going on with the data() -blocks. I have a bunch of more or less identical .vue -files and some got covered while some not. Just for test I moved the (this time non-empty) data () {} -section as last after methods & computed and suddenly coverage was correct! Moved then back to original place and coverage was 0%.

Strange thing is that there are some files where the data block is not the last but the coverage is still working as expected. Is this some sort of timing problem where the parallel tests somehow affect each other?

eddyerburgh commented 6 years ago

@nirkki What OS are you using?

Can you try deleting this line in the package and see if it solves the issue—https://github.com/vuejs/vue-jest/blob/master/vue-jest.js#L6

nirkki commented 6 years ago

Oh yes, removing getCacheKey solves the issue! I verified this on 3 different files that had the problem. OS is Windows 10.

eddyerburgh commented 6 years ago

I've removed cacheing in 2.1.1, can you see if this solved the issue?

nirkki commented 6 years ago

Updated to 2.1.1 This solved both coverage issues I had in my project: the need for empty data () declaration as well as the changed behaviour when the data section position within .vue -file was altered. So the coverage is now correct in my Windows 10 environment.

thequailman commented 6 years ago

Is the fix for this still to add an empty data () block? I'm on vue-jest 2.5.0 and this behavior still exists.

trylovetom commented 6 years ago

same here

raulcesar commented 6 years ago

Hi. I'm using vue-jest 2.5 with vue 2.5.16 and am also getting the problem with coverage. To try to isolate the problem, I'm running jest with --no-cache option, and I can confirm that putting in a data block will put the vue file in the coverage report, and taking it out will remove it. Just as a note, if I run without the --no-cache option, I get inconsistent results depending on what I ran.

raulcesar commented 6 years ago

Just to complement the information from my last post, I did some more testing and found that not only adding a data section will cause the file to appear in coverage, but also adding things like a "methods" or "computed" section with a dummy function or adding lifecyle hooks such as created will also "work". I'm not very familiar with jest, but running some debugging, it seems to me that the problem can be traced to when jest calls the istanbul function sourceMapStore.transformCoverage. At that point, it eliminates the vue components that don't have the aforementioned sections. It's as though it can't find any statements, functions or branches.

JFGHT commented 6 years ago

I'm also having this issue. Adding the data block combined with --no-cache helped partially. Why partially? Well, first let me briefly explain the project's composition:

I've split my component into these files: [comp1.html, comp1.scss, comp1.js, comp1.spec.js, index.vue].

Then, the index.vue is like this:

<template src="./comp1.html" />
<script src="./comp1.js"></script>
<style src="./comp1.scss" scoped lang="scss"></style>

So, after running the tests, the coverage is 100% on the index.vue but 0% on the comp1.js.

AndyWilson82 commented 6 years ago

Was a solution found for this other than adding the empty data? Using the latest versions of vue-jest, vue-cli (3.0.1) etc and only way I can get "dummy" components that have props only to appear in the coverage reports is to include the additional markup.

justinhelmer commented 6 years ago

@eddyerburgh I suggest we upgrade from jest@20.x to the latest (jest@23.x). Without complete context, the original description of this issue makes me think some of the problems in this thread may disappear. The mapCoverage method has been deprecated, "as it is no longer needed"

eddyerburgh commented 6 years ago

We can upgrade the dev dependency, but I believe this issue still stands. mapCoverage used to be required for Jest to use custom source maps, but now it searches for inline source maps by default.

This issue with source mapping still stands

kaidjohnson commented 5 years ago

I have been dealing with this issue setting up a new project. It can be reproduced using the latest vue-cli (3.0.5) and following the "Creating a Project" guide (https://cli.vuejs.org/guide/creating-a-project.html#vue-create).

vue create hello-world
> Manually select features
(x) Babel
(x) Unit Testing
> Jest
> In dedicated config files

Edit jest.config.js and add:

  collectCoverage: true,
  collectCoverageFrom: ['src/**/*.{js,vue}'],
  coverageReporters: ['text'],

Run npm run test:unit

Notice that HelloWorld.vue is missing from the test report.

Edit components/HelloWorld.vue and add in an empty data segment

data() {
  return {};
}

Run npm run test:unit again

Notice that HelloWorld.vue suddenly appears with its test coverage.

Thanks @nirkki for the workaround!! I have been parsing bug reports all evening with no luck as to what was causing this missing coverage.

The package.json that results from the vue-cli build:

{
  "name": "hello-world",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "test:unit": "vue-cli-service test:unit"
  },
  "dependencies": {
    "vue": "^2.5.17"
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "^3.0.5",
    "@vue/cli-plugin-unit-jest": "^3.0.5",
    "@vue/cli-service": "^3.0.5",
    "@vue/test-utils": "^1.0.0-beta.20",
    "babel-core": "7.0.0-bridge.0",
    "babel-jest": "^23.0.1",
    "vue-template-compiler": "^2.5.17"
  }
}

It's not a vue-cli issue, either, as I originally ran across the bug with a manual setup. In that scenario, the empty data segment also fixed the issue. That package json looks like:

{
  "name": "new-project",
  "version": "0.0.1",
  "description": "",
  "scripts": {
    "build": "webpack",
    "dev": "webpack-dev-server",
    "lint": "eslint 'src/**/*.{js,vue}'",
    "test": "jest",
    "tdd": "jest --watchAll"
  },
  "devDependencies": {
    "@babel/core": "7.1.2",
    "@babel/plugin-syntax-dynamic-import": "7.0.0",
    "@babel/preset-env": "7.1.0",
    "@vue/test-utils": "1.0.0-beta.25",
    "babel-core": "7.0.0-bridge.0",
    "babel-eslint": "10.0.1",
    "babel-jest": "23.6.0",
    "babel-loader": "8.0.4",
    "clean-webpack-plugin": "0.1.19",
    "eslint": "5.7.0",
    "eslint-plugin-jest": "21.26.1",
    "eslint-plugin-vue": "4.7.1",
    "html-webpack-plugin": "3.2.0",
    "jest": "23.6.0",
    "redux": "4.0.1",
    "reselect": "4.0.0",
    "vue": "2.5.17",
    "vue-cli": "2.9.6",
    "vue-jest": "3.0.0",
    "vue-loader": "15.4.2",
    "vue-router": "3.0.1",
    "vue-template-compiler": "2.5.17",
    "webpack": "4.22.0",
    "webpack-cli": "3.1.2",
    "webpack-dev-server": "3.1.10"
  }
}
larsalbrecht commented 5 years ago

I have also a strange issue. With the help from this issue-report, i could fix 2 files of 4. In short: 4 vue-files. 2 have now:

  data () {
    return {}
  }

THESE 2 files, will now be covered. The other 2 files have real data there (just an example):

  data () {
    return {
        items: [],
        somethingElse: []
    }
  }

Additional information (as mentioned by https://github.com/vuejs/vue-jest/issues/32#issuecomment-370217990) One file has:

implemented (in addition to data) the other uncovered file has:

These 2 files will not be under coverage, even with empty return{}. Project is created with vue-cli 2.9.6 webpack build.

With --no-cache it will works :-/

adamchenwei commented 5 years ago

that's crazy, why in the world we need to add data property so the component can be tested for vuejs component? and the ticket was opened since 2017............

is there something wrong with vue or with jest? any idea?

Having the same trouble even upgrade jest to latest as well as vue to 2.5 my deps

"dependencies": {
    "vue": "^2.5.17",
    "vue-router": "^3.0.1"
  },
  "devDependencies": {
    "@babel/core": "^7.1.2",
    "@babel/preset-env": "^7.1.5",
    "@storybook/vue": "^4.0.4",
    "@vue/test-utils": "^1.0.0-beta.25",
    "acorn": "^6.0.4",
    "babel-core": "^7.0.0-bridge.0",
    "babel-eslint": "^10.0.1",
    "babel-loader": "^8.0.4",
    "babel-preset-env": "^1.7.0",
    "babel-preset-vue": "^2.0.2",
    "clean-webpack-plugin": "^1.0.0",
    "copy-webpack-plugin": "^4.5.4",
    "css-loader": "^1.0.0",
    "eslint": "^5.9.0",
    "eslint-config-standard": "^12.0.0",
    "eslint-loader": "^2.1.1",
    "eslint-plugin-import": "^2.14.0",
    "eslint-plugin-node": "^7.0.1",
    "eslint-plugin-promise": "^4.0.1",
    "eslint-plugin-standard": "^4.0.0",
    "eslint-plugin-vue": "^4.7.1",
    "html-webpack-plugin": "^3.2.0",
    "jest": "^23.6.0",
    "mini-css-extract-plugin": "^0.4.4",
    "node-sass": "^4.10.0",
    "sass-loader": "^7.1.0",
    "style-loader": "^0.23.1",
    "vue-jest": "^3.0.0",
    "vue-loader": "^15.4.2",
    "vue-style-loader": "^4.1.2",
    "vue-template-compiler": "^2.5.17",
    "webpack": "^4.23.0",
    "webpack-bundle-analyzer": "^3.0.3",
    "webpack-cli": "^3.1.2",
    "webpack-dev-server": "^3.1.10",
    "webpack-merge": "^4.1.4"
  }
eddyerburgh commented 5 years ago

The issue will be fixed by this PR. Sorry for the delay.

rkomiyama commented 5 years ago

Has anybody gotten code coverage to work for functional components?

If I add data() to a functional component, it will show up in the list, but I'll have 0% coverage on it because it never hits the return {} line.

scniro commented 5 years ago

that's crazy, why in the world we need to add data property so the component can be tested for vuejs component? and the ticket was opened since 2017............

...Srsly 🤦‍♂

The issue will be fixed by this PR. Sorry for the delay.

Still seems to be an issue in 3.0.4. @eddyerburgh any updates by chance?

range-of-motion commented 5 years ago

Bump. @eddyerburgh–which vue-jest version fixes this?

rn4n commented 5 years ago

Is there a solution to this? It does not make much sense to create an empty data block only just for the file appears in coverage. 😞

Geminii commented 4 years ago

It's the same thing for ava, or mocha. I have never found a framework which work nyc and got a coverage to 100% without no tricks ... Even a simple Logo.vue doesn't got a coverage at 100% with 5 poor lines :'(

range-of-motion commented 4 years ago

People have already figured this out.. 🤦‍♂ It's because of the lack of a data property. Merely add the following to your component, and it will show up.

data() {
  return {
    // This solely exists to appear in the coverage report
  };
}
Geminii commented 4 years ago

@range-of-motion It changes nothing to add an empty data. Line are always incorrect and doesn't fix the coverage to 100% of the component :/ I got more uncovered line :(

range-of-motion commented 4 years ago

Right. But we're not gonna get much further with "this isn't working".. If you want this investigated, we need a test case.

Geminii commented 4 years ago

@range-of-motion I will create a repository to reproduce this. But on all subject that i could read, it's a problem between nyc and framework (jest, mocha, ava) about source map inline.