Skip to content
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

Empty coverage #433

Closed
roman01la opened this issue Jul 14, 2015 · 32 comments
Closed

Empty coverage #433

roman01la opened this issue Jul 14, 2015 · 32 comments

Comments

@roman01la
Copy link

I'm struggling to get code coverage with Jest.

Here's a sample component I'm running tests on:

var React = require('react');

var Input = React.createClass({
  render: function() {
    var placeholder = this.props.placeholder,
        value = this.props.value,
        name = this.props.name;

    return React.DOM.div({
      className: 'field'
    }, [
      React.DOM.label({
        htmlFor: name
      }),
      React.DOM.input({
        name: name,
        value: value,
        type: 'text',
        placeholder: placeholder
      })
    ]);
  }
});

module.exports = Input;

And here's a test file:

jest.dontMock('../../../components/input');

var React, TestUtils, Input;

var input;

var placeholder = 'placeholder',
    name = 'name',
    value = 'value';

describe('Input', function() {

  it('should render props', function() {

    React = require('react/addons');
    TestUtils = React.addons.TestUtils;
    Input = require('../../../components/input');

    input = TestUtils.renderIntoDocument(
      React.createElement(Input, {
        name: name,
        value: value,
        placeholder: placeholder
      }));

    var inputTag = TestUtils.findRenderedDOMComponentWithTag(input, 'input')
          .getDOMNode();

    expect(inputTag.getAttribute('placeholder')).toEqual(placeholder);
    expect(inputTag.getAttribute('name')).toEqual(name);
    expect(inputTag.getAttribute('value')).toEqual(value);
  });
});

And also Jest settings from package.json:

 {
    "collectCoverage": true,
    "testDirectoryName": "test/unit",
    "rootDir": "./src",
    "unmockedModulePathPatterns": [
      "./node_modules/react"
    ]
  }

All paths a valid. I've been debugging Jest and found out that moduleLoader.getDependenciesFromPath(testFilePath) returns empty array. So for some reason it can not get dependencies of the test file.

@browniefed
Copy link
Contributor

I found that if you don't add in the moduleFileExtensions param in package.json it will not collect coverage on anything but js files. Or maybe I'm misunderstanding your question.

    "moduleFileExtensions": [
      "js",
      "jsx"
    ],

@roman01la
Copy link
Author

@browniefed Didn't help :(

@rbardini
Copy link

I'm also getting empty coverage results, but I'm not sure if it is a jest, babel-jest or even istanbul issue. I'm using Jest 0.5.x with ES6 imports and auto-mock off, and the following configuration:

"jest": {
  "scriptPreprocessor": "<rootDir>/node_modules/babel-jest",
  "testPathDirs": [
    "<rootDir>/src"
  ],
  "testDirectoryName": "spec",
  "testFileExtensions": [
    "js",
    "jsx"
  ],
  "moduleFileExtensions": [
    "js",
    "json"
  ],
  "unmockedModulePathPatterns": [
    "<rootDir>/node_modules/react"
  ]
}

This is the Jest output:

> iojs ./node_modules/jest-cli/bin/jest.js --coverage

Using Jest CLI v0.4.17
 PASS  src/tests/spec/DurationFormatter-test.js (1.751s)
1 test passed (1 total)
Run time: 2.435s
----------|----------|----------|----------|----------|----------------|
File      |  % Stmts | % Branch |  % Funcs |  % Lines |Uncovered Lines |
----------|----------|----------|----------|----------|----------------|
----------|----------|----------|----------|----------|----------------|
All files |      100 |      100 |      100 |      100 |                |
----------|----------|----------|----------|----------|----------------|

All reports generated

And coverage/clover.xml contents:

<?xml version="1.0" encoding="UTF-8"?>
<coverage generated="1438265018003" clover="3.2.0">
  <project timestamp="1438265018003"  name="All Files" >
    <metrics statements="0"  coveredstatements="0"  conditionals="0"  coveredconditionals="0"  methods="0"  coveredmethods="0"  elements="0"  coveredelements="0"  complexity="0"  packages="0"  files="0"  classes="0"  loc="0"  ncloc="0" />
  </project>
</coverage>

@aluxian
Copy link

aluxian commented Jul 30, 2015

I get exactly the same output as @rbardini. I don't use babel-jest, I transpile the files before running jest from the 0.5 branch on them.

preprocessor.js just replaces require('./styles.scss') with {}.

"jest": {
    "scriptPreprocessor": "<rootDir>/preprocessor.js",
    "testDirectoryName": "build",
    "testPathDirs": [
      "build"
    ],
    "testFileExtensions": [
      "spec.js"
    ],
    "moduleFileExtensions": [
      "js",
      "jsx"
    ],
    "unmockedModulePathPatterns": [
      "/node_modules/"
    ]
  }

