Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to run Typescript (not AngularJs) unit tests with Jasmine and Webpack

There is a ton of information on how to unit test with Webpack and Jasmine for Angular projects.

But I have a project that uses 'plain' typescript, not AngularJs. So I have ts classes, but I don't use components. I cannot figure out how to apply the information I'm finding to a non-AngularJs project; everything seems geared toward using components.

How do I integrate Jasmine (ts spec files) in a Typescript Webpack project?

I'd prefer a solution that uses a separate webpack config for the tests.

My setup/what I have to work with:

package.json Start script launches node with dev-build

{
  "name": "webpack.typescript",
  "version": "1.0.0",
  "description": "Webpack + TypeScript",
  "main": "dev-build.js",
  "author": "Shane Osbourne and John Lindquist",
  "license": "MIT",
  "scripts": {
    "start": "node dev-build"
  },
  "dependencies": {
    "bootstrap": "^3.3.7",
    "lodash": "^4.17.4"
  },
  "devDependencies": {
    "@types/lodash": "^4.14.53",
    "browser-sync": "^2.18.8",
    "bs-pretty-message": "^1.0.8",
    "css-loader": "^0.26.2",
    "node-sass": "^4.5.0",
    "sass-loader": "^6.0.2",
    "style-loader": "^0.13.2",
    "ts-loader": "^2.0.1",
    "typescript": "^2.2.1",
    "url-loader": "^0.5.8",
    "webpack": "^2.2.1",
    "webpack-dev-middleware": "^1.10.1"
  }
}

dev-build.js Load config, bundle, and start BrowserSync.

/**
 * Require Browsersync along with webpack and middleware for it
 */
var browserSync          = require('browser-sync').create();
var webpack              = require('webpack');
var webpackDevMiddleware = require('webpack-dev-middleware');

/**
 * Require ./dev-webpack.config.js and make a bundler from it
 */
var webpackConfig = require('./dev-webpack.config');
var bundler       = webpack(webpackConfig);

/**
 * Reload all devices when bundle is complete
 * or send a fullscreen error message to the browser instead
 */
bundler.plugin('done', function (stats) {
    if (stats.hasErrors() || stats.hasWarnings()) {
        return browserSync.sockets.emit('fullscreen:message', {
            title: "Error",
            timeout: 100000
        });
    }
    browserSync.reload();
});

/**
 * Run Browsersync and use middleware for Hot Module Replacement
 */
browserSync.init({
    server: 'app',
    open: false,
    logFileChanges: false,
    middleware: [
        webpackDevMiddleware(bundler, {
            publicPath: webpackConfig.output.publicPath,
            stats: {colors: true}
        })
    ],
    plugins: ['bs-pretty-message'],
    files: [
        'app/css/*.css',
        'app/*.html'
    ]
});

dev-webpack.config.js Handle Typescript and scss. (I was thinking I should have a test-webpack.config.js)

var webpack = require('webpack');
var path = require('path');

module.exports = {
  devtool: '#inline-source-map',

  entry: [
    './src/main.ts',
    './src/main.scss'
  ],

  output: {
    path: path.join(__dirname, 'app'),
    publicPath: '/',
    filename: 'dist/bundle.js'
  },

  plugins: [
    new webpack.NoEmitOnErrorsPlugin(),
    new webpack.LoaderOptionsPlugin({
      debug: true
    })
  ],

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

  module: {
    rules: [
      {
        test: /\.ts$/, use: [{
          loader: 'ts-loader'
        }]
      },
      {
        test: /\.woff($|\?)|\.woff2($|\?)|\.ttf($|\?)|\.eot($|\?)|\.svg($|\?)/,
        use: [{
          loader: 'url-loader'
        }]
      },
      {
        test: /\.scss$/,
        use: [{
          loader: "style-loader"
        }, {
          loader: "css-loader", options: {
            sourceMap: true
          }
        }, {
          loader: "sass-loader", options: {
            sourceMap: true
          }
        }]
      }
    ],
  }
};

What I've found:

https://dzone.com/articles/unit-testing-with-webpack-amp-mocha

Unit testing with Webpack, Jasmine (-core), typescript

Jasmine Spec as Typescript File

TypeScript compilation failure and Karma test execution?

Executing Typescript Jasmine tests via Webpack (Terminal) to test Angular2

like image 838
Koert van Kleef Avatar asked Mar 03 '17 17:03

Koert van Kleef


People also ask

Does Jasmine support TypeScript?

jasmine : it is a testing framework for javascript code. It does not require DOM. @types/jasmine : it contains the type definition for Jasmine to be used with TypeScript.

How do I run a unit test in TypeScript?

For TypeScript, unit tests are run against the generated JavaScript code. Add your unit tests to the tests folder in the project root. For example, you might use the following code by selecting the correct documentation tab that matches your test framework, in this example either Mocha or Jest.

How do you write and run tests in Angular using jasmine and karma?

Create an Angular project with jasmine and karma By doing this, the jasmine and karma configuration is resolved for us. Install and create a new project with angular-cli: Install npm -g @angular/cli. Ng new angular-unit-testing angular unit-testing.


1 Answers

Ngz answer still included angular and al lot of extra things. So I'll try to answer with the bare necessities.

The test-webpack-config.js has the tests as entry point, since webpack looks from there for dependencies, and the ts-loader does the transpiling:

var webpack = require('webpack');
var path = require('path');

module.exports = {
  devtool: '#inline-source-map',

  entry: [
    './test/index.spec.ts',
  ],

  output: {
    filename: 'dist/bundle.js'
  },

  plugins: [
    new webpack.NoEmitOnErrorsPlugin(),
    new webpack.LoaderOptionsPlugin({
      debug: true
    })
  ],

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

  module: {
    rules: [
      {
        test: /\.ts$/, use: [{
          loader: 'ts-loader'
        }]
      }]
  }
};

An I used karma as a test runner, with the karma-webpack plugin, here is the config:

var webpackConfig = require('./test-webpack.config.js');

module.exports = function(config) {
  config.set({

    // base path that will be used to resolve all patterns (eg. files, exclude)
    basePath: '',


    // frameworks to use
    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['jasmine'],


    // list of files / patterns to load in the browser
    files: [
      'test/*.spec.ts',
    ],


    // list of files to exclude
    exclude: [
    ],


    // preprocess matching files before serving them to the browser
    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
    preprocessors: {
       'test/**/*.spec.ts': ['webpack'],
       'src/**/*.ts': ['webpack'],
    },


    // test results reporter to use
    // possible values: 'dots', 'progress'
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
    reporters: ['progress'],


    // web server port
    port: 9876,


    // enable / disable colors in the output (reporters and logs)
    colors: true,


    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,


    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: true,


    // start these browsers
    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
    browsers: ['Chrome'],


    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: true,

    // Concurrency level
    // how many browser should be started simultaneous
    concurrency: Infinity, 

    mime: {
      'text/x-typescript': ['ts','tsx']
    },

    // Set Webpack configuration, but set the entry to spec files
    webpack: {
      module: webpackConfig.module,
      resolve: webpackConfig.resolve
    }
  })
}

The mime part is the key for having tests made in typescript to work.

For the full example: https://github.com/SierraNL/webpack-typescript-jasmine

like image 101
LeonG Avatar answered Sep 29 '22 10:09

LeonG