Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save x-yuri/df5dde8a15ccabc7888c889477301dc7 to your computer and use it in GitHub Desktop.
Save x-yuri/df5dde8a15ccabc7888c889477301dc7 to your computer and use it in GitHub Desktop.
#rails #minitest #rake #spring

Gems from test, but not development group might be unavailable when running tests

a.sh:

#!/bin/sh -eux
apk add build-base sqlite-dev nodejs tzdata
cat <<GEMFILE >Gemfile
source 'https://rubygems.org'
gem 'rails', '~> 4.0'
gem 'nokogiri', '< 1.11.0'
GEMFILE
bundle
rails new app
cd app
sed -Ei "s/gem 'sqlite.*/gem 'sqlite3', '~> 1.3.6'/" Gemfile
cat <<GEMFILE >>Gemfile
group :test do
  gem 'factory_bot', '5.2.0'
end
GEMFILE
bundle
sed -Ei 's/# Add more.*/include FactoryBot::Syntax::Methods/' test/test_helper.rb
bin/rails generate scaffold post title body:text published:boolean
bin/rake db:migrate
"$@"
$ docker run --rm -v $PWD/a.sh:/a.sh ruby:2.4-alpine ./a.sh bin/rake --trace
...
+ bin/rake --trace
Running via Spring preloader in process 12318
** Invoke default (first_time)
** Invoke test (first_time)
** Execute test
** Invoke test:run (first_time)
** Execute test:run
rake aborted!
NameError: uninitialized constant ActiveSupport::TestCase::FactoryBot
/app/test/test_helper.rb:9:in `<class:TestCase>'
/app/test/test_helper.rb:5:in `<top (required)>'
/app/test/controllers/posts_controller_test.rb:1:in `<top (required)>'
/usr/local/bundle/gems/railties-4.2.11.3/lib/rails/test_unit/sub_test_task.rb:114:in `block (3 levels) in define'
/usr/local/bundle/gems/railties-4.2.11.3/lib/rails/test_unit/sub_test_task.rb:114:in `each'
/usr/local/bundle/gems/railties-4.2.11.3/lib/rails/test_unit/sub_test_task.rb:114:in `block (2 levels) in define'
/usr/local/bundle/gems/railties-4.2.11.3/lib/rails/test_unit/sub_test_task.rb:113:in `each'
/usr/local/bundle/gems/railties-4.2.11.3/lib/rails/test_unit/sub_test_task.rb:113:in `block in define'
/usr/local/bundle/gems/rake-13.0.3/lib/rake/task.rb:281:in `block in execute'
/usr/local/bundle/gems/rake-13.0.3/lib/rake/task.rb:281:in `each'
/usr/local/bundle/gems/rake-13.0.3/lib/rake/task.rb:281:in `execute'
/usr/local/bundle/gems/rake-13.0.3/lib/rake/task.rb:219:in `block in invoke_with_call_chain'
/usr/local/lib/ruby/2.4.0/monitor.rb:214:in `mon_synchronize'
/usr/local/bundle/gems/rake-13.0.3/lib/rake/task.rb:199:in `invoke_with_call_chain'
/usr/local/bundle/gems/rake-13.0.3/lib/rake/task.rb:188:in `invoke'
/usr/local/bundle/gems/railties-4.2.11.3/lib/rails/test_unit/sub_test_task.rb:20:in `invoke_rake_task'
/usr/local/bundle/gems/railties-4.2.11.3/lib/rails/test_unit/testing.rake:8:in `block in <top (required)>'
/usr/local/bundle/gems/rake-13.0.3/lib/rake/task.rb:281:in `block in execute'
/usr/local/bundle/gems/rake-13.0.3/lib/rake/task.rb:281:in `each'
/usr/local/bundle/gems/rake-13.0.3/lib/rake/task.rb:281:in `execute'
/usr/local/bundle/gems/rake-13.0.3/lib/rake/task.rb:219:in `block in invoke_with_call_chain'
/usr/local/lib/ruby/2.4.0/monitor.rb:214:in `mon_synchronize'
/usr/local/bundle/gems/rake-13.0.3/lib/rake/task.rb:199:in `invoke_with_call_chain'
/usr/local/bundle/gems/rake-13.0.3/lib/rake/task.rb:243:in `block in invoke_prerequisites'
/usr/local/bundle/gems/rake-13.0.3/lib/rake/task.rb:241:in `each'
/usr/local/bundle/gems/rake-13.0.3/lib/rake/task.rb:241:in `invoke_prerequisites'
/usr/local/bundle/gems/rake-13.0.3/lib/rake/task.rb:218:in `block in invoke_with_call_chain'
/usr/local/lib/ruby/2.4.0/monitor.rb:214:in `mon_synchronize'
/usr/local/bundle/gems/rake-13.0.3/lib/rake/task.rb:199:in `invoke_with_call_chain'
/usr/local/bundle/gems/rake-13.0.3/lib/rake/task.rb:188:in `invoke'
/usr/local/bundle/gems/rake-13.0.3/lib/rake/application.rb:160:in `invoke_task'
/usr/local/bundle/gems/rake-13.0.3/lib/rake/application.rb:116:in `block (2 levels) in top_level'
/usr/local/bundle/gems/rake-13.0.3/lib/rake/application.rb:116:in `each'
/usr/local/bundle/gems/rake-13.0.3/lib/rake/application.rb:116:in `block in top_level'
/usr/local/bundle/gems/rake-13.0.3/lib/rake/application.rb:125:in `run_with_threads'
/usr/local/bundle/gems/rake-13.0.3/lib/rake/application.rb:110:in `top_level'
/usr/local/bundle/gems/rake-13.0.3/lib/rake/application.rb:83:in `block in run'
/usr/local/bundle/gems/rake-13.0.3/lib/rake/application.rb:186:in `standard_exception_handling'
/usr/local/bundle/gems/rake-13.0.3/lib/rake/application.rb:80:in `run'
/app/bin/rake:9:in `<top (required)>'
/usr/local/lib/ruby/site_ruby/2.4.0/rubygems/core_ext/kernel_require.rb:54:in `require'
/usr/local/lib/ruby/site_ruby/2.4.0/rubygems/core_ext/kernel_require.rb:54:in `require'
-e:1:in `<main>'
Tasks: TOP => test:run

The reason is because spring is bad at recognizing when it needs to run tests, and some such commands might run in development environment.

By default spring runs a command in the environment in which it was invoked. But if rake is invoked without arguments, with RAILS_ENV=.../RACK_ENV=..., or with the first argument being test or starting with test:, the target environment is test. bin/rake --trace apparently doesn't meet these conditions.

One can add DISABLE_SPRING=1 or RAILS_ENV=test (as an environment variable or as an argument), but minitest would also take --trace as its argument:

$ docker run --rm -v $PWD/a.sh:/a.sh -e DISABLE_SPRING=1 ruby:2.4-alpine ./a.sh bin/rake --trace
...
+ bin/rake db:migrate
== 20210208233136 CreatePosts: migrating ======================================
-- create_table(:posts)
   -> 0.0004s
== 20210208233136 CreatePosts: migrated (0.0004s) =============================

+ bin/rake --trace
** Invoke default (first_time)
** Invoke test (first_time)
** Execute test
** Invoke test:run (first_time)
** Execute test:run
** Execute default

invalid option: --trace

minitest options:
    -h, --help                       Display this help.
        --no-plugins                 Bypass minitest plugin auto-loading (or set $MT_NO_PLUGINS).
    -s, --seed SEED                  Sets random seed. Also via env. Eg: SEED=n rake
    -v, --verbose                    Verbose. Show progress processing files.
    -n, --name PATTERN               Filter run on /regexp/ or string.
    -e, --exclude PATTERN            Exclude /regexp/ or string from run.

Known extensions: pride
    -p, --pride                      Pride. Show your testing pride!

So to make it work do:

$ docker run --rm -v $PWD/a.sh:/a.sh -e RAKEOPT=--trace ruby:2.4-alpine ./a.sh bin/rake
...
+ bin/rake
Running via Spring preloader in process 12322
** Invoke default (first_time)
** Invoke test (first_time)
** Execute test
** Invoke test:run (first_time)
** Execute test:run
Running via Spring preloader in process 12329
** Invoke db:test:prepare (first_time)
** Invoke environment (first_time)
** Execute environment
** Invoke db:load_config (first_time)
** Execute db:load_config
** Execute db:test:prepare
** Invoke db:test:load (first_time)
** Invoke db:test:purge (first_time)
** Invoke environment 
** Invoke db:load_config 
** Execute db:test:purge
** Execute db:test:load
** Invoke db:test:load_schema (first_time)
** Invoke db:test:purge 
** Execute db:test:load_schema
** Execute default
Run options: --seed 17292

# Running:

.......

Finished in 0.600600s, 11.6550 runs/s, 21.6450 assertions/s.

7 runs, 13 assertions, 0 failures, 0 errors, 0 skips
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment