Continuously complinig and running my coffeescript tests with karma - coffeescript

I'm using grunt, karma (singleRun: false). My tests are written in coffeescript. Each time my coffee file changes I want my tests to run. The problem is that I don't know how to make both happens.
So far I discovered the watch task, I tried to add my coffee thing there and add the watcher to my test task like that:
//karma.conf.js
singleRun: true,
and in Gruntfile:
//Gruntfile.js
watch: {
coffee: {
files: ['test/spec/{,*/}*.coffee'],
tasks: 'coffee'
}
}
grunt.registerTask('test', [
'clean:server',
'coffee',
'concurrent:test',
'autoprefixer',
'connect:test',
'karma',
'watch:coffee'
]);
This way the karma watcher is watching javascript files, but my own coffee watcher is not triggered at all.
Right now I just removed watch:coffee from test task and I'm running grunt test and grunt watch:coffee in parallel terminals, which looks a bit pathetic. Is there a better way?

Much better approach is to use the karma-coffee-preprocessor. It's simple to set up and I can use singleRun: true.

Related

How to run multiple feature files in sequence using Cucumber + protractor

I want to run feature files in a desired order or sequence, for example:
tags:"`#ProtractorScenario` or #CucumberScenario"
But cucumber scenario is getting executed first. Can someone guide me on this?
Note: Cucumber is executing scenario based on alphabetical order of feature file in folder
Also, in cases with more than 50+ feature files, what would be the best way to define sequencing of cucumber feature files?
In order to have reliable tests, your tests should be independent and not rely on the order they are run in. The reason being that your test shouldn't depend on the system being in a certain state, as this will lead to flaky tests. Each of your tests should set up the expected state (and teardown!), so they can be run independently.
Below is how protractor executes cucumber feature files:
Protractor finds out all feature files specified in specs, save the absolute file path into an array, let's call it feature_list.
Protractor starts a session (start a browser instance)
Protractor generates a Cucumber CLI as below, and execute the CLI to hand over the running control cucumber:
./node_modules/bin/cucumber --require xxx --format xxx feature1,feature2,....featureN
feature1,feature2,....featureN calculated by feature_list.join(',')
From above, we can learn the only opportunity to change the order
is given an order-done feature_list to protractor specs.
Note: every member of the feature_list should be absolute/relative
path of single feature file. folder and wildcard are not recommended to appear in the path.
You can get a solution code from my github: spec.filter.js, which implements:
filter feature file by cucumberOpts.tags
order filter result of above step 1 by priority
Guide to use spec.filter.js:
// protractor conf file
const specFilter = require('./spec.filter.js');
var config = {
seleniumAddress: 'xxxxx',
capabilities:'xxxx',
framework: 'custom',
frameworkPath: require.resolve('protractor-cucumber-framework'),
ignoreUncaughtExceptions: true,
specs: [
'./aa/**/*.feature',
'./bb/**/*.feature'
],
cucumberOpts: {
require: [
'xxx'
],
priorities: {
// feature has tag #SPGC-21542 or #SPGC-21944 or #SPGC-21946
// will has priority 1
'1': ['#SPGC-21542 or #SPGC-21944', '#SPGC-21946'],
// feature has tag #SPGC-22055 will has priority 2,
// feature has heighest priority will put ahead at
// the `specs` list and get executed firstly.
'2': ['#SPGC-22055']
}
tags: ""
}
....
};
exports.config = specFilter(config);

Override JSHint Options by using the Grunt Command-Line

By calling
grunt jshint:path_to_file
I want to override the default JSHint configuration
grunt.initConfig({
jshint: {
options: {
curly: true,
eqeqeq: true,
eqnull: true,
browser: true,
globals: {
jQuery: true
}
},
all: ['Gruntfile.js', 'Scripts/src/**/*.js']
}
});
and only include that specific file.
"grunt jshint path_to_file" would also be okay yet I do not want to use the
grunt jshint --file=filePath
grunt.option function unless it can do what I need.
Is this achievable somehow?
The spirit of grunt is more to code which files to use in the gruntfile itself than specifying it on the command line.
So we would need more details on why you want to do that. I imagined 2 possibilities:
you only want to work on a subcomponent: in that case, you would declare different targets for each and call the targets from the command line: grunt jshint component1 with in your Gruntfile:
jshint: {
component1: [filePath1],
component2: [filePath2]
}
it's a performance issue: you only want to jshint some files because only them changed. In that case, combine grunt-contrib-watch (to run jshint on file change) and grunt-newer (to only run on the modified files)

How to suppress output for skipped tests in Jasmine

If I have the scenario with 1000+ tests and want to run only selected portion of them I can use fdescribe.
The rest of tests are skipped which is great however they still pollute the console output. How can I suppress the console output for skipped tests?
If you're running tests via Karma, there is a spec reporter plugin that you can configure to ignore various things.
https://www.npmjs.com/package/karma-spec-reporter
https://www.npmjs.com/package/karma-spec-reporter-2
Add the following to your karma.conf.js:
...
config.set({
...
reporters: ["spec"],
specReporter: {
suppressSkipped: true, // do not print information about skipped tests
},
plugins: ["karma-spec-reporter"],
...
If you're not using Karma, then you need to find the proper Jasmine reporter and configure it, or create your own reporter.
https://www.npmjs.com/package/jasmine2-reporter
If you're using the mocha reporter:
reporters: ['mocha'],
mochaReporter: {
ignoreSkipped: true,
},

How do I run only certain tests in karma?

I have karma config set up correctly, config file, running in the background, just great. As soon as I change and save a file, it reruns the tests.... all 750 of the unit tests. I want to be able to run just a few. Short of manually hacking the config file or commenting out hundreds of tests across many files, is there any easy way to do it?
E.g. when running command line server tests using say mocha, I just use regexp: mocha -g 'only tests that I want'. Makes it much easier to debug and quickly check.
So now I feel foolish. mocha supports a very narrow version of regexp matching.
This runs all tests
describe('all tests',function(){
describe('first tests',function(){
});
describe('second tests',function(){
});
});
This runs just 'first tests'
describe('all tests',function(){
describe.only('first tests',function(){
});
describe('second tests',function(){
});
});
You can also do it.only()
I should have noticed that. Sigh.
You can do that at karma startup time unfortunately, not at runtime.
If you want to change it dynamically you have to put some more effort.
Say you want to focus on a specific set/suite of tests from the beginning, on the karma-mocha plugin page there's this snippet of code to do what you want:
module.exports = function(config) {
config.set({
// karma configuration here
...
// this is a mocha configuration object
client: {
// The pattern string will be passed to mocha
args: ['--grep', '<pattern>'],
...
}
});
};
In order to make the <pattern> parametric you have to wrap the configuration file in a Configurator that will listen CLI and customize the karma configuration for you.
Have a look to this SO answer to know how to setup a very simple Configurator.
I have same question and this is my workround by a little change on karma.conf.js.
In fact, take an argument from command line and modify the pattern in "files".
I use minimist to parse the argument list.
In config file:
/* Begin */
var minimist = require('minimist');
var argv = minimist(process.argv);
var testBase="test/unit";
var testExt=".spec.js";
var unitTestPattern = testBase+'/**/*'+testExt;
if ("test" in argv){
unitTestPattern = testBase+"/"+argv["test"]+testExt;
}
/* End */
module.exports = function(config){
config.set({
//....
files : [
//....
unitTestPattern, //place here
// 'test/unit/**/*.spec.js', //replace this
//....
],
//....
});
};
run in command prompt:
karma start test/karma.conf.js --single-run --test #TEST_CASE_FILE#
a nice extension that can help here is karma-jasmine-html-reporter-livereload
https://www.npmjs.com/package/karma-jasmine-html-reporter-livereload
or karma-jasmine-html-reporter https://www.npmjs.com/package/karma-jasmine-html-reporter?__hstc=72727564.86845f057bb4d741f59d578059e30644.1443860954685.1453095135802.1453138187458.37&__hssc=72727564.1.1453138187458&__hsfp=2285154675
It creates a debug page in which you can run each test individually. very useful for large projects!
1) In your karma.conf.js get the params from the terminal:
var files = (process.env.npm_config_single_file) ? process.env.npm_config_single_file : 'test/test_index.js';
2) In order to run a single test you will need to set an option object with all your configuration (Without files and preprocessors):
var option = {
webpack: {
// webpack configuration
},
// more configuration......
};
3) Set your files path and preprocessors:
option.files = [
{pattern: files, watch: false}
];
option.preprocessors = {};
option.preprocessors[files] = [ 'webpack', 'sourcemap' ];
// call config.set function
config.set(option);
4) Run in the terminal:
npm test --single_file=**/my-specific-file-spec.js
For more information check this PR:
https://github.com/webpack/karma-webpack/pull/178
There are different ways to do it.
Use --grep option. The disadvantage of this is that all the tests are preprocessed before running the specific test suite.
Use .only method. Disadvantage same as no. 1. Using both 1 and 2 method my node process used to crash often saying out of memory.
Limit the files options for processing. This is super fast.
Limit preprocessing to certain folder like Unit or Integration folder.
For this I have used custom cli option --only and in the karma config
const modules = config.only;
and in the the files pattern
files: typeof modules === 'string ? '[`tests/**/${module}/**/*.(test|spec).js`]: 'tests/**/*.(test|spec).js'
Advantage: Developers can run only certain tests when they make a small change way faster by limiting in the preprocessing phase.
You can also use combination of no.3 and no.1 or 2.

Writing Mocha tests with IcedCoffeeScript?

I'm trying to run some database queries in a Mocha test but I'm running into some problems.
Here's the test (using Mongoose):
it.only "should create some objects", (done) ->
await models.MyModel1.count defer(err, oldModel1Count)
await models.MyModel2.count defer(err, oldModel2Count)
# ... do some stuff
await models.MyModel1.count defer(err, newModel1Count)
await models.MyModel2.count defer(err, newModel2Count)
assert.equal oldModel1Count + 1, newModel1Count
assert.equal oldModel2Count + 1, newModel2Count
The command for running the tests:
mocha --compilers coffee:iced-coffee-script --require iced-coffee-script --require mocha --colors --recursive test"
The error happens on the first line:
ReferenceError: err is not defined
I can only assume that it is attempting to use normal CoffeeScript to execute this code, so it thinks that defer is a function and attempts to evaluate err.
Is it possible to write the Mocha tests in IcedCoffeeScript?
This works for me
mocha --require ./fix_my_iced_tests.js --compilers coffee:coffee-script
create fix_my_iced_tests.js
require('iced-coffee-script').register()
create test/some_test.coffee (this make sure that fix actually works)
assert = require 'assert'
describe 'test section', ()->
it 'is ok', (done)->
await setTimeout (defer next), 100
assert.strictEqual(1, 1)
done()
return
return
You should recieve something like this
Type subdsl
√ is ok (102ms)
1 passing (109ms)
without fix you should recieve something like this
ReferenceError: next is not defined
--- EDITED ---
Much better option found here
mocha --compilers coffee:iced-coffee-script/register
Not sure if that's still relevant, but it's 2015 now, and Node.js has first-class support for Promises and Generators, which enables you to write your code exactly as concise and elegant as IcedCoffeeScript, but with a lot less wrinkles.