And the output:

Using Jest CLI v0.4.17
 PASS  build/components/Paper/tests.spec.js (0.47s)
 PASS  build/components/Button/tests.spec.js (0.572s)
Warning: Returning `false` from an event handler is deprecated and will be ignored in a future release. Instead, manually call e.stopPropagation() or e.preventDefault(), as appropriate.
2 tests passed (2 total)
Run time: 1.603s
----------|----------|----------|----------|----------|----------------|
File      |  % Stmts | % Branch |  % Funcs |  % Lines |Uncovered Lines |
----------|----------|----------|----------|----------|----------------|
----------|----------|----------|----------|----------|----------------|
All files |      100 |      100 |      100 |      100 |                |
----------|----------|----------|----------|----------|----------------|

All reports generated

@aluxian
Copy link

aluxian commented Jul 30, 2015

I fixed this by including every file in collectCoverageOnlyFrom:

"jest": {
    "scriptPreprocessor": "<rootDir>/preprocessor.js",
    "testDirectoryName": "build",
    "testPathDirs": [
      "build"
    ],
    "testFileExtensions": [
      "spec.js"
    ],
    "unmockedModulePathPatterns": [
      "/node_modules/"
    ],
    "collectCoverageOnlyFrom": {
      "build/components/Paper/index.js": true,
      "build/components/Button/index.js": true
    }
  }

cc @rbardini

@rbardini
Copy link

Thanks @aluxian, your solution also worked for me, although I find it a little impractical to list all the desired files in package.json as time goes on and the number of tested components increase. I don't know if that's feasible, but perhaps we could have a jest.collectCoverage(moduleName) method?

Besides that, I've noticed that my test fails if I list the file in collectCoverageOnlyFrom but do not tell Jest to collect coverage information either via the --coverage flag or the collectCoverage option:

> iojs ./node_modules/jest-cli/bin/jest.js

Using Jest CLI v0.4.17
 FAIL  src/tests/spec/DurationFormatter-test.js
TypeError: src/tests/spec/DurationFormatter-test.js: undefined is not a function
  at Loader._execModule (node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:222:9)
  at Loader.requireModule (node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:905:12)
  at Loader.requireModuleOrMock (node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:926:17)
  at Object.<anonymous> (src/tests/spec/DurationFormatter-test.js:2:258)
  at Object.runContentWithLocalBindings (node_modules/jest-cli/src/lib/utils.js:495:17)
  at Loader._execModule (node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:236:9)
  at Loader.requireModule (node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:905:12)
  at jasmineTestRunner (node_modules/jest-cli/src/jasmineTestRunner/jasmineTestRunner.js:283:16)
  at node_modules/jest-cli/src/TestRunner.js:376:12
  at tryCatcher (node_modules/jest-cli/node_modules/bluebird/js/main/util.js:26:23)
  at Promise._settlePromiseFromHandler (node_modules/jest-cli/node_modules/bluebird/js/main/promise.js:503:31)
  at Promise._settlePromiseAt (node_modules/jest-cli/node_modules/bluebird/js/main/promise.js:577:18)
  at Promise._settlePromises (node_modules/jest-cli/node_modules/bluebird/js/main/promise.js:693:14)
  at Async._drainQueue (node_modules/jest-cli/node_modules/bluebird/js/main/async.js:123:16)
  at Async._drainQueues (node_modules/jest-cli/node_modules/bluebird/js/main/async.js:133:10)
  at Immediate.Async.drainQueues [as _onImmediate] (node_modules/jest-cli/node_modules/bluebird/js/main/async.js:15:14)
  at processImmediate [as _immediateCallback] (timers.js:371:17)
1 test failed, 0 tests passed (1 total)
Run time: 2.253s
npm ERR! Test failed.  See above for more details.

Otherwise it works as expected:

> iojs ./node_modules/jest-cli/bin/jest.js --coverage

Using Jest CLI v0.4.17
 PASS  src/tests/spec/DurationFormatter-test.js (1.473s)
1 test passed (1 total)
Run time: 2.004s
-----------------------|----------|----------|----------|----------|----------------|
File                   |  % Stmts | % Branch |  % Funcs |  % Lines |Uncovered Lines |
-----------------------|----------|----------|----------|----------|----------------|
 components/           |      100 |      100 |      100 |      100 |                |
  DurationFormatter.js |      100 |      100 |      100 |      100 |                |
-----------------------|----------|----------|----------|----------|----------------|
All files              |      100 |      100 |      100 |      100 |                |
-----------------------|----------|----------|----------|----------|----------------|

