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
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