admin管理员组文章数量:1277910
Just upgrading a Rails 7.2.2 app to Rails 8.0.1. Before the upgrade, all tests run cleanly. App was upgraded to ruby 3.4.2 just before (and all tests passed with no warnings). After upgrade, this warning is emitted:
/home/<username>/.asdf/installs/ruby/3.4.2/lib/ruby/gems/3.4.0/gems/railties-8.0.1/lib/rails/tasks/statistics.rake:4: warning: already initialized constant STATS_DIRECTORIES Time: 00:00:10, ETA: 00:03:50
/home/<username>/.asdf/installs/ruby/3.4.2/lib/ruby/gems/3.4.0/gems/railties-8.0.1/lib/rails/tasks/statistics.rake:4: warning: previous definition of STATS_DIRECTORIES was here
I have traced the issue to one test suite for a Rake Task that is run regularly in production by Heroku Scheduler.
The test looks like:
require "test_helper"
class TimedEmailsTaskTest < ActionDispatch::IntegrationTest
setup do
Rails.application.load_tasks
@my_object = create(:object)
end
teardown do
ActionMailer::Base.deliveries.clear
Rake::Task["my_regular_emails_task"].reenable
end
... 4 tests that assert things using Rake::Task["my_regular_emails_task"].invoke ...
end
The offending line is Rails.application.load_tasks
, which I tracked down with the help of this github issue. Originally the warning was emitted once for each test in this suite; I can get it down to once by using:
Rails.application.load_tasks unless defined?(Rake::Task) && Rake::Task.tasks.any?
With the help of some good old puts debugging, I have tracked the initial "hit" on statistics.rake:4
to my Rakefile (in the app root directory), which is the standard default file:
require_relative "config/application"
Rails.application.load_tasks
So, the Rakefile runs, sets the constant STATS_DIRECTORIES, but the tasks aren't available in tests without running Rails.application.load_tasks
again, which emits the warning. Interestingly, If I just run the single test file, the Rakefile doesn't run and warning isn't emitted; it only happens when running multiple tests (e.g. rails test
or rails test:integration
).
I have spent a few hours with this, including trying to move statements to test_helper.rb with no meaningful change in the outcome. I'm also unhappy with the possibility of creating flaky tests that either emit a warning when running the suite and pass silently when running the one file, or fail when running the one file and pass (with warning) when running the full suite. I'm somewhat confused about how Rakefile
works and when it runs, and confused why this wasn't an issue on Rails 7. Is there an insight I'm missing? Is there an obvious misconfiguration here or more idiomatic approach that would solve this?
PS: This same railties line was emitting warnings for people back on Rails 4, but that question was never resolved so isn't much help.
Just upgrading a Rails 7.2.2 app to Rails 8.0.1. Before the upgrade, all tests run cleanly. App was upgraded to ruby 3.4.2 just before (and all tests passed with no warnings). After upgrade, this warning is emitted:
/home/<username>/.asdf/installs/ruby/3.4.2/lib/ruby/gems/3.4.0/gems/railties-8.0.1/lib/rails/tasks/statistics.rake:4: warning: already initialized constant STATS_DIRECTORIES Time: 00:00:10, ETA: 00:03:50
/home/<username>/.asdf/installs/ruby/3.4.2/lib/ruby/gems/3.4.0/gems/railties-8.0.1/lib/rails/tasks/statistics.rake:4: warning: previous definition of STATS_DIRECTORIES was here
I have traced the issue to one test suite for a Rake Task that is run regularly in production by Heroku Scheduler.
The test looks like:
require "test_helper"
class TimedEmailsTaskTest < ActionDispatch::IntegrationTest
setup do
Rails.application.load_tasks
@my_object = create(:object)
end
teardown do
ActionMailer::Base.deliveries.clear
Rake::Task["my_regular_emails_task"].reenable
end
... 4 tests that assert things using Rake::Task["my_regular_emails_task"].invoke ...
end
The offending line is Rails.application.load_tasks
, which I tracked down with the help of this github issue. Originally the warning was emitted once for each test in this suite; I can get it down to once by using:
Rails.application.load_tasks unless defined?(Rake::Task) && Rake::Task.tasks.any?
With the help of some good old puts debugging, I have tracked the initial "hit" on statistics.rake:4
to my Rakefile (in the app root directory), which is the standard default file:
require_relative "config/application"
Rails.application.load_tasks
So, the Rakefile runs, sets the constant STATS_DIRECTORIES, but the tasks aren't available in tests without running Rails.application.load_tasks
again, which emits the warning. Interestingly, If I just run the single test file, the Rakefile doesn't run and warning isn't emitted; it only happens when running multiple tests (e.g. rails test
or rails test:integration
).
I have spent a few hours with this, including trying to move statements to test_helper.rb with no meaningful change in the outcome. I'm also unhappy with the possibility of creating flaky tests that either emit a warning when running the suite and pass silently when running the one file, or fail when running the one file and pass (with warning) when running the full suite. I'm somewhat confused about how Rakefile
works and when it runs, and confused why this wasn't an issue on Rails 7. Is there an insight I'm missing? Is there an obvious misconfiguration here or more idiomatic approach that would solve this?
PS: This same railties line was emitting warnings for people back on Rails 4, but that question was never resolved so isn't much help.
Share Improve this question edited Feb 24 at 1:53 NGobin asked Feb 24 at 1:46 NGobinNGobin 4034 silver badges17 bronze badges 2 |1 Answer
Reset to default 0I've gotten around this for now by implementing the guidance on this reddit thread. Basically, I refactored all the logic from the task into a service object, and then the Rake task becomes a single line call that I leave untested. It's probably a better architectural solution, but my OCD doesn't like leaving the task untested, even if it's just a single line, because it's production critical. Oh well.
It still doesn't really answer when/why/how the rakefile runs when running the test suite, but not a single file of tests, why the rake tasks loaded in the rakefile don't persist and need to be re-loaded (but apparently constant definitions do persist), how to load a task in tests without incurring this warning, and why this popped up in Rails 8.0 but was silent in Rails 7.
Anyways, I'll leave this answer as not accepted for a good long time in case someone else has insight on the core questions.
本文标签:
版权声明:本文标题:ruby - Rails 8.0.1 upgrade, railties-8.0.1 gives warning: already initialized constant STATS_DIRECTORIES - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741297372a2370894.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
Rails.application.load_tasks
from your test? Is the test still passing? – Greg Commented Feb 25 at 5:48Rails.application.load_tasks
from the test causes the test to fail, and without itRake::Task.tasks.any?
in the test suite returns False. Commenting the load_tasks line in the Rakefile causes the warning not to be emitted (because it only runs once). It seems like the Rakefile runs and loads the tasks, but then they're cleared before the test suite starts (puts Rake::Task.tasks.any?
in the Rakefile returns True). – NGobin Commented Feb 26 at 20:48