Low commit activity in last 3 years
A long-lived project that still receives updates
Infinity Test is a continuous testing library and a flexible alternative to Autotest, using Watchr library with RSpec, Test::Unit or Bacon with RVM funcionality, giving the possibility to test with all Rubies that you have in your RVM configuration.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Development

>= 1.4.0
>= 2.0.1

Runtime

>= 1.1.0
>= 0.7
 Project Readme

Infinity Test

To Infinity and Beyond!

Infinity Test is a continuous testing library and a flexible alternative to Autotest and Guard. It watches your files for changes and automatically runs your tests, providing instant feedback with desktop notifications.

Version 2.0.0 brings a complete rewrite with modern dependencies, multi-Ruby support via RVM/RbEnv, and a powerful callbacks system.

Table of Contents

  • Installation
  • Quick Start
  • Command Line Options
  • Configuration File (INFINITY_TEST)
  • Ruby Version Managers
  • Test Frameworks
  • Application Frameworks
  • Notifications
  • Image Themes
  • Callbacks
  • File Watching
  • Advanced Usage

Installation

Since this is a release candidate (rc1), you need to explicitly request the pre-release version:

gem install infinity_test --pre

Or add to your Gemfile:

gem 'infinity_test', '~> 2.0.0.rc1', group: :development

Then run:

bundle install

Quick Start

Step 1: Navigate to your project

cd /path/to/your/project

Step 2: Run Infinity Test

infinity_test

That's it! Infinity Test will:

  1. Auto-detect your test framework (RSpec or Test::Unit)
  2. Auto-detect your application framework (Rails, Padrino, or Rubygems)
  3. Run all tests immediately
  4. Watch for file changes and re-run relevant tests
  5. Show desktop notifications with test results

Step 3: Start coding

Edit your files and watch the tests run automatically!


Command Line Options

Option Short Description
--ruby strategy Ruby manager strategy: auto_discover, rvm, rbenv, ruby_default
--rubies=versions Ruby versions to test against (comma-separated)
--test library Test framework: auto_discover, rspec, test_unit
--framework library Application framework: auto_discover, rails, rubygems, padrino
--options=options Additional options to pass to test command
--notifications library Notification system: auto_discover, osascript, terminal_notifier, notify_send, dunstify
--mode theme Image theme for notifications (see Image Themes)
--no-infinity-and-beyond -n Run tests once and exit (CI mode)
--just-watch -j Skip initial test run, only watch for changes
--focus [FILE] -f Focus on specific tests or failures for last failed tests
--no-verbose Don't print commands before executing
--no-bundler Bypass Bundler support
--help Show help message

Examples

Run with RSpec only:

infinity_test --test rspec

Run tests on multiple Ruby versions with RVM:

infinity_test --ruby rvm --rubies=3.0.0,3.1.0,3.2.0

Run tests once and exit (for CI):

infinity_test -n

Skip initial test run, just watch:

infinity_test --just-watch

Focus on failed tests:

infinity_test --focus failures

Focus on a specific file:

infinity_test --focus spec/models/user_spec.rb

Use a specific notification theme:

infinity_test --mode mario_bros

Pass additional options to the test runner:

infinity_test --options="-Ilib -Itest"

Configuration File (INFINITY_TEST)

You can persist your settings in an INFINITY_TEST file. Infinity Test looks for configuration in two locations:

  1. Project file: ./INFINITY_TEST (higher priority)
  2. Global file: ~/INFINITY_TEST (lower priority)

Basic Configuration

InfinityTest.setup do |config|
  config.test_framework = :rspec
  config.framework      = :rails
  config.notifications  = :terminal_notifier
  config.mode           = :mario_bros
  config.verbose        = true
end

All Configuration Options

InfinityTest.setup do |config|
  # Ruby Version Manager
  # Options: :auto_discover, :rvm, :rbenv, :ruby_default
  config.strategy = :auto_discover

  # Ruby versions to test against (requires RVM or RbEnv)
  config.rubies = ['3.0.0', '3.1.0', '3.2.0']

  # Gemset to use with RVM
  config.gemset = 'my_project'

  # Test framework
  # Options: :auto_discover, :rspec, :test_unit
  config.test_framework = :rspec

  # Application framework
  # Options: :auto_discover, :rails, :padrino, :rubygems
  config.framework = :rails

  # File observer
  # Options: :listen (event-driven), :filewatcher (polling)
  config.observer = :listen

  # Notification system
  # Options: :auto_discover, :osascript, :terminal_notifier, :notify_send, :dunstify
  config.notifications = :auto_discover

  # Image theme for notifications
  config.mode = :simpson

  # Or use custom images
  config.success_image = '/path/to/success.png'
  config.failure_image = '/path/to/failure.png'
  config.pending_image = '/path/to/pending.png'

  # Bundler support (auto-detected if Gemfile exists)
  config.bundler = true

  # Print commands before executing
  config.verbose = true

  # File extension to watch
  config.extension = :rb

  # Skip initial test run
  config.just_watch = false

  # Run tests and exit (CI mode)
  config.infinity_and_beyond = true

  # Focus mode: nil, :failures, or file path
  config.focus = nil

  # Ignore specific test files
  config.ignore_test_files = [
    'spec/slow/performance_spec.rb'
  ]

  # Ignore test folders
  config.ignore_test_folders = [
    'spec/integration'
  ]
end

Configuration with Callbacks

InfinityTest.setup do |config|
  config.test_framework = :rspec
  config.mode           = :faces
end

# Clear terminal before running tests
InfinityTest::Core::Base.before(:all) do
  InfinityTest::Core::Base.clear_terminal
end

# Run after all tests complete
InfinityTest::Core::Base.after(:all) do
  system('say "Tests finished"')
end

# Run before each Ruby version (when testing multiple rubies)
InfinityTest::Core::Base.before(:each_ruby) do |environment|
  puts "Testing with Ruby #{environment[:ruby_version]}"
end

# Run after each Ruby version
InfinityTest::Core::Base.after(:each_ruby) do |environment|
  puts "Finished testing Ruby #{environment[:ruby_version]}"
end

Ruby Version Managers

Infinity Test supports testing across multiple Ruby versions using RVM or RbEnv.

Auto Discovery (Default)

config.strategy = :auto_discover

Priority order: RVM > RbEnv > RubyDefault

RVM Strategy

Test against multiple Ruby versions with optional gemset support:

InfinityTest.setup do |config|
  config.strategy = :rvm
  config.rubies   = ['3.0.0', '3.1.0', 'jruby-9.4.0.0']
  config.gemset   = 'infinity_test'  # Optional
end

Command line:

infinity_test --ruby rvm --rubies=3.0.0,3.1.0,jruby-9.4.0.0

RbEnv Strategy

Test against multiple Ruby versions using rbenv:

InfinityTest.setup do |config|
  config.strategy = :rbenv
  config.rubies   = ['3.0.0', '3.1.0', '3.2.0']
end

Command line:

infinity_test --ruby rbenv --rubies=3.0.0,3.1.0

Ruby Default Strategy

Use the current Ruby version only (no version manager):

config.strategy = :ruby_default

Test Frameworks

RSpec

Auto-detected when spec/ directory exists with spec_helper.rb or *_spec.rb files.

config.test_framework = :rspec

Test::Unit / Minitest

Auto-detected when test/ directory exists with test_helper.rb or *_test.rb files.

config.test_framework = :test_unit

Application Frameworks

Rails

Auto-detected when config/environment.rb exists.

Watched directories:

  • app/models → runs corresponding model specs/tests
  • app/controllers → runs corresponding controller specs/tests
  • app/helpers → runs corresponding helper specs/tests
  • app/mailers → runs corresponding mailer specs/tests
  • app/jobs → runs corresponding job specs/tests
  • lib/ → runs corresponding lib specs/tests
  • spec/ or test/ → runs the changed spec/test file
  • spec_helper.rb or test_helper.rb → runs all tests

Padrino

Auto-detected when config/boot.rb exists with Padrino reference.

Similar heuristics to Rails with Padrino-specific paths.

Rubygems (Default)

Used for gem development and simple Ruby projects.

Watched directories:

  • lib/ → runs corresponding specs/tests
  • spec/ or test/ → runs the changed spec/test file

Notifications

Desktop notifications show test results with themed images.

Notification Systems

System Platform Description
auto_discover All Automatically detect available notifier
terminal_notifier macOS Modern macOS notifications
osascript macOS Built-in AppleScript notifications
notify_send Linux libnotify notifications
dunstify Linux Dunst notification daemon

Configuration:

config.notifications = :terminal_notifier

Command line:

infinity_test --notifications terminal_notifier

