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

TypeScript support? #176

Closed
JaKXz opened this issue Feb 29, 2016 · 27 comments
Closed

TypeScript support? #176

JaKXz opened this issue Feb 29, 2016 · 27 comments

Comments

@JaKXz
Copy link
Member

JaKXz commented Feb 29, 2016

When scanning through the issues, there was a hint that theoretically, TypeScript could be possible to instrument and produce coverage for.

This is my first guess in my package.json for an Angular 2 project using karma:

  "scripts": {
    "test": "npm run lint && nyc karma start",
    "lint": "tslint './src/**/*.ts'"
  },
  "nyc": {
    "extensions": [
      ".ts"
    ],
    "exclude": [
      "**/*.js",
      "**/*.test.ts",
      "**/tests.*.ts" //helper_files_like_'tests.entry.js'
    ]
  },

and I'm just getting an empty table.

@JaKXz
Copy link
Member Author

JaKXz commented Feb 29, 2016

I tried both npm i -D nyc@latest and npm i -D bcoe/nyc#master [at time of writing], because the regular alias was just getting me v5.6.0 since v6.0.0 hasn't been published yet...

@bcoe
Copy link
Member

bcoe commented Mar 1, 2016

@JaKXz good find, I should definitely promote v6.0.0 to latest. You can install currently by running:

npm i nyc@next

Could you link me to an OSS project of yours that has .ts tests, I'd be happy to help figure things out.

@JaKXz
Copy link
Member Author

JaKXz commented Mar 1, 2016

@bcoe https://github.com/JaKXz/webpack-ts-demo/tree/chore/use-nyc is an old project, spent some time this morning updating it and cleaning up some errors. That branch has a pretty similar setup to what I've described here, with one .spec.ts file -- the master branch has the old karma-coverage setup, which instruments the transpiled code and so you do get coverage numbers, but they're skewed because of the extra boilerplate.

Feel free to email me if you need anything. Thanks for looking into this! 😄 JaKXz/webpack-ts-demo#3

@bcoe
Copy link
Member

bcoe commented Mar 13, 2016

@JaKXz any progress on this, hope things are going well.

@JaKXz
Copy link
Member Author

JaKXz commented Mar 13, 2016

@bcoe I haven't had any luck, no :( thanks for asking!

Was my project / branch installable without issues?

@JaKXz
Copy link
Member Author

JaKXz commented Mar 13, 2016

I did use npm i nyc@next in that branch :)

@JaKXz
Copy link
Member Author

JaKXz commented Mar 14, 2016

@bcoe I also tried here: JaKXz/angular2-redux-starter@ec82374 using remap-istanbul, following @novemberborn's instructions without success.

@novemberborn
Copy link
Contributor

@JaKXz nyc can handle source maps out of the box now, provided the source maps are available when it instruments the source files. I'm not sure how well it would work with Karma though. In your branch you seem to be hooking up Istanbul yourself which might conflict with nyc. And nyc might not work great with a Webpack bundle either.

@JaKXz
Copy link
Member Author

JaKXz commented Mar 14, 2016

@novemberborn good catch, but removing the postLoader didn't work either.

My guess for sourcemaps was that they should be inline for nyc to read them, is that right?

@JaKXz
Copy link
Member Author

JaKXz commented Mar 15, 2016

More and more it just looks like the .ts extension is just not supported. No matter what configuration (with or without remap-istanbul and/or sourcemaps) I use, I don't get any files listed when I specify the .ts extension.

@bcoe
Copy link
Member

bcoe commented Mar 15, 2016

@JaKXz I noticed a problem with the documentation digging into your problem, which I corrected extensions should have been documented as extension. Having said this, the approach you are using will not work with nyc:

You are using ts-loader, as far as I can determine this does not ultimately call a require() which is how nyc instruments files. As far as I can tell, you have a couple options:

  1. you could try out this module which should allow you to instrument the files that are being loaded by web-pack: https://github.com/deepsweet/istanbul-instrumenter-loader
  2. alternatively, you could test you typescript code in isolation, and use a module like this: https://github.com/theblacksmith/typescript-require

