nyc: unable to get correct nyc/istanbul coverage report for typescript
Please use the template provided below, when reporting bugs:
Expected Behavior
get correct coverage report for typescript project
Observed Behavior
coverage is not correct for typescript files. i.e. html coverage map is miss-aligned with the source also coverage numbers seem to not be correct (and sometimes non deterministic
I’ve described my issue in https://stackoverflow.com/questions/44701991/getting-nyc-istanbul-coverage-report-to-work-with-typescript
copy-pasting the info here:
nyc
relevant config in package.json
"scripts": {
"test:coverage": "nyc npm run test:unit",
"test:unit": "gulp mocha"
}
"nyc": {
"check-coverage": true,
"all": true,
"extension": [
".js",
".jsx",
".ts",
".tsx"
],
"include": [
"src/**/!(*.test.*).[tj]s?(x)"
],
"reporter": [
"html",
"lcov",
"text",
"text-summary"
],
"report-dir": "docs/reports/coverage"
}
gulpfile.js
mocha relevant part
const SRC_DIR = path.join(__dirname, 'src');
const SRC_FILES = path.join(SRC_DIR, '**', '*.[jt]s?(x)');
const TEST_FILES = path.join(SRC_DIR, '**', '*.test.[jt]s?(x)');
const MOCHA_CONFIG = {
src: [
TEST_FILES
],
watchSrc: [
SRC_FILES,
TEST_FILES
],
mocha: {
// compilers: [
// 'ts:ts-node/register',
// 'tsx:ts-node/register'
// ],
require: [
'./tests/setup.js',
'ignore-styles',
'source-map-support/register'
]
}
};
gulp.task('mocha', mocha(MOCHA_CONFIG));
tsconfig.json
{
"compilerOptions": {
"baseUrl": "./",
"rootDir": "./src",
"outDir": "./build",
"allowJs": true,
"module": "commonjs",
"target": "es5",
"lib": ["es5", "es6", "dom"],
"sourceMap": true,
"inlineSourceMap": false,
"inlineSources": false,
"experimentalDecorators": true,
"noUnusedParameters": true,
"noUnusedLocals": true,
"jsx": "react",
"moduleResolution": "node"
},
"exclude": [
"docs",
"tests",
"**/*.test.js",
"**/*.test.jsx",
"**/*.test.ts",
"**/*.test.tsx",
"tools",
"gulpfile.js",
"node_modules",
"build",
"typings/main",
"typings/main.d.ts"
],
"awesomeTypescriptLoaderOptions": {
"useCache": true,
"useBabel": true
}
}
I’ve tried a number of approaches, some of them seem to be unable to use source maps and other fails due to ts-node
/tsc
errors.
With the above setup coverage produces results for all the files but they are incorrect for TS files most probably due to source maps not being used (i.e. report shows no coverage for lines which are comments and the numbers seems to be wrong as well).
With a number of variant approaches tried with no success one of the most commonly suggested is to add "require": ["ts-node/register"]
to nyc
configuration yet then I’m getting errors complaining about i.e. gulpfile.js
, docs/reports/coverage/lcov-report/prettify.js
and number of other JS files to be not under 'rootDir'
which is correct yet it is not clear why ts-node
tries to process all the files out of src
even if they are excluded in tsconfig.json
(still the configuration gets really complex).
Forensic Information
Operating System: macOS 10.12.4 Environment Information: node v7.2.0 npm v3.10.9 nyc v11.0.1
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Reactions: 35
- Comments: 22 (8 by maintainers)
There is a tutorial on how to use Istanbul with TypeScript & mocha but is there also a tutorial that explains how to use it with Jasmine?
I guess that it would be possible to instrument the compiled JavaScript code to get code coverage from TypeScript code?
By the way, do not know if this is related, but I noticed the
removeComments
option, intsconfig.json
, if enabled will remove Istanbul ignore tags and so actual coverage will be different from the expected one.This is my command to launch coverage:
nyc mocha 'test/**/*.ts'
.mocha.opts:
.nycrc:
I think it would be worthy to add this detail in the Istanbul + Typescript configuration tutorial.
Thanks for pointing me in the right direction. I added the require statement to my package.json which contained the
all:true
.We had problems with this require stanza before, producing vague error messages:
ts.Debug.assert(outputText !== undefined, "Output generation failed"
. I found out that this could be fixed this by adding"**/*.d.ts"
to our excludes. (nyc seems to considerfile.d.ts
to have a.ts
extension)@johan-gorter as indicated in the initial post, make sure that nyc has a
require
stanza that pulls in"ts-node/register"
for you. This is required because the--all
step functions by pre-instrumenting all of the files, and pulling out the coverage information.If
nyc
itself is not the process performing the instrumentation, then there will be a discrepancy between the line count retrieved during the fake instrumentation applied by--all
and the instrumentation applied when running tests that exercise the file.tldr; if you’re using
--all
, thenyc
process needs to control the instrumentation of the files; feel free to share yourpackage.json
with me, and something might jump out.I’m also seeing this issue. I’ve created a repository to demonstrate the issue. In that repository, I created two files with identical contents. One has a .ts extension and the other has a .tsx extension. Interestingly, the coverage highlighting seems accurate in the .ts file, but not in the .tsx file:
This suggests that there is some sort of issue with the source map, but I don’t know enough to tell whether it’s an issue with the generation of the source map or one of the libraries that are processing it.
I hope this helps.
upgrading to latest
nyc
,ts-node
did not change anything for me. Yet just found that using"target": "es5"
ascompilerOptions
intsconfig.conf
seems to solve the issue (need to confirm though if coverage report is fully correct). Also if you needes5
target in production there is still an option to useTS_NODE_COMPILER_OPTIONS='{"target":"es6"}' nyc ...
i.e. inpackage.json
’sscripts
sectionsee: https://github.com/Microsoft/TypeScript/issues/24993 I would like for us to better document a happy path for TypeScript and nyc.
I still have this issue on .ts code, I tried everything mentioned above, switching to es6 or es2017 using inlineSourceMap. none of them solved my issue. when I run the test, 3 json files are generated in my .nyc_output. But their statementMap are different. if nyc analyze one of the json first, the result is correct, but if it analyze the other file fist, and then try to merge the good one into it, the result would be broken.
my work around: run nyc twice with 2 different nycrc, the second one with
that makes the second nycrc always output correct result, but it rely on the cache generated by the first run
I found that using
"inlineSourceMap": true
intsconfig.json
andinline-source-map
fordevtool
in my Webpack conf (Because I’m doing Typescript -> ES6 -> Babel -> ES5), seems to have fixed the alignment of my TS source in coverage. I am also requiringsource-map-support/register
with mocha’s-r
switch.Hopefully, this helps put anyone on the right track. I understand you may not be using the same setup as me (As I’ve Webpack in the middle) so our circumstance may be different.