grunt jasmine-node tests are running twice - javascript

I set up grunt to run node.js jasmine tests. For some reason, with this config, the results always show double the tests.
Here is my config:
I'm using jasmine-node which plugs into grunt.
/spec/some-spec.js:
var myModule = require('../src/myModule.js');
describe('test', function(){
it('works', function(done){
setTimeout(function(){
expect(1).toBe(1);
done();
}, 100);
});
});
Gruntfile.js:
module.exports = function(grunt) {
grunt.initConfig({
jasmine_node: {
options: {
forceExit: true
},
all: ['spec/']
}
});
grunt.loadNpmTasks('grunt-jasmine-node');
grunt.registerTask('default', ['jasmine_node']);
};
This results in two tests running rather than one.
> grunt
Running "jasmine_node:all" (jasmine_node) task
..
Finished in 0.216 seconds
2 tests, 2 assertions, 0 failures, 0 skipped

I was able to reproduce the behavior. This is what seems to be happening:
The task looks in the specified folder (spec in your case) for files with spec in the name.
Then it looks again in every folder in the whole project for files with spec in the name.
What it ends up with is 2 overlapping sets of test files to run.
My first attempt at trying to coerce it into more logical behavior was to set specNameMatcher: null (default is 'spec'), and leave the folder set to 'spec/'. This results in no tests being run, since apparently both conditions (name and folder) must be met for files in the specified folder. You get the same problem if specNameMatcher is left at the default value, but the files in the folder don't have 'spec' in the name.
What does work is to set the folder (or 'test set' or whatever you want to call it) to []:
jasmine_node: {
options: {
forceExit: true
},
all: []
}
The catch is that if you have any other files somewhere else in the project with 'spec' in the name, they'll be mistaken for tests by jasmine.
I would consider this behavior a bug, and it should probably be reported via the project's github issues page.

