I'm trialing Wallaby.js using VS2013. I've got it running for one test class, lets call it queueTests.ts, which covers the class queue.ts. The tests run and pass (or fail if I break them) and it's pretty cool.
The problem I have is that in the queue.ts file I do not see any code coverage indicators in the left hand margin. I do see them in queueTests.ts file. I guess I've got some configuration wrong but I can't work it out. In queue.ts I do see the little angle bracket indicator at the end of the line my cursor is on and it changes state as the tests pass and fail.
Here is my config. It is a solution item because me code and tests are in different projects.
module.exports = function(w) {
return {
files: [
// lib files
{ pattern: "./path/Scripts/jquery-1.9.1.js", load: true, instrument: false },
{ pattern: "./path/Scripts/underscore.js", load: true, instrument: false },
// references
{ pattern: "./path/refernencedfile.ts", load: true, instrument: true },
{ pattern: "./path/anotherrefencedfile.ts", load: true, instrument: true },
// class under test
{ pattern: "./path/path2/Queue.ts", load: true, instrument: true },
// test helpers
{ pattern: "./Tests/TestSupport/**/*.ts", load: true, instrument: false }
],
tests: [
"./Tests/path2/queuetests.ts"
],
compilers: {
"**/*.ts": w.compilers.typeScript({ orderFilesByReferenceComments: true })
}
};
};
Try removing ./ from all of your paths in wallaby config.
Related
I am using karma with jasmine and the jasmine-spec-tags framework. When starting karma from CLI I use "karma start --tags=MY_TAG" to run only some tests with the tag MY_TAG. This works fine.
Now, I need to start karma programmatically. I tried the following code (note the client.args value at the end):
const server = new Server(
{
autoWatch: true,
browsers: [
'Chrome',
],
files: [
'./node_modules/babel-polyfill/dist/polyfill.js',
'./node_modules/es6-shim/es6-shim.min.js',
'./karma/karma.entry.js'
],
frameworks: ['jasmine', 'jasmine-spec-tags'],
phantomJsLauncher: {
exitOnResourceError: true
},
port: 9876,
preprocessors: {
'./karma/karma.entry.js': ['webpack', 'sourcemap']
},
reporters: ['dots'],
singleRun: false,
webpack: webpackConf,
webpackServer: {
noInfo: true
},
client:
{
args: ['--tags=SchedulingApiService']
}
});
server.start();
This does not work. Am I misunderstanding the client.args value? Would be glad about any help.
To solve this, the client part has to look like this:
client:
{
tags: 'SchedulingApiService'
}
enter code herenpm test;
var webpackConfig = require('./webpack.test');
module.exports = function(config) {
config.set({
basePath: '',
frameworks: ['jasmine'],
files: [
{pattern: './karma-shim.js', watched: false}
],
exclude: [
],
preprocessors: {
'./karma-shim.js': ['webpack']
},
webpack: webpackConfig,
plugins:[
'karma-jasmine',
'karma-chrome-launcher',
require("karma-webpack")
],
proxies:{
"/app/": "http://localhost:3000/src/app"
},
reporters: ['progress'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false,
concurrency: Infinity
})
}
module.exports = {
devtool: 'cheap-module-eval-source-map',
resolve: {
extensions: ['','.ts','.js']
},
module: {
loaders: [
//以.ts结尾的文件使用 TypeScript loader
{test: /.ts$/,loader: 'awesome-typescript-loader'},
{
test:/\.html$/,
loader: 'html'
},
{
test:/\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/,
loader: 'null'
},
{
test:/\.css$/,
loader: 'null'
}
]
}
}
then throws a BUG.
karma start karma.conf.js
keywords if/then/else require v5 option
WebpackOptionsValidationError: Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration.entry should be one of these:
object { : string | [string] } | string | [string]
The entry point(s) of the compilation.
- configuration.resolve.extensions[0] should not be empty.
Can not load "webpack"!
First i don't see any entey point mentioned in config file which is required in order to webpack understand where to start from.
Second your resolve option in config file hase mentioned three types to resolve and first one is empty string which webpack don't like so by removing that empty string it should fix that problem
Hope this help you to fix the issue.
I had the same issue and resolved by updating the karma-webpack package to the latest version.
Is it possible to write unit tests for VueJs if you are using Laravel's Elixir for your webpack configuration?
VueJs 2x has a very simple example for a component test: Vue Guide Unit testing
<template>
<span>{{ message }}</span>
</template>
<script>
export default {
data () {
return {
message: 'hello!'
}
},
created () {
this.message = 'bye!'
}
}
</script>
and then...
// Import Vue and the component being tested
import Vue from 'vue'
import MyComponent from 'path/to/MyComponent.vue'
describe('MyComponent', () => {
it('has a created hook', () => {
expect(typeof MyComponent.created).toBe('function')
})
it ...etc
})
and gives an example of a karma conf file here: https://github.com/vuejs-templates
But the Karma configuration file requires a webpack configuration file
webpack: webpackConfig,
The only problem is the Laravel's Elixir is creating the webpack configuration so it can't be included.
I have tried creating another webpack configuration file based on the example from https://github.com/vuejs-templates/webpack.
Something like this:
var path = require('path');
var webpack = require('webpack');
module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, './dist'),
publicPath: '/dist/',
filename: 'build.js'
},
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
// Since sass-loader (weirdly) has SCSS as its default parse mode, we map
// the "scss" and "sass" values for the lang attribute to the right configs here.
// other preprocessors should work out of the box, no loader config like this necessary.
'scss': 'vue-style-loader!css-loader!sass-loader',
'sass': 'vue-style-loader!css-loader!sass-loader?indentedSyntax'
}
// other vue-loader options go here
}
},
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/
},
{
test: /\.(png|jpg|gif|svg)$/,
loader: 'file-loader',
options: {
name: '[name].[ext]?[hash]'
}
}
]
},
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js'
}
},
devServer: {
historyApiFallback: true,
noInfo: true
},
performance: {
hints: false
},
devtool: '#eval-source-map'
}
and included it like...
// Karma configuration
// Generated on Wed Mar 15 2017 09:47:48 GMT-0500 (CDT)
var webpackConf = require('./karma.webpack.config.js');
delete webpackConf.entry;
module.exports = function(config) {
config.set({
webpack: webpackConf, // Pass your webpack.config.js file's content
webpackMiddleware: {
noInfo: true,
stats: 'errors-only'
},
But I am getting errors that seem to indicate that webpack isn't doing anything.
ERROR in ./resources/assets/js/components/test.vue
Module parse failed: /var/www/test/resources/assets/js/components/test.vue Unexpected token (1:0)
You may need an appropriate loader to handle this file type.
| <template>
| <span >{{test}}</span>
| </template>
Ok, I got this to work. Couple of things that might help.
I was originally running gulp, and trying to run tests in my vagrant box, to try to match the server configuration. I think that makes it much harder to find examples and answers on the internet.
Ok, so the main problem I was having is that webpack wasn't processing my components included in my test files. I copied the webpack config out of the laravel-elixir-vue-2/index.js node module directly into the Karma configuration file and it started working.
The key is that karma-webpack plugin needs both the resolve and module loader configuration settings (resolve with alias and extensions) for it to work.
Hope this helps someone.
karma.conf.js:
module.exports = function (config) {
config.set({
// to run in additional browsers:
// 1. install corresponding karma launcher
// http://karma-runner.github.io/0.13/config/browsers.html
// 2. add it to the `browsers` array below.
browsers: ['Chrome'],
frameworks: ['jasmine'],
files: ['./index.js'],
preprocessors: {
'./index.js': ['webpack']
},
webpack: {
resolve: {
alias: {
vue: 'vue/dist/vue.common.js'
},
extensions: ['.js', '.vue']
},
vue: {
buble: {
objectAssign: 'Object.assign'
}
},
module: {
loaders: [
{
test: /\.vue$/,
loader: 'vue-loader'
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'file-loader',
query: {
limit: 10000,
name: '../img/[name].[hash:7].[ext]'
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
query: {
limit: 10000,
name: '../fonts/[name].[hash:7].[ext]'
}
}
]
}
},
webpackMiddleware: {
noInfo: true,
},
coverageReporter: {
dir: './coverage',
reporters: [
{ type: 'lcov', subdir: '.' },
{ type: 'text-summary' },
]
},
});
};
I ran into the exact same problem. The accepted answer did not fully work for me. The following solved my issue:
Install relevant loaders for webpack:
npm install --save-dev vue-loader file-loader url-loader
Create webpack config file (note the format). The accepted answer produced errors citing invalid format of the webpack.config.js file. At least with me it did.
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.vue$/,
use: [
{ loader: 'vue-loader' }
]
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
use: [
{
loader: 'file-loader',
query: {
limit: 10000,
name: '../img/[name].[hash:7].[ext]'
}
}
]
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
use: [
{
loader: 'url-loader',
query: {
limit: 10000,
name: '../fonts/[name].[hash:7].[ext]'
}
}
]
}
]
}
}
karma.conf.js
// Karma configuration
var webpackConf = require('./webpack.config.js');
delete webpackConf.entry
module.exports = function(config) {
config.set({
frameworks: ['jasmine'],
port: 9876, // web server port
colors: true,
logLevel: config.LOG_INFO,
reporters: ['progress'], // dots, progress
autoWatch: true, // enable / disable watching files & then run tests
browsers: ['Chrome'], //'PhantomJS', 'Firefox',
singleRun: true, // if true, Karma captures browsers, runs the tests and exits
concurrency: Infinity, // how many browser should be started simultaneous
webpack: webpackConf, // Pass your webpack.config.js file's content
webpackMiddleware: {
noInfo: true,
stats: 'errors-only'
},
/**
* base path that will be used to resolve all patterns (eg. files, exclude)
* This should be your JS Folder where all source javascript
* files are located.
*/
basePath: './resources/assets/js/',
/**
* list of files / patterns to load in the browser
* The pattern just says load all files within a
* tests directory including subdirectories
**/
files: [
{pattern: 'tests/*.js', watched: false},
{pattern: 'tests/**/*.js', watched: false}
],
// list of files to exclude
exclude: [
],
/**
* pre-process matching files before serving them to the browser
* Add your App entry point as well as your Tests files which should be
* stored under the tests directory in your basePath also this expects
* you to save your tests with a .spec.js file extension. This assumes we
* are writing in ES6 and would run our file through babel before webpack.
*/
preprocessors: {
'app.js': ['webpack', 'babel'],
'tests/**/*.spec.js': ['babel', 'webpack']
},
})
}
Then run karma start and everything should work.
I'm totally new to the concept of testing, and i need one solid example on how to do it in my project:
I have a gulp file goes like this (Not all of it, just the important portions)
gulp.task('bundle', function() {
gulp.src('public/angular-app/main.js')
.pipe(browserify({
debug: true
}))
.pipe(gulp.dest('public/min-js'));
});
This is a slight portion of my main.js:
'use strict';
angular.module('myApp', [
'ui.router',
'ui.bootstrap',
'ngSanitize',
'ngFx',
...
], ['$interpolateProvider',
function($interpolateProvider) {
$interpolateProvider.startSymbol('{{');
$interpolateProvider.endSymbol('}}');
}
])
.config(require('./config/routes'))
.config(require('./config/authInterceptor'))
.run(require('./config/runPhase'))
.run(require('./config/xeditable'))
.controller('homeController', require('./controllers/homeController'))
.controller('modalInstanceCtrl', require('./controllers/modalInstanceCtrl'))
.controller('modalparticipantCtrl',require('./controllers/modalParticipantCtrl'))
.controller('generatorController',require('./controllers/generatorController'))
.controller('navController', require('./controllers/navController'))
.controller('signInController', require('./controllers/signInController'))
.controller('pricingController', require('./controllers/pricingController'))
.controller('howItWorksController',require('./controllers/howItWorks'))
...
Now this is my config file for karma:
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: [
'public/vendor/jquery/dist/jquery.js',
'public/vendor/angular/angular.js',
'public/vendor/angular-mocks/angular-mocks.js',
'public/angular-app/**/*.js',
'test/**/*Spec.js'
],
// list of files to exclude
exclude: [
],
When i run karma with karma start this is what i get:
Uncaught reference error:require is not defined
at root/public/angular-app/main.js
So my question is simple, how can i do tests, for example, on my homeController...
//update
So I updated my test file to this:
describe("An Angularjs test suite",function(){
var target, rootScope;
beforeEach(inject(function($rootScope) {
rootScope = $rootScope;
// Mock everything here
spyOn(rootScope, "$on")
}));
beforeEach(inject(function(homeController) {
target = homeController;
}));
it('should have called rootScope.$on', function(){
expect(rootScope.$on).toHaveBeenCalled();
});
});
and my config file to this:
// list of files / patterns to load in the browser
files: [
'public/vendor/jquery/dist/jquery.js',
'public/vendor/angular/angular.js',
'public/vendor/angular-mocks/angular-mocks.js',
'public/min-js/main.js',
'test/**/*Spec.js'
],
// list of files to exclude
exclude: [
],
browserify: {
watch: true,
debug: true
},
preprocessors: {
'test/*': ['browserify']
},
Still nothing works, first he says 'unknown provider homeControllerProvider',
Now if i delete them lines:
beforeEach(inject(function(homeController) {
target = homeController;
}));
it still gives me error, expected spy $on to be called, How do i fix this?
You need to inform Karma to run Browserify before running tests.
You can add this in your Karma config:
{
browserify: {
watch: true,
debug: true
},
preprocessors: {
'test/*': ['browserify']
}
}
Karma config file reference: http://karma-runner.github.io/0.12/config/configuration-file.html
Or have a look at one of of my projects that uses Karma for testing: smild.
I'm using Grunt 0.4.5 with these dependencies in my project:
"grunt": "~0.4.5",
"grunt-contrib-concat": "~0.5.0",
"grunt-contrib-uglify": "~0.6.0",
"grunt-contrib-watch": "~0.6.1",
"grunt-contrib-sass": "~0.8.1"
I've just noticed that grunt-autoprefixer didn't get added to my package.json file. Is that because it doesn't have the grunt-contrib prefix? Anyway, Source Maps work for me when I remove autoprefixer from my watch task, but as soon as I add it in again the comment at the very end of the compiled css file gets removed.
This is my autoprefixer config:
autoprefixer: {
options: {
browsers: ['last 2 version', 'ie 8', 'ie 9']
},
single_file: {
options: {
// Target-specific options go here.
},
src: 'library/css/style.css',
dest: 'library/css/style.css'
},
sourcemap: {
options: {
map: true
}
},
},
My Sass config looks like this:
sass: {
dist: {
options: {
style: 'expanded',
debugInfo: true,
sourcemap: true
},
files: {
'library/css/style.css': 'library/scss/style.scss'
}
}
},
and here's my watch task:
watch: {
options: {
livereload: true,
},
scripts: {
files: ['library/js/*.js'],
tasks: ['concat', 'uglify'],
options: {
spawn: false,
},
},
css: {
files: ['library/scss/*.scss'],
tasks: ['sass', 'autoprefixer'],
sourceComments: 'normal',
options: {
spawn: false,
}
},
page: {
files: ['*.php', '*.html']
}
}
I don't get why autoprefixer has to interfere with the source map at all to be honest, I tried using false instead of true, specifying the sourcemap manually as per the example in the grunt-autoprefixer repo, but whatever I do the comment - /*# sourceMappingURL=style.css.map */ gets stripped from the file and source maps don't work in chrome.
EDIT: Sorry, I just got it to work by using:
sourcemap: {
options: {
map: true
},
src: 'library/css/style.css',
dest: 'library/css/style.css' // -> dest/css/file.css, dest/css/file.css.map
},
I'd be interested to know, for performance reasons, do I need to bother specifying a sourcemap option at all in the grunt-contrib-sass config now? It takes me about 2.4s to compile so every 0.1s counts!
Sorry, I just got it to work by using:
sourcemap: {
options: {
map: true
},
src: 'library/css/style.css',
dest: 'library/css/style.css' // -> dest/css/file.css, dest/css/file.css.map
},
I'd be interested to know, for performance reasons, do I need to bother specifying a sourcemap option at all in the grunt-contrib-sass config now? It takes me about 2.4s to compile so every 0.1s counts! I'll do some testing and see, as far as I can see it looks like source maps are generated by default now by sass, so I probably only need to specify this in autoprefixer
I found the following worked for me:
sass: {
options: {
sourceMap: true,
sourceMapEmbed: false
},
dist: {
files: {
'css/style.css': 'css/src/style.scss',
'css/debug.css': 'css/src/debug.scss',
}
}
},
autoprefixer: {
//prefix all files
multiple_files: {
expand: true,
flatten: true,
src: 'css/*.css',
dest: 'css/'
},
options: {
map: true,
annotation: false
}
},
Without specifying annotation: false, I found that autoprefixer always overwrote the /*# sourceMappingURL=style.css.map */ with a data-uri sourceMappingURL that would not work (my browser inspectors would not show the original .scss source).
I also found that using sourcemap as in the accepted answer does not work if you have multiple scss/css files. I believe sourcemap allows you to set a different set of options for each scss->css mapping, but I wanted the same settings for all of mine.
Hope this helps!