16

I want to run some tests with Karma using multiple browsers. However, the tests are integration tests that interact with the database (get and update data). Since the same tests are run in multiple browsers, they all interact with the same test data.

Therefore, if the tests are run concurrently in multiple browsers, one test may impact other tests running in other browsers.

How can I limit the number of concurrent browsers, while still testing with multiple browsers? (for example, setting a limit to 1 would result in running tests for each browser in sequence instead of in parallel)

Andy
  • 17,423
  • 9
  • 52
  • 69
ckarras
  • 4,946
  • 2
  • 33
  • 37

3 Answers3

5

This has been fixed in https://github.com/karma-runner/karma/pull/1646 and merged into 0.13.2:

concurrency

Type: Number

Default: Infinity

Description: How many browser Karma launches in parallel.

Especially on sevices like SauceLabs and Browserstack it makes sense to only launch a limited amount of browsers at once, and only start more when those have finished. Using this configuration you can sepcify how many browsers should be running at once at any given point in time.

https://karma-runner.github.io/2.0/config/configuration-file.html

Community
  • 1
  • 1
Andy
  • 17,423
  • 9
  • 52
  • 69
0

Just an rough idea:

  • Create a wrapper around karma to create a configuration object based on your criteria
    • In this case it will be a configuration object per browser type I guess
    • You can have a "configuration template" stored in a karma.conf.js file without the browsers property
    • There's a programmatic way to "enrich" this template adding more properties
  • Populate a queue with these configuration objects (it can be a simple array)
  • Use the karma API to launch the karma server passing the right configuration every time

Tip: You can have at this point a "wrapper" configuration to stop or carry on if a running instance face some errors

This snippet of code shows how to load and fill a template configuration:

function getConfigTemplate(path){
  var config = {
    // Maybe you want to add/remove some files from the list
    // based on some criteria
    files: [...],
    // Path of the template file
    configFile: path
  }
  return config;
}

var template = getConfigTemplate('/path/to/the/file');
// Here I can append more stuff
template.browsers = ['Chrome']

Note: the merging strategy used in karma for the two configurations works as follow:
- If a property is on the template, then it goes straight to the final configuration
- If a property is not on the template then the configuration "wrapper" object is looked up for that property
- If you a property on the template and add more on the wrapper, only the former will used and the latter will be ignored.

This code instead can be used to "chain" your karma servers:

var currentServer = 0;
var configs  = [ ... ];

function startKarmaServer(config, callback){
  karma.server.start(config, function (exitCode){

    if(exitCode){
      // an error occurred
      // stop karma!
    } else {
       currentServer++;
       callback();
    }
  });
}

function startServers(){
  // here some code to run the karma servers in series
}

I would recommend async.js for the startServers function.

In case you're using an older version of karma (0.10 or below) you may have a look at this fix for closing the web server after the execution.

Also, note that the Continuos Integration flag (autoWatch) should be off in order to make the chaining work.

MarcoL
  • 9,829
  • 3
  • 37
  • 50
0

If you are using grunt with grunt-karma I wrote this task that does what you want.

Malki
  • 2,335
  • 8
  • 31
  • 61