@bcoe bcoe closed this as completed Mar 15, 2016
@JaKXz
Copy link
Member Author

JaKXz commented Mar 15, 2016

@bcoe thanks for the response. I fixed the typo in extension and have re-added istanbul-instrumenter-loader in my karma webpack config [as a postLoader], but the nyc --reporter=json karma start command is still returning an empty coverage-final.json object.

@bcoe
Copy link
Member

bcoe commented Mar 15, 2016

@JaKXz nyc overrides require() and child_process to instrument code with Istanbul on the fly. It looks like the webpack is not compatible with this; rather than overriding the require statement it implements its own concept of loaders.

tldr; rather than using nyc just use istanbul-instrumenter-loader

  1. make your loaders look something like this:
//TODO use object.assign here
exports.typescript = {
  test: /\.ts$/,
  loaders: ['ng-annotate', 'istanbul-instrumenter', 'ts'],
  exclude: /\.spec\.ts$/
};

exports.typescriptTest = {
  test: /\.ts$/,
  loaders: ['ng-annotate', 'istanbul-instrumenter', 'ts']
};
  1. make your karma.conf.js look something like this:
reporters: ['mocha', 'coverage'],
  1. take a look in your /coverage folder at the end of the day, and you're in flavor country:

screen shot 2016-03-14 at 11 03 28 pm

PS., I'm flying in from Oakland and talking at Toronto JavaScript on the 22nd, if you happen to be around.

@JaKXz
Copy link
Member Author

JaKXz commented Mar 15, 2016

@bcoe thanks for the support! That is pretty much as far as I'd gotten before but I was hoping that I could instrument the actual .ts files - I have to move on for now, but I will try again someday, perhaps with a fix to remap-istanbul.

Looking forward to meeting you! 😄

@mohsen1
Copy link

mohsen1 commented Sep 30, 2016

I'll leave it here: Setting up test coverage using Mocha, Istanbul, NYC with TypeScript

Thanks for the amazing work! ❤️

@bcoe
Copy link
Member

bcoe commented Sep 30, 2016

@mohsen1 this is wonderful, mind if I put a copy on our IstanbulJS website?

@mohsen1
Copy link

mohsen1 commented Sep 30, 2016

Not at all! I copied all of your code in my project! ;)

@seanpoulter
Copy link

FYI The link to @mohsen1's article has changed.

It's also possible to produce TypeScript coverage without ts-node by running tsc with source maps and letting Mocha use them with --require source-map-support/register. Nyc will map the rest for you.

@Izhaki
Copy link

Izhaki commented Mar 15, 2017

I've managed to get this to work

  • with: webpack, mocha, mocha-webpack, nyc
  • without: babel, ts-node, bells and whistles

package.json

"coverage": "cross-env NODE_ENV=coverage nyc mocha-webpack",

.nycrc

{
    "extension": [
      ".ts"
    ],
    "reporter": [
      "html",
      "text-summary"
    ],
    "cache": true,
    "sourceMap": false,
    "instrument": false
}

mocha-webpack.opts

--webpack-config ./config/webpack/tests.js
--full-trace
src/**/!(server).ts

config/webpack/tests.js:

var path = require('path');
var path = require('path');
var nodeExternals = require('webpack-node-externals');

var config = {
    target: 'node',

    externals: [ nodeExternals() ],

    output: {
        devtoolModuleFilenameTemplate: '[absolute-resource-path]',
        devtoolFallbackModuleFilenameTemplate: '[absolute-resource-path]?[hash]'
    },

    devtool: 'inline-source-map',

    resolve: {
        extensions: ['.ts', '.tsx', '.js', '.jsx']
    },

    module: {
        rules: [{
            test: /\.ts?$/,
            include: path.resolve('src'),
            exclude: /node_modules/,
            rules: [{
                test: () => process.env.NODE_ENV === 'coverage',
                exclude: /\.spec.ts?$/,
                enforce: 'post',
                loader: 'istanbul-instrumenter-loader',
            }, {
                loader: 'awesome-typescript-loader',
            }, {
                test: () => process.env.NODE_ENV !== 'coverage' ,
                enforce: 'pre',
                loader: 'tslint-loader'
            }]
        }]
    }

};

