vue-jest
vue-jest copied to clipboard
Jest requires `--no-cache` for proper coverage
I have been digging into why many of our well tested components/views are not showing up on coverage reports, and I noticed that if I applied the --no-cache
flag to jest I started getting appropriate coverage numbers. There seems to be an issue with the vue-jest
caching mechanism that may be preventing some from getting appropriate coverage numbers.
We copied our settings from https://github.com/eddyerburgh/vue-test-utils-jest-example
I can confirm this issue on vue-enterprise-boilerplate. I've also noticed tests that should pass sometimes failing unless I clear the cache. If there's some information I can collect the next time it happens, I'm happy to post it here.
Any info is usefu:
- Jest version
- Node version
- OS version
Also, you could delete this line and see if it solves the issue—https://github.com/vuejs/vue-jest/blob/master/vue-jest.js#L6.
- Jest: v22.3.0
- Node: v9.5.0
- OS: macOS 10.13.3
I also just confirmed that deleting that line fixes the issue, so it does seem to be cache-related.
Does anyone have an example of a test that fails currently if the cache isn't cleared? I'd like to add a test case to the library when I fix the issue
The best solution right now might be to remove the getCacheKey function.
The getCacheKey
function is returning a different hash when the file data changes, so the issue could be with how Jest uses the cache key.
I don't have an example of a test that fails, as it's not a persistent problem. At some point, a test will start failing when it shouldn't and I'm not sure what the trigger is. Then I clear the cache and it's all good.
The coverage problem is very reproducible though. On vue-enterprise-boilerplate, running yarn jest --coverage
will consistently report 0% for every .vue
file unless you also add --no-cache
.
I'm unable to reproduce.
I cloned the vue-enterprise-boilerplate (which is great by the way 😀), ran yarn install
, and yarn jest --coverage
.
- node 9.5.0
- OS: macOS 10.12.6
Results:
---------------------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
---------------------|----------|----------|----------|----------|-------------------|
All files | 100 | 75 | 100 | 100 | |
components | 100 | 75 | 100 | 100 | |
_base-icon.vue | 100 | 100 | 100 | 100 | |
_base-input.vue | 100 | 100 | 100 | 100 | |
nav-bar-routes.vue | 100 | 75 | 100 | 100 | 19 |
nav-bar.vue | 100 | 100 | 100 | 100 | |
router/layouts | 100 | 100 | 100 | 100 | |
main.vue | 100 | 100 | 100 | 100 | |
router/views | 100 | 100 | 100 | 100 | |
home.vue | 100 | 100 | 100 | 100 | |
login.vue | 100 | 100 | 100 | 100 | |
profile.vue | 100 | 100 | 100 | 100 | |
---------------------|----------|----------|----------|----------|-------------------|
I think the solution is to remove the getCacheKey method temporarily.
So weird! I'm not sure if this is another option, but it looks like Facebook offers a createCacheKeyFunction
utility that may be useful to us. I apologize if you already know about it and it's not appropriate for our use case - I'm just starting to dig my head into this stuff. 😅
(And as an aside about the boilerplate, please don't hesitate to let me know if you have any suggestions/questions about how I'm managing unit tests there, including the global helpers in tests/unit/setup.js
. I'd be honored to get feedback from the test master himself!)
Thanks @chrisvfritz , I wasn't aware of that method. Would you be able to use it on this line—https://github.com/vuejs/vue-jest/blob/master/vue-jest.js#L6- and see if it fixes the issue. I'm still unable to reproduce the bug locally
Definitely! It looks like we need a list of files whose content can be used as a key. What do you recommend we use in our case?
Sorry, I didn't see this message! I've removed cacheing as a temporary fix in 2.1.1.
I believe we just use the filename, and then set getCacheKey to createCacheKeyFunction. It should be called with the correct arguments
I've been running --no-cache
for some time to get around this issue, if a second confirmation helps. Just stumbled across this bug as I was looking for the reason for the cache removal in 2.1.1
.
Same issue here, --no-cache
avoids the issue as well
After creating a project using vue init webpack my-project
I was getting 0% coverage for some Vue components. Just reporting in that --no-cache
fixed the issue as well. Hope this can help anyone who searches for this in Google.
I've also encountered @chrisvfritz 's issue with tests failing until the cache is cleared or jest is called with no-cache. Other people here are also encountering it on the same tests.
I also recently had this issue which was causing none of the .vue
files to show in the coverage reports. Running with --no-cache
resolved the issue.
I can confirm this issue still exists on [email protected]
and [email protected]
(and also with @vue/[email protected]
). Using --no-cache resolves the problem.
This issue came out of nowhere for me, took me way too long to recognize that it's a cache error.
FIX
All tests work again with adding --no-cache
to the test script:
"test:unit": "vue-cli-service test:unit --no-cache"
SETUP
"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",
...
}
jest.config.js
module.exports = {
moduleFileExtensions: ["js", "jsx", "json", "vue"],
verbose: true,
transform: {
"^.+\\.vue$": "vue-jest",
".+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$":
"jest-transform-stub",
"^.+\\.jsx?$": "babel-jest"
},
moduleNameMapper: {
"^@/(.*)$": "<rootDir>/src/$1"
},
snapshotSerializers: ["jest-serializer-vue"],
testMatch: [
"**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)"
],
testURL: "http://localhost/"
};
ERROR
Here is the error from console:
jest-haste-map: @providesModule naming collision:
Duplicate module name: _my-module_
Paths: C:\...\frontend\package.json collides with C:\...\frontend\src\package.json
This warning is caused by a @providesModule declaration with the same name across two different files.
FAIL tests/unit/App.spec.js
● Test suite failed to run
Cannot find module 'C:\...\frontend\node_modules\@babel\runtime/helpers/builtin/interopRequireDefault' from 'App.spec.js'
1 | import { shallowMount, createLocalVue } from "@vue/test-utils";
2 | import VueRouter from "vue-router";
> 3 | import App from "@/App.vue";
| ^
4 |
5 | const localVue = createLocalVue();
6 | localVue.use(VueRouter);
at Resolver.resolveModule (node_modules/jest-resolve/build/index.js:221:17)
at Object.<anonymous> (tests/unit/App.spec.js:3:30)
TEST
@eddyerburgh
Does anyone have an example of a test that fails currently if the cache isn't cleared? I'd like to add a test case to the library when I fix the issue
Even the most simple isVueInstance
test fails:
import { shallowMount, createLocalVue } from "@vue/test-utils";
import VueRouter from "vue-router";
import App from "@/App.vue";
const localVue = createLocalVue();
localVue.use(VueRouter);
const router = new VueRouter();
describe("App", () => {
test("is a Vue instance", () => {
const wrapper = shallowMount(App, { localVue, router });
expect(wrapper.isVueInstance()).toBeTruthy();
});
});
..but again, other tests fail, too.
"test:unit": "vue-cli-service test:unit --no-cache" worked for me!! Thanks.
This one is a little frustrating for me. Using --no-cache
fixes the test, but if I'm using it in conjunction with --watch
then changes aren't picked up as I make them, so the only way to see if I've broken something is to manually run jest
. First world problems, but it'd be nice to have my test runner up while building so as to make the flow a bit less tedious.
example.spec.ts
import { shallowMount } from '@vue/test-utils'
import Example from './example.vue'
describe('stuff', () => {
it('works', () => {
const wrapper = shallowMount(Example);
expect(wrapper.text()).toMatch('Hello')
})
})
example.vue
<template>
<div class="primary">{{ msg }}</div>
</template>
<script lang="ts" src="./example.ts"></script>
<style lang="scss" src="./example.scss"></style>
example.ts
export default {
data() {
return {
msg: 'Hello Vue'
}
}
}
So if I have jest --watch --no-cache
running, and change msg
in example.ts
to 'Hey Vue'
the change isn't picked up and jest
still thinks it's passing. Not sure if there's a way around that in jest
or if it's the purview of vue-jest
but seems relevant to the conversation here.
@Jack-Barry I'm experiencing the exact same issue, did you find a workaround?
@couellet For me it was a matter of giving up on keeping my TypeScript in a separate file, and might have also been partly due to pulling in updated dependencies.
If I put my business logic between the <script>
tags instead of in its own file it's working for me using Jest 23.6.0
, vue-jest
3.0.3
, ts-jest
23.10.5
, @vue/test-utils
1.0.0-beta.29
.
Not a huge deal for our project, just was hoping to keep the business logic in a proper .ts
file since the VS Code support for linting those tends to work a bit more predictably than when TS is in a .vue
file.
@Jack-Barry We're using the same setup, with the .ts
file in a separate file for better TypeScript support in unit tests. I guess we'll live with that until the next version of Vue which will have a better TypeScript support. Thanks!
I have the same problem with .pug
files. My components usually have this structure:
Header/
Header.css
Header.pug
Header.spec.ts
Header.vue
For others struggling with the cache not being cleared during --watchAll
here is my solution (hack) to get around this issue:
package.json
{
"scripts": {
"test": "jest --no-cache -u",
"test:watch": "onchange 'src/**/*' -i -- yarn test",
},
"devDependencies": {
"onchange": "^7.0.2",
},
}
yarn test:watch
Is this issue linked to code coverage reporting import statements as uncovered lines? I'm encountering this with a vue/gridsome project.
jest: 26.6.3 vue-jest: 3.0.7 node: v10.16.2 (windows)
no cache doesn't seem to help, this is my jest config:
module.exports = {
moduleFileExtensions: ["js", "jsx", "json", "vue"],
transform: {
"^.+\\.vue$": require.resolve("vue-jest"),
"^.+\\.jsx?$": require.resolve("babel-jest"),
},
transformIgnorePatterns: ["/node_modules/"],
moduleNameMapper: {
"^~/(.*)$": "<rootDir>/src/$1",
},
testMatch: ["**/tests/unit/**/*.spec.[jt]s?(x)", "**/__tests__/*.[jt]s?(x)"],
collectCoverage: true,
collectCoverageFrom: [
"src/**/*.{js,vue}",
"!src/main.js", // No need to cover bootstrap file
],
};
Even with "vue-jest": "^4.0.0-rc.0",
my command vue-cli-service test:unit --no-cache --collect-coverage
results in line 122 being uncovered, while line 122 doesn't even exist.
The other lines are weird as well
I think the source map is incorrect, which results in the incorrect coverage...