This grunt plugin ( https://github.com/jasmine-contrib/grunt-jasmine-node ) seems to be dead ( https://github.com/jasmine-contrib/grunt-jasmine-node/issues/60 ).
Maybe it is a better to switch to https://github.com/onury/grunt-jasmine-nodejs ?

The jasmine-node project is pretty old. The latest commit is from July of 2014. The grunt-jasmine-node plugin appears to be active, but running against something that is going stale seems a little pointless IMHO.
To test CommonJS modules using Jasmine I'd recommend using Karma along with the
karma-jasmine and karma-commonjs plugins. I got your example working with the following files:
package.json
{
"private": "true",
"devDependencies": {
"grunt": "^0.4.5",
"grunt-jasmine-node": "^0.3.1",
"grunt-karma": "^0.10.1",
"jasmine-core": "^2.3.4",
"karma": "^0.12.31",
"karma-commonjs": "0.0.13",
"karma-jasmine": "^0.3.5",
"karma-phantomjs-launcher": "^0.1.4"
}
}
karma.conf.js
module.exports = function(config) {
config.set({
basePath: '.',
frameworks: ['jasmine', 'commonjs'],
files: [{
pattern: 'src/**/*.js'
}, {
pattern: 'spec/**/*.js'
}],
preprocessors: {
'src/**/*.js': ['commonjs'],
'spec/**/*.js': ['commonjs']
},
reporters: ['progress'],
browsers: ['PhantomJS']
});
};
Gruntfile.js (optional if you still want to use grunt)
module.exports = function(grunt) {
grunt.initConfig({
karma: {
unit: {
configFile: 'karma.conf.js',
options: {
singleRun: true
}
}
}
});
grunt.loadNpmTasks('grunt-karma');
grunt.registerTask('default', ['karma:unit']);
};
You should also install the karma command line runner globally, just like you probably did with grunt. npm install -g karma-cli
From your command line you can start karma by typing karma start. It will run the tests and then watch your files and re-run them on every save. (VERY NICE)
Alternatively you can run karma start --single-run to have it just run your tests once and exit. If you also updated your Gruntfile you can also just run grunt to run the tests once.

The current up voted answer isn't the solution. You simply modify the expression that's going to match your tests. The answer is as follows:
module.exports = function(grunt) {
grunt.initConfig({
jasmine_node: {
options: {
forceExit: true
},
all: ['spec/*spec.js']
}
});
grunt.loadNpmTasks('grunt-jasmine-node');
grunt.registerTask('default', ['jasmine_node']);
};
Here you can see that 'all' is set to *'spec/spec.js'. This will search for all tests.
Secondly, just because a project hasn't had a recently commit, doesn't mean it's "old". jasmine-node is simply stable.

I have the same issue using grunt-jasmine-node, and as aeryaguzov points out, that project is no longer maintained. Switching to grunt-jasmine-node-new solves the issue for me.
grunt-jasmine-node-new is a fork of grunt-jasmine-node that is actively maintained, and can be found here: https://www.npmjs.com/package/grunt-jasmine-node-new

Related

Next.js Scripts Error: Cannot find module '../../webpack-runtime.js'

I want to create RSS script using Next.js.
So I put up a script in a subfolder inside the root folder scripts/ & named it build-rss.js
next.config.js
module.exports = {
webpack: (config, options) => {
config.module.rules.push({
test: /\.svg$/,
issuer: { and: [/\.(js|ts|md)x?$/] },
use: [
{
loader: '#svgr/webpack',
options: {
prettier: false,
svgo: true,
svgoConfig: { plugins: [{ removeViewBox: false }] },
titleProp: true,
},
},
],
})
if (!options.dev && options.isServer) {
const originalEntry = config.entry
config.entry = async () => {
const entries = { ...(await originalEntry()) }
entries['./scripts/build-rss'] = './scripts/build-rss.js'
return entries
}
}
if (!options.isServer) {
config.resolve.fallback.fs = false
}
return config
},
}
When I try to run my script npm run build:development which in package.json represents:
"scripts": {
"clean": "rimraf .next",
"dev": "next dev",
"export": "next export",
"start": "next start",
"lint": "next lint",
"build:development": "next build && npm run export && npm run rss:development",
"build": "next build && npm run export && npm run rss",
"rss:development": "node ./.next/server/scripts/build-rss.js",
"rss": "node ./.next/serverless/scripts/build-rss.js"
}
It throws an error saying:
Error: Cannot find module '../../webpack-runtime.js'
But I checked. The file does exist.
The blunder is this used to work earlier. Probably few versions ago when my other project used the same combination.
I have made a complete reproduction showcasing the error → https://github.com/deadcoder0904/next-script-rss-error
Just clone it, install it & try the script npm run build:development in the terminal to see the error.
Based on our conversation:
entry: path.join(__dirname, '..', 'path/to/file')
That's what a webpack entry looks like. It can also be an array or an object:
entry: [
path.join(__dirname, '..', 'path/to/file'),
// other entries here
]
Whereas you're already getting the whole webpack config:
webpack: (config, options)
So doing:
const originalEntry = config.entry
config.entry = async () => {
const entries = { ...(await originalEntry()) }
entries['./scripts/build-rss'] = './scripts/build-rss.js'
return entries
}
Makes no sense to me if you can just do:
config.entry.push('./scripts/build-rss')
// config.entry['./scripts/build-rss'] = './scripts/build-rss.js'
Unless I miss something with how nextjs is loading the webpack config.
Even then I'd suggest that you use path.join in order to ensure it's loaded to the correct location, because that relative root will execute from wherever webpack is compiled from.
Along with that in your first project you used nextjs v10 and now you're using nextjs v11, which has an upgrade from webpack 4 to 5, which is a major upgrade. I don't know the details, I can only speculate, but under no conditions should you assume that "because your previous project was working this one should using the same stuff", it won't necessarily (especially not in this case).
The first intuitive thing I thought was that webpack should by default bundle everything to a single output file, unless the configuration for that was changed by nextjs (I don't know). So using a script you added to entries didn't make sense to me, because it wouldn't exist. But you're saying that it does exist so I can only assume that webpack is configured to do code splitting and outputs each entry to a different file. In which case I have no idea. As far as I'm aware in webpack 5 (I don't know about webpack 4) code splitting is disabled in dev and enabled in production so your problem is likely a discrepancy between dev and production.
Perhaps the last thing you can try is to change your !options.dev, because right now you're only adding that script when it's production but you're trying to run the script using development.
If you really just have to get it working you can downgrade your nextjs to the previous version you were using (v10), even though that's not really a solution.
Other than that I'm out of ideas.
Not sure if you are still looking for an answer, but simply changing the webpack entry as follows seems to have fixed the problem.
entries['scripts/build-rss'] = './scripts/build-rss.js';
// instead of entries['./scripts/build-rss']
I had the same Error! I deleted the .next Folder and did an npm run dev, It started to work for me!

Foundation-Apps angular site integration with karma-jasmine unit testing

I believe there is a problem with using angular-mocks and foundation-apps when trying to run a karma jasmine unit test. It could also be that I have missed something. Since there is so much code to see I have posted an example project on github for review.
Basically the site runs fine and karma runs the test but when you debug into the angular.mocks.module function you find that your module from your app is not being loaded.
If you take foundation-apps out of the situation it will work fine.
Could this be a version conflict because foundation-apps has an older dependency for angular-mocks?
fatest on github
I hit the same issue and my solution was to add resulting css-file (app.css - generated with sass task) to karma configuration. Without this file i got:
TypeError: 'null' is not an object (evaluating 'mediaQueries[key].replace')
Here is my gulp config:
var karma = require('karma').server;
//...........//
// Compiles Sass
gulp.task('sass', function () {
return gulp.src('client/assets/scss/app.scss')
.pipe(plugins.sass({
includePaths: paths.sass,
outputStyle: (isProduction ? 'compressed' : 'nested'),
errLogToConsole: true
}))
.pipe(plugins.autoprefixer({browsers: ['last 2 versions', 'ie 10']}))
.pipe(gulp.dest('./build/assets/css/'))
.pipe(plugins.livereload());
});
/// ..... some other things here ......///
gulp.task('unit-test', function (done) {
var testFiles = [
{pattern:'./build/assets/js/foundation.js',watched:false},
{pattern:'./build/assets/js/routes.js',watched:false},
{pattern:'./build/assets/css/app.css',watched:false},
{pattern:'./build/assets/js/templates.js',watched:false},
{pattern:'./bower_components/angular-mocks/angular-mocks.js', watched:false},
{pattern:'./client/assets/js/*.js'},
{pattern:'./client/templates/**/*.js'}
];
karma.start({
configFile:__dirname + '/karma.conf.js',
singleRun: true,
files: testFiles
}, done);
});
Assuming your application is already builded, just run gulp unit-test.

Karma: Running a single test file from command line

So, I've been looking all over for this, found "similar" answers here, but not exactly what I want.
Right now if I want to test a single file with karma, I need to do fit(), fdescribe() on the file in question...
However, what I do want is to be able to just call karma, with the config file, and direct it to a specific file, so I don't need to modify the file at all, ie:
karma run --conf karma.conf.js --file /path/to/specific/test_file.js
is it possible to do this? Or with any helper? (using grunt or gulp?)
First you need to start karma server with
karma start
Then, you can use grep to filter a specific test or describe block:
karma run -- --grep=testDescriptionFilter
Even though --files is no longer supported, you can use an env variable to provide a list of files:
// karma.conf.js
function getSpecs(specList) {
if (specList) {
return specList.split(',')
} else {
return ['**/*_spec.js'] // whatever your default glob is
}
}
module.exports = function(config) {
config.set({
//...
files: ['app.js'].concat(getSpecs(process.env.KARMA_SPECS))
});
});
Then in CLI:
$ env KARMA_SPECS="spec1.js,spec2.js" karma start karma.conf.js --single-run
This option is no longer supported in recent versions of karma:
see https://github.com/karma-runner/karma/issues/1731#issuecomment-174227054
The files array can be redefined using the CLI as such:
karma start --files=Array("test/Spec/services/myServiceSpec.js")
or escaped:
karma start --files=Array\(\"test/Spec/services/myServiceSpec.js\"\)
References
karma-runner source: cli.js
karma-runner source: config.js
I tried #Yuriy Kharchenko's solution but ran into a Expected string or object with "pattern" property error.
Therefore I made the following modifications to his answer and now I'm able to run single files using Karma:
function getSpecs(specList) {
if (specList) {
return specList.toString();
} else {
return ['**/*_spec.js'] // whatever your default glob is
}
}
module.exports = function(config) {
config.set({
//...
files: [
{ pattern: getSpecs(process.env.KARMA_SPECS), type: "module"}
]
});
});
Note: This solution only works with a single file mentioned in the KARMA_SPECS env variable. Ex: export KARMA_SPECS="src/plugins/muc-views/tests/spec1.js"

