Skip to content

Repository files navigation

rspec-queue

A parallel test runner specifically for rspec.

The main difference between this and similar gems is that it spawns entirely new worker processes instead of forking. This makes configuring the workers easier (especially when Rails is involved) as many things will "just work".

It's intended to work with RSpec >= 3.2. It may work with earlier versions, but I doubt it.

Usage

Put it in your Gemfile, bundle, and you're away.

gem'rspec-queue'

If you need isolated databases, you'll need to ensure they are prepared before attempting to run any tests.

Add any configuration needed for each worker to your spec_helper file.

RSpecQueue::Configuration.after_worker_spawndo |index|
# Establish connection to an isolated databaseActiveRecord::Base.configurations['test']['database'] << index.to_sActiveRecord::Base.establish_connection(:test)end

Running tests via rspec-queue is the same as running them via rspec.

bundle exec rspec-queue spec

By default, rspec-queue will spawn a number of workers equal to one less than the count of your total cpus. You can override this behaviour by setting the RSPEC_QUEUE_WORKERS environment variable.

RSPEC_QUEUE_WORKERS=6 bundle exec rspec-queue spec

Potential Issues

If you're doing some form of acceptance testing you'll probably want to use xvfb to isolate the browsers for each worker so they don't do annoying things like steal focus from each other. This can cause many headaches trying to debug strange failures!

Fortunately, there's a gem for that: https://github.com/leonid-shevtsov/headless

You can then add some extra configuration in the after_worker_spawn block to use a different display for each worker:

RSpecQueue::Configuration.after_worker_spawndo |index|
# ...Headless.new(display: 100 + index.to_i,reuse: true,destroy_at_exit: true).startend

If you're using Rails with page caching in test, you probably want to isolate the public folders for each worker. This should probably be done in your test environment configuration. It should be as easy as making a copy of your public folder for each worker.

# test.rbRails.application.configuredo# ...# RSPEC_QUEUE_WORKER_ID is a unique identifier for the current workerifENV["RSPEC_QUEUE_WORKER_ID"]# copy the public directory to a distinct foldermaster_public_path=Rails.root.join("public")worker_root_path=Rails.root.join("tmp","rspec-queue",ENV["RSPEC_QUEUE_WORKER_ID"])FileUtils.mkdir_pworker_root_pathFileUtils.cp_rmaster_public_path,worker_root_pathworker_public_path=worker_root_path.join("public")# point rails to the new directoryconfig.paths["public"]=worker_public_pathconfig.action_controller.page_cache_directory=worker_public_pathendend

Setting a distinct public folder can also assist with issues that arise when uploading files in acceptance tests.

Things that aren't great

The way the formatting works isn't great. It was hacked together in a rush and extracted from an existing codebase as is. It unfortunately means that this gem won't work with any formatter that isn't it's own. The way the formatter is set in the rspec-queue binary is also not ideal and will likely cause issues with certain setups.

At the moment, the worker passes some lo-fi results to the server over the unix socket, but not the full set of example results that most formatters use and expect. To deal with this we use our custom formatter that only needs basic information.

However, if we want to use another formatter, we would need to reconstruct much more information, which is difficult to marshal/unmarshal, and if we try to do this manually we risk coupling ourselves to a particular rspec version's internals.

The plan is to fix that so it will work just fine with any formatter and make the configuration more sensible, but right now, it is how it is.


MIT license.

About

No description, website, or topics provided.

Resources

Stars

12 stars

Watchers

12 watching

Forks

Releases

Packages

Used by

Contributors

Languages