module.exports = config;

@Nava2
Copy link

Nava2 commented Jul 13, 2017

@seanpoulter you mentioned:

It's also possible to produce TypeScript coverage without ts-node by running tsc with source maps and letting Mocha use them with --require source-map-support/register.

Would this be possible to do while running mocha against tsc-compiled js files? If they have inline source maps. My scenario is that I have tsc compiling my library files to a folder, lib-js. All of my mocha tests than include the lib-js versions.

I run coverage against the js files, but having the ts source maps respected would be excellent.

@bcoe
Copy link
Member

bcoe commented Aug 1, 2017

@Nava2 @seanpoulter I recently created a slack channel for nyc, istanbul, yargs, etc., might be a good place to discuss some of these features.

@nikmash
Copy link

nikmash commented Jan 25, 2018

@seanpoulter were you able to get the all flag working so all files (even the ones that aren't required in your tests) will show up in the coverage report.

@seanpoulter
Copy link

I don't recall trying that @nikmash, sorry.

@nikmash
Copy link

nikmash commented Jan 25, 2018

So what I found is that when using the all flag all the files that have been imported by the tests will show up as .ts files in the coverage report but all the files that have not been imported but are in the project will show up as .js files in the coverage report. Using lcov reporter.

@subhranshudas
Copy link

subhranshudas commented Apr 23, 2018

Can anybody provide the working configuration for JS + NYC + MOCHA-WEBPACK, i tried below config, but get a blank coverage report
webpack.config.test.js


var nodeExternals = require('webpack-node-externals');
var isCoverage = process.env.NODE_ENV === 'coverage';

module.exports = {
  output: {
    // use absolute paths in sourcemaps (important for debugging via IDE)
    devtoolModuleFilenameTemplate: '[absolute-resource-path]',
    devtoolFallbackModuleFilenameTemplate: '[absolute-resource-path]?[hash]'
  },
  module: {
    rules: [].concat(
      isCoverage ? {
          test: /\.(js)/,
          include: path.resolve('src'), // instrument only testing sources with Istanbul, after ts-loader runs
          loader: 'istanbul-instrumenter-loader'
      } : [],
      {
          test: /.js$/,
          exclude: /(node_modules|bower_components)/,
          loader: 'babel-loader',
      },
    ),
  },
  target: 'node',  // webpack should compile node compatible code
  externals: [nodeExternals()], // in order to ignore all modules in node_modules folder
  devtool: 'inline-cheap-module-source-map'
};

package.json

 "scripts": {
    "test": "./node_modules/mocha-webpack/bin/mocha-webpack ./tests/*.test.js",
    "coverage": "cross-env NODE_ENV=coverage nyc --reporter=lcov --reporter=text npm run test",
    "start": "webpack --watch",
    "build": "webpack"
  },```

can't see any files in src in the table.

@shirakaba
Copy link

shirakaba commented Jan 16, 2019

I'll leave it here: Setting up test coverage using Mocha, Istanbul, NYC with TypeScript

This article was invaluable to me, but returned a 404; so here's the up-to-date URL:

Setting up test coverage using Mocha, Istanbul, NYC with TypeScript

@Cauany
Copy link

Cauany commented Nov 9, 2020

I'm having a problem with the configuration of the coverage of my project, where I'm using Vue.Js, Quasar framework and Typescript. Coverage reports are returning all files, but the files are not read in the coverage.

Dependencies -> nyc, @cypress-coverage, @istanbuljs/nyc-config-typescript, coveralls, istanbul-instrumenter-loader, istanbul-lib-coverage, @cypress/webpack-preprocessor and babel/preset-typescript.

Files
Babelrc -> {"plugins": ["istanbul"],}
Nycrc.json -> {
"nyc": {
"extends": "@istanbuljs/nyc-config-typescript",
"all": true
}
}

Babel.config.js -> module.exports = {
plugins: [
['babel-plugin-istanbul', {
extension: ['.js', '.vue','.ts']
}]
]
};

Screenshot_20201109_165001

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests