Testing Configuration
This guide explains how to configure React on Rails for optimal testing with RSpec, Minitest, or other test frameworks.
Quick Start
For most applications, the simplest approach is to let Shakapacker handle asset compilation automatically:
# config/shakapacker.yml
test:
compile: true
public_output_path: webpack/testThat's it! Shakapacker will automatically compile assets before running tests.
Two Approaches to Test Asset Compilation
React on Rails supports two mutually exclusive approaches for compiling webpack assets during tests:
Approach 1: Shakapacker Auto-Compilation (Recommended)
Best for: Most applications, especially simpler test setups
Configuration:
# config/shakapacker.yml
test:
<<: *default
compile: true
public_output_path: webpack/testNote: Ensure that
source_pathis correctly configured in yourconfig/shakapacker.yml, or Shakapacker won't correctly detect source changes. This is only necessary if you're not using Shakapacker's defaults.
How it works:
- Shakapacker automatically compiles assets when they're requested
- No additional configuration in React on Rails or test helpers needed
- Assets are compiled on-demand during test runs
Pros:
- ✅ Simplest configuration
- ✅ No extra setup in spec helpers
- ✅ Automatically integrates with Rails test environment
- ✅ Works with any test framework (RSpec, Minitest, etc.)
Cons:
- ⚠️ May compile assets multiple times during test runs
- ⚠️ Less explicit control over when compilation happens
- ⚠️ Can slow down tests if assets change frequently
When to use:
- You want the simplest possible configuration
- Your test suite is relatively fast
- You don't mind automatic compilation on-demand
Approach 2: React on Rails Test Helper (Explicit Control)
Best for: Applications needing precise control over compilation timing
Configuration:
Set your build command:
# config/initializers/react_on_rails.rb
ReactOnRails.configure do |config|
config.build_test_command = "NODE_ENV=test RAILS_ENV=test bin/shakapacker"
# Or use your project's package manager with a custom script:
# config.build_test_command = "pnpm run build:test" # or: npm run build:test, yarn run build:test
endThen configure your test framework:
RSpec:
# spec/rails_helper.rb
require "react_on_rails/test_helper"
RSpec.configure do |config|
# Ensures webpack assets are compiled before the test suite runs
ReactOnRails::TestHelper.configure_rspec_to_compile_assets(config)
endSee lib/react_on_rails/test_helper.rb for more details and customization options.
By default, the helper triggers compilation for examples tagged with :js, :server_rendering, or :controller. You can pass custom metatags as an optional second parameter if you need compilation for other specs — for example, if you use Webpack to build CSS assets for request and feature specs:
# spec/rails_helper.rb
RSpec.configure do |config|
ReactOnRails::TestHelper.configure_rspec_to_compile_assets(config, :requires_webpack_assets)
config.define_derived_metadata(file_path: %r{spec/(features|requests)}) do |metadata|
metadata[:requires_webpack_assets] = true
end
endMinitest:
# test/test_helper.rb
require "react_on_rails/test_helper"
class ActiveSupport::TestCase
setup do
ReactOnRails::TestHelper.ensure_assets_compiled
end
endAlternatively, you can use a Minitest plugin to run the check in before_setup:
module MyMinitestPlugin
def before_setup
super
ReactOnRails::TestHelper.ensure_assets_compiled
end
end
class Minitest::Test
include MyMinitestPlugin
endAsset detection settings:
The following settings in config/initializers/react_on_rails.rb control how the test helper detects stale assets:
ReactOnRails.configure do |config|
# Define the files to check for Webpack compilation when running tests.
config.webpack_generated_files = %w( manifest.json )
# If you're not hashing the server bundle, include it in the list:
# config.webpack_generated_files = %w( server-bundle.js manifest.json )
endImportant: The
build_test_commandmust not include the--watchoption. If you have separate server and client bundles, the command must build all of them.
How it works:
- Compiles assets at most once per test run, and only when they're out of date (stale)
- The helper checks the Webpack-generated files folder (configured via
public_root_pathandpublic_output_pathinconfig/shakapacker.yml). If the folder is missing, empty, or contains files listed inwebpack_generated_fileswithmtimes older than any source files, assets are recompiled. - Uses the
build_test_commandconfiguration - Fails fast if compilation has errors
Pros:
- ✅ Explicit control over compilation timing
- ✅ Assets compiled only once per test run
- ✅ Clear error messages if compilation fails
- ✅ Can customize the build command
Cons:
- ⚠️ Requires additional configuration in test helpers
- ⚠️ More setup to maintain
- ⚠️ Requires
build_test_commandto be set
When to use:
- You want to compile assets exactly once before tests
- You need to customize the build command
- You want explicit error handling for compilation failures
- Your test suite is slow and you want to optimize compilation
Don't Mix Approaches
Do not use both approaches together. They are mutually exclusive:
# config/shakapacker.yml
test:
compile: true # ← Don't do this...# config/initializers/react_on_rails.rb
config.build_test_command = "RAILS_ENV=test bin/shakapacker" # ← ...with this
# spec/rails_helper.rb
ReactOnRails::TestHelper.configure_rspec_to_compile_assets(config) # ← ...and thisThis will cause assets to be compiled multiple times unnecessarily.
Migrating Between Approaches
From React on Rails Test Helper → Shakapacker Auto-Compilation
-
Set
compile: trueinconfig/shakapacker.ymltest section:test: compile: true public_output_path: webpack/test -
Remove test helper configuration from spec/test helpers:
# spec/rails_helper.rb - REMOVE these lines: require "react_on_rails/test_helper" ReactOnRails::TestHelper.configure_rspec_to_compile_assets(config) -
Remove or comment out
build_test_commandin React on Rails config:# config/initializers/react_on_rails.rb # config.build_test_command = "RAILS_ENV=test bin/shakapacker" # ← Comment out
From Shakapacker Auto-Compilation → React on Rails Test Helper
-
Set
compile: falseinconfig/shakapacker.ymltest section:test: compile: false public_output_path: webpack/test -
Add
build_test_commandto React on Rails config:# config/initializers/react_on_rails.rb config.build_test_command = "RAILS_ENV=test bin/shakapacker" -
Add test helper configuration:
# spec/rails_helper.rb (for RSpec) require "react_on_rails/test_helper" RSpec.configure do |config| ReactOnRails::TestHelper.configure_rspec_to_compile_assets(config) end
Verifying Your Configuration
Use the React on Rails doctor command to verify your test configuration:
bundle exec rake react_on_rails:doctorThe doctor will check:
- Whether
compile: trueis set in shakapacker.yml - Whether
build_test_commandis configured - Whether test helpers are properly set up
- Whether you're accidentally using both approaches
Troubleshooting
Assets not compiling during tests
Problem: Tests fail because JavaScript/CSS assets are not compiled.
Solution: Check which approach you're using:
-
If using Shakapacker auto-compilation:
# config/shakapacker.yml test: compile: true # ← Make sure this is true -
If using React on Rails test helper:
- Verify
build_test_commandis set - Check that test helper is configured in spec/test helper
- Run
bundle exec rake react_on_rails:doctor
- Verify
Assets compiling multiple times
Problem: Tests are slow because assets compile repeatedly.
Solutions:
-
If using Shakapacker auto-compilation:
- Switch to React on Rails test helper for one-time compilation
- Or ensure
cache_manifest: truein shakapacker.yml
-
If using React on Rails test helper:
- This shouldn't happen - assets should compile only once
- Check that you don't also have
compile: truein shakapacker.yml
Stale assets not recompiling
Problem: You added a source file but the test helper doesn't trigger recompilation.
Cause: The test helper compares mtimes of source files against generated output files. If you add a source file that has an older timestamp than the existing output (e.g., copied from another directory or restored from version control), it won't be detected as a change.
Solution: Clear out your Webpack-generated files directory to force recompilation:
rm -rf public/webpack/testBuild command fails
Problem: build_test_command fails with errors.
Check:
-
Does
bin/shakapackerexist and is it executable?ls -la bin/shakapacker chmod +x bin/shakapacker # If needed -
Can you run the command manually?
RAILS_ENV=test bin/shakapacker -
Are your webpack configs valid for test environment?
Test helper not found
Problem: LoadError: cannot load such file -- react_on_rails/test_helper
Solution: Make sure react_on_rails gem is available in test environment:
# Gemfile
gem "react_on_rails", ">= 16.0" # Not in a specific group
# Or explicitly in test group:
group :test do
gem "react_on_rails"
endPerformance Considerations
Asset Compilation Speed
Shakapacker auto-compilation:
- Compiles on first request per test process
- May compile multiple times in parallel test environments
- Good for: Small test suites, simple webpack configs
React on Rails test helper:
- Compiles once before entire test suite
- Blocks test start until compilation complete
- Good for: Large test suites, complex webpack configs
Faster Development with Watch Mode
If you're using the React on Rails test helper and want to avoid waiting for compilation on each test run, run your build command with the --watch flag in a separate terminal:
RAILS_ENV=test bin/shakapacker --watch
# Or with your package manager:
# pnpm run build:test --watch
# npm run build:test -- --watch
# yarn run build:test --watchThis keeps webpack running and recompiling automatically when files change, so your tests start faster.
Note: The
--watchflag should only be used in a separate terminal process — never include it inbuild_test_command, which must exit after compilation.
Caching Strategies
Improve compilation speed with caching:
# config/shakapacker.yml
test:
cache_manifest: true # Cache manifest between runsParallel Testing
When running tests in parallel (with parallel_tests gem):
Shakapacker auto-compilation:
- Each process compiles independently (may be slow)
- Consider precompiling assets before running parallel tests:
RAILS_ENV=test bin/shakapacker bundle exec rake parallel:spec
React on Rails test helper:
- Compiles once before forking processes (efficient)
- Works well out of the box with parallel testing
CI/CD Considerations
GitHub Actions / GitLab CI
Option 1: Precompile before tests
- name: Compile test assets
run: RAILS_ENV=test bundle exec rake react_on_rails:assets:compile_environment
- name: Run tests
run: bundle exec rspecOption 2: Use Shakapacker auto-compilation
# config/shakapacker.yml
test:
compile: true
# CI workflow
- name: Run tests (assets auto-compile)
run: bundle exec rspecDocker
When running tests in Docker, consider:
- Caching
node_modulesbetween builds - Precompiling assets in Docker build stage
- Using bind mounts for local development
Best Practices
- Choose one approach - Don't mix Shakapacker auto-compilation with React on Rails test helper
- Use doctor command - Run
rake react_on_rails:doctorto verify configuration - Precompile in CI - Consider precompiling assets before running tests in CI
- Cache node_modules - Speed up installation with caching
- Monitor compile times - If tests are slow, check asset compilation timing
Summary Decision Matrix
| Scenario | Recommendation |
|---|---|
| Simple test setup | Shakapacker compile: true |
| Large test suite | React on Rails test helper |
| Parallel testing | React on Rails test helper or precompile |
| CI/CD pipeline | Precompile before tests |
| Quick local tests | Shakapacker compile: true |
| Custom build command | React on Rails test helper |
Related Documentation
Need Help?
- Forum: ShakaCode Forum
- Docs: React on Rails Guides
- Support: [email protected]