All reports generated

@aluxian
Copy link

aluxian commented Jul 31, 2015

Same for me ^ I enabled coverage by default now.

And yeah, I know it's impractical, but hey – at least it works. Now that we know what's wrong is much easier to find a viable solution.

@Nutelac
Copy link

Nutelac commented Aug 18, 2015

Did someone found solution? I have lot of tests, so it's impractical to add them using collectCoverageOnlyFrom. Thank you.

@rafaelmaiolla
Copy link

+1

@akheron
Copy link

akheron commented Oct 28, 2015

I found out that using testPathDirs breaks the coverage output. If I remove testPathDirs from config and use testPathIgnorePatterns instead to ignore tests from unwanted directories, I get real coverage output.

@fangmobile
Copy link

@roman01la I think you need to put your test under __test__ folder in order to get coverage report. And my also get rid the line "testDirectoryName": "test/unit",
I got that suggest from http://blog.redradix.com/get-coverage-reports-with-jest-js-react/ and was able to get report.

My problem is I get the report only from the files I tested, or list them in collectCoverageOnlyFrom. If my test does not touch a file in the test folder, I wish the report show 0% for that file, but it is not reported at all.

Should I raise separate issue?

@dready
Copy link

dready commented Nov 6, 2015

same like @akheron, as soon as i add testPathDirs it's over with the coverage, only the coverage of the first file is shown.. and i already have the tests within a __test__ directory.

Using testPathDirs speeds up my initialization routine by far.. from 1 minute 17 seconds to 14 seconds.. but without coverage this is useless...

@hourliert
Copy link

Same issue here. I only get coverage if I add manually files in collectCoverageOnlyFrom.

@aospan
Copy link

aospan commented Dec 23, 2015

as workaround you can create fake __tests__/package.json with {} inside. In this case node-haste create correct requiredModules and you will see coverage for all files (direct dependent from test file).

@quantizor
Copy link
Contributor

@hourliert That was my finding as well. Annoying, but it works...

@korto
Copy link

korto commented Dec 30, 2015

@hourliert, @yaycmyk +1

@threesquared
Copy link

Am also having this issue. Coverage only working when files added to collectCoverageOnlyFrom.

@JaxGit
Copy link

JaxGit commented Feb 13, 2016

jest-cli@0.8.2
I found that one of the reasons for getting empty coverage is require.requireActual your test object, although it works fine during testing process.

By changing to syntax:
jest.dontMock('./test object');
const TestObject = require('./test object');
problem bypassed.

@JaxGit
Copy link

JaxGit commented Feb 14, 2016

Another reason is using a custom structure to organise tests and mocks.
It works fine by using
"testPathDirs": [ "app/"],
and following tutorial to use the default structure:
/app
└── mocks
└── components

       └── __tests__
                    └── testObject.<testFileExtension>
       └── testObject.js

While this won't work (even using dontMock instead of require.requireActual):
/app
└── mocks
└── tests

       └── components
                    └── testObject.<testFileExtension>

└── components

       └── testObject.js

@cpojer
Copy link
Member

cpojer commented Mar 3, 2016

This should be fixed in 0.9.0, currently as alpha release tagged with jest-cli@next. Let me know if this still doesn't work and I will reopen this issue.

@cpojer cpojer closed this as completed Mar 3, 2016
@blainekasten
Copy link
Contributor

@cpojer This is still a bug in 0.9.2.

Steps to reproduce within a set of code with zero tests.

  1. run jest --coverage and see that it shows coverage errors.
  2. set a "testPathDirs": [ ... ] to your src files
  3. run jest --coverage

The second run will result with zero files untested. While it still should since there are plenty of files within src that doesn't have any tests.

@cpojer
Copy link
Member

cpojer commented Apr 25, 2016

@blainekasten can you provide a repo that highlights this issue so we can add it as an integration test and fix it?

@cpojer cpojer reopened this Apr 25, 2016
@skawian
Copy link

skawian commented Apr 26, 2016

In my case I get an empty coverage when I try to put test files in the same directory as source files. I found it useful to stick a breakpoint in this line https://github.com/facebook/jest/blob/master/src/Runtime/Runtime.js#L296 and found out that the whole test directory is excluded from coverage. My fix is to check if the file does not have test extension (I use 'spec.test') rather than being in the test directory.

@cpojer
Copy link
Member

cpojer commented Apr 26, 2016

Oh you are right, it's because we don't collect coverage information from tests. I'm not entirely sure what the best behavior here should be – I believe when we fix the test path pattern to be based on the full path rather than just the directory name, this bug will resolve itself :) Soon!