Image Themes

Infinity Test includes fun image themes for notifications. Each theme has three images: success, failure, and pending.

Available Themes

Theme Description Location
simpson The Simpsons characters (default) images/simpson/
faces Expressive face icons images/faces/
fuuu Rage comic faces images/fuuu/
hands Hand gesture icons images/hands/
mario_bros Super Mario characters images/mario_bros/
rails Ruby on Rails themed images/rails/
rubies Ruby gemstone themed images/rubies/
street_fighter Street Fighter characters images/street_fighter/
toy_story Toy Story characters images/toy_story/

Using a Theme

Configuration file:

config.mode = :mario_bros

Command line:

infinity_test --mode mario_bros

Custom Images

Use your own images by setting the image paths directly:

InfinityTest.setup do |config|
  config.success_image = '/path/to/my_success.png'
  config.failure_image = '/path/to/my_failure.png'
  config.pending_image = '/path/to/my_pending.png'
end

Or point to a custom directory containing success.*, failure.*, and pending.* images:

config.mode = '/path/to/my/images/directory'

Callbacks

Callbacks let you run custom code before or after tests.

Available Callbacks

Callback Scope Description
before(:all) All Runs once before all tests
after(:all) All Runs once after all tests
before(:each_ruby) Per Ruby Runs before testing each Ruby version
after(:each_ruby) Per Ruby Runs after testing each Ruby version

Examples

Clear terminal before tests:

InfinityTest::Core::Base.before(:all) do
  InfinityTest::Core::Base.clear_terminal
end

Play a sound after tests:

InfinityTest::Core::Base.after(:all) do
  system('afplay /path/to/sound.mp3')
end

Log Ruby version being tested:

InfinityTest::Core::Base.before(:each_ruby) do |env|
  File.write('test.log', "Testing: #{env[:ruby_version]}\n", mode: 'a')
end

Compile extensions before each Ruby:

InfinityTest::Core::Base.before(:each_ruby) do |env|
  system('rake compile')
end

File Watching

Listen (Default)

Event-driven file watching using native OS notifications. Fast and efficient.

config.observer = :listen

Filewatcher

Polling-based file watching. Works everywhere including VMs and NFS mounts.

config.observer = :filewatcher

Advanced Usage

Continuous Integration Mode

Run tests once and exit with proper exit code:

infinity_test -n

Or in configuration:

config.infinity_and_beyond = false

Just Watch Mode

Skip the initial test run and only watch for changes. Useful for large projects:

infinity_test --just-watch

Focus Mode

Run only specific tests:

# Run only previously failed tests
infinity_test --focus failures

# Run only a specific file
infinity_test --focus spec/models/user_spec.rb

Ignoring Files

InfinityTest.setup do |config|
  # Ignore specific test files
  config.ignore_test_files = [
    'spec/slow/large_integration_spec.rb',
    'spec/external/api_spec.rb'
  ]

  # Ignore entire directories
  config.ignore_test_folders = [
    'spec/integration',
    'spec/system'
  ]
end

Watching Non-Ruby Files

# Watch Python files
config.extension = :py

# Watch JavaScript files
config.extension = :js

Sample Complete Configuration

# INFINITY_TEST

InfinityTest.setup do |config|
  # Multi-Ruby testing with RVM
  config.strategy = :rvm
  config.rubies   = ['3.1.0', '3.2.0', '3.3.0']
  config.gemset   = 'myapp'

  # Test framework and app framework
  config.test_framework = :rspec
  config.framework      = :rails

  # Notifications with Mario theme
  config.notifications = :terminal_notifier
  config.mode          = :mario_bros

  # Performance settings
  config.observer   = :listen
  config.just_watch = false
  config.verbose    = true

  # Ignore slow tests during development
  config.ignore_test_folders = ['spec/system']
end

# Clear screen before each run
InfinityTest::Core::Base.before(:all) do
  InfinityTest::Core::Base.clear_terminal
end

# Notify via system sound when done
InfinityTest::Core::Base.after(:all) do
  system('afplay /System/Library/Sounds/Glass.aiff')
end

Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Run the tests (infinity_test)
  4. Commit your changes (git commit -am 'Add amazing feature')
  5. Push to the branch (git push origin feature/amazing-feature)
  6. Create a Pull Request

License

MIT License - see LICENSE.txt for details.


Author

Tomas D'Stefano

Happy Testing!