Karma jasmine tests: Highlight diff in terminal

I'm using Karma with Jasmine for my tests. In some tests, I have large objects that the test relies on. When I do something like
expect(obj).toEqual(expectedObj);
and obj != expectedObj, I get an error message in my terminal. But this error is really long, because it includes both of the objects, and it's very hard to see, in what parts the two objects are different.
So, is there any highlighter for the terminal, that can be used along with karma? This way, it would be much more easy to figure out, what's wrong.
I had the same problem and what did it for me was karma-jasmine-diff-reporter.
Just install it:
npm install karma-jasmine-diff-reporter --save-dev
and configure it as a reporter, eg:
// karma.conf.js
module.exports = function(config) {
config.set({
reporters: ['jasmine-diff']
});
};
You can configure it to pretty print:
// karma.conf.js
module.exports = function(config) {
config.set({
reporters: ['jasmine-diff'],
jasmineDiffReporter: {
pretty: true, // 2 spaces by default for one indent level
matchers: {
toEqual: {
pretty: false // disable pretty print for toEqual
}
}
}
});
};
Output will be something like this:

How to get better test reports in the console?

I have a fairly simple karma.config.js file
basePath = '../';
files = [
JASMINE,
JASMINE_ADAPTER,
'js/lib/angular*.js',
'test/lib/angular/angular-mocks.js',
'js/**/*.js',
'test/unit/**/*.js'
];
autoWatch = true;
browsers = ['PhantomJS'];
When I run karma start config/karma.conf.js --single-run I'm getting the following output
$ karma start config/karma.conf.js --single-run
[2013-06-24 23:47:08.750] [DEBUG] config - autoWatch set to false, because of singleRun
INFO [karma]: Karma server started at http://localhost:9876/
INFO [launcher]: Starting browser PhantomJS
INFO [PhantomJS 1.9 (Mac)]: Connected on socket id LwMoWxzIbSUuBsvIqB_m
PhantomJS 1.9 (Mac): Executed 6 of 6 SUCCESS (0.073 secs / 0.02 secs)
I've been searching for something to tell me how to get the output of the tests that get logged (e.g. SUCCESS Unit: services myService should behave)
The only way I can see the output of the tests is to open Chrome and click 'Debug', then show the developer tools console. I want the messages to be logged out to the terminal, but I cannot figure out how to get this working.
Fixed by installing the karma-spec-reporter
npm install karma-spec-reporter --save-dev
and adding this my karma.config.js
reporters: ['spec'],
According to karma documentation
By default, Karma loads all NPM modules that are siblings to it and their name matches karma-*.
but some users have had to add the following to their config
plugins: ['karma-spec-reporter']
Just another detail - if you keep the default reporter 'progress' in the karma.config.js, like below:
reporters: ["progress", "spec"]
or another console reporter, the "spec" reporter output won't work.
You should keep only the "spec" one, or the "spec" with other browser reporters. For example:
reporters: ["spec", "coverage"]
I wrote a reporter to make the output more readable: karma-helpful-reporter
Has some nice customization options: https://github.com/whyboris/karma-helpful-reporter
Instal instructions inside, basically npm install --save-dev karma-helpful-reporter and then add to the Karma configuration plugins section:
plugins: [
require('karma-helpful-reporter')
],
reporters: [ 'helpful' ],
You can also use the Karma-mocha-reporter
as reporter and you should have a clean report in your console.
npm i karma-mocha-reporter --save-dev
// karma.conf.js
module.exports = function(config) {
config.set({
frameworks: ['jasmine'],
// reporters configuration
reporters: ['mocha']
});
};
Sometimes, e.g in #angular/cli environment you should require this like:
plugins: [
...
require('karma-mocha-reporter'),
...
]
Here is my working (draft) configuration without the section 'plugins' (actually I don't fully understand why I should need to specify them ...):
package.json
"devDependencies": {
[...]
"grunt-karma": "~0.9.0",
"karma": "~0.12.24",
"karma-jasmine": "~0.2.3",
"karma-chrome-launcher": "~0.1.5",
"karma-phantomjs-launcher": "~0.1.4",
"karma-spec-reporter": "0.0.13"
}
karma.conf.js
module.exports = function (config) {
config.set({
frameworks: ['jasmine'],
reporters: ['spec'],
browsers: ['PhantomJS']
});
};
Gruntfile.js
karma: {
options: {
configFile: 'karma.conf.js',
files: [
'app/libs/angular.js',
'app/libs/angular-resource.js',
'app/libs/angular-route.js',
[...]
'app/modules/**/*-spec.js'
]
},
unit: {
singleRun: true
}
}
Now when I run grunt karma messages from the *-spec.js files (describe('message', function() ...)) are displayed nicely in the console.

Categories

Resources