skawian pushed a commit to skawian/jest that referenced this issue Apr 26, 2016
skawian pushed a commit to skawian/jest that referenced this issue Apr 26, 2016
Check if the file does have test extension rather than being in the test directory.
Could potentially fix jestjs#433
skawian pushed a commit to skawian/jest that referenced this issue Apr 26, 2016
Check if the file does have test extension rather than being in the test directory.
Could potentially fix jestjs#433
skawian pushed a commit to skawian/jest that referenced this issue Apr 26, 2016
Check if the file does have test extension rather than being in the test directory.
Could potentially fix jestjs#433
The side effect of it is that you cannot specify just "js" as your test file extension as this would include all tests in the coverage
skawian pushed a commit to skawian/jest that referenced this issue Apr 26, 2016
Check if the file does have test extension rather than being in the test directory.
Could potentially fix jestjs#433
The side effect of it is that you cannot specify just "js" as your test file extension as this would include all tests in the coverage
@blainekasten
Copy link
Contributor

There are so many different issues listed in this ticket that I'm having a hard time following what is actually still a problem.

@cpojer I did make a repo with the one issue I currently still see here

The issue i'm still seeing:

  • Files not touched by jest aren't reported in coverage

That said, I would gladly enjoy anyone else putting up PR's in that repo for other configurations that are having issues so we can try to keep these centrally located.

@cpojer
Copy link
Member

cpojer commented May 20, 2016

I think this should be fine now. If there are issues that are still unresolved with Jest 12.1, please open individual new issues.

@cdaringe
Copy link

cdaringe commented Nov 17, 2016

@cpojer, i can confirm this is still an issue.

  • here you will see that coverage is requested. on npm test, indeed, jest shows the coverage report
  • the report in stdout shows 100% coverage, yet the coverage/lcov* and coverage/*.xml show as 0% coverage. hence, there is an easily reproducible discrepancy between outputs

jest 17.x. thx!

@JimLynchCodes
Copy link

I am using jest version 24, and this is still an issue!!!

What is the proper jest config to have it report untouched source files?? Insane that this hasn't been fixed yet... 😢

@MattAydin
Copy link

Not sure if it's still relevant for someone, but I fixed it by adding this to my package.json file:

"jest": {
    "preset": "react-native",
    "testMatch": [
      "**/__tests__/**/?(*.)+(spec|test).[tj]s?(x)"
    ],
    "moduleFileExtensions": [
      "ts",
      "tsx",
      "js",
      "jsx"
    ],
    "collectCoverageFrom": [
      "src/**/*.{ts,tsx,js,jsx}"
    ]
  }

@celtic7716
Copy link

celtic7716 commented Dec 29, 2020

This is still an issue in 26.6.3. When I pass specific files to jest, I have to pass those same files to collectCoverageOnlyFrom for jest to actually detect coverage.

I'm using the specific files in pre-commit hooks to only test the files that have changed.

So what I have to do is this:

jest /file/that/changed.js --findRelatedTests --collectCoverage --collectCoverageOnlyFrom "/file/that/changed.js"

If there are multiple files that are changed in staging, then it needs to look like this to work:

jest /file/that/changed.js /another/file/that/changed.js --findRelatedTests --collectCoverage --collectCoverageOnlyFrom "/another/file/that/changed.js" --collectCoverageOnlyFrom "/file/that/changed.js"

Others have found success by hard-coding values into package.json, but in a dynamic CLI context, I have to use the outdated option collectCoverageOnlyFrom (instead of the new option collectCoverageFrom which does not work properly in the CLI). Further, I have to append each file independently instead of in an array or json format.

The ideal usage would be:

jest /file/that/changed.js --findRelatedTests --collectCoverage

Ideally the above command would collect coverage only for that file that changed, unless otherwise specified in package.json. Currently that command just returns 0 for all coverage which is not useful or what is expected when --collectCoverage is used.

@celtic7716
Copy link

celtic7716 commented Dec 29, 2020

Not sure if it's still relevant for someone, but I fixed it by adding this to my package.json file:

"jest": {
    "preset": "react-native",
    "testMatch": [
      "**/__tests__/**/?(*.)+(spec|test).[tj]s?(x)"
    ],
    "moduleFileExtensions": [
      "ts",
      "tsx",
      "js",
      "jsx"
    ],
    "collectCoverageFrom": [
      "src/**/*.{ts,tsx,js,jsx}"
    ]
  }

@MattAydin The problem with this is that this collects coverage on all the source code every time. If you want to run jest only on files that changed (and collect coverage for only the files that changed), there needs to be a dynamic solution for collecting coverage.

@github-actions
Copy link

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Please note this issue tracker is not a help forum. We recommend using StackOverflow or our discord channel for questions.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 11, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.