繁体   English   中英

在'rake test`之后执行rake任务

[英]Executing a rake task after `rake test`

我正在尝试为Rails 4.0.2(Ruby 2.2.3)项目创建一个rake任务,该项目创建测试数据库以及种子,然后运行测试套件,最后通过删除测试数据库进行清理。 这是一个简单的例子如下:

task better_test: :environment do
  Rake::Task["test:setup"].execute
  Rake::Task["test"].execute
  Rake::Task["test:cleanup"].execute
end

上面的任务确实调用了test:setup rake任务(创建/播种测试数据库),然后调用test rake任务,最后调用test:cleanup rake任务。 但问题是最后一次test:cleanuptest rake任务完成运行之前调用test:cleanup 无论如何在上一个任务完成后调用清理rake任务?

以下是使用trace运行任务的输出:

$ RAILS_ENV=test be rake better_test --trace
/usr/local/rvm/gems/ruby-2.2.3/gems/activesupport-4.0.2/lib/active_support/values/time_zone.rb:282: warning: circular argument reference - now
/usr/local/rvm/gems/ruby-2.2.3/gems/honeybadger-1.16.3/lib/honeybadger/rack/user_feedback.rb:51: warning: circular argument reference - action
** Invoke better_test (first_time)
** Invoke environment (first_time)
** Execute environment
** Execute better_test
** Execute test:setup
Creating test database.
** Execute db:test:setup
** Execute db:test:create
** Execute db:create
** Execute db:test:load
** Execute db:schema:load
** Execute db:test_project:setup
** Execute db:test_project:create
** Invoke db:create (first_time)
** Invoke environment
** Execute db:create
** Execute db:test_project:migrate:down
** Execute db:test_project:migrate:up
** Execute db:test_project:seed
** Execute test
** Invoke test:run (first_time)
** Invoke test:units (first_time)
** Invoke test:prepare (first_time)
** Invoke db:test:prepare (first_time)
** Invoke db:abort_if_pending_migrations (first_time)
** Invoke environment
** Invoke db:migrate:load (first_time)
** Invoke environment
** Execute db:migrate:load
** Execute db:abort_if_pending_migrations
** Execute db:test:prepare
** Execute db:drop
** Execute db:create
** Execute db:load
** Invoke db:schema:load (first_time)
** Invoke environment
** Execute db:schema:load
** Execute test:prepare
** Execute test:units
** Invoke test:functionals (first_time)
** Invoke test:prepare
** Execute test:functionals
** Invoke test:integration (first_time)
** Invoke test:prepare
** Execute test:integration
** Execute test:run
** Invoke test:decorators (first_time)
** Invoke test:prepare
** Execute test:decorators
** Execute test:cleanup
** Execute db:test:drop
** Execute db:drop
** Execute db:test_project:drop
** Invoke db:drop (first_time)
** Invoke environment
** Execute db:drop
Run options: --seed 19360

# Running tests:

EE....

Finished tests in 0.037493s, 160.0278 tests/s, 106.6852 assertions/s.

如您所见,按顺序调用任务,但在测试完成之前执行清理任务。 有什么想法解决这个问题?

事实证明,这与rake关系不大,而与Minitest执行测试的方式有关。 我在问题中提到,似乎rake任务以正确的顺序被调用,但测试由于某种原因后来执行。 原因是Minitest利用ruby Kernel方法at_exit来执行测试。 在调用rake test时读入测试文件,但所有测试都在ruby程序结束时执行,即使在我后续的rake任务之后也是如此。 这是一篇博客文章,更详细地解释了这个问题: http//blog.arkency.com/2013/06/are-we-abusing-at-exit/

尝试使用rake标准语法来调用多个任务:

task better_test: ["test:setup", "test", "test:cleanup"]

也许这会解决你的问题。

此外,似乎Rake实际上构建了在执行它们之前应该运行的所有任务的列表,并且只运行一次。 例如:

task :a
task :b
task :c

task better_test: ["a", "b", "c", "b"]

结果是:

$ rake better_test -t
** Invoke better_test (first_time)
** Invoke a (first_time)
** Execute a
** Invoke b (first_time)
** Execute b
** Invoke c (first_time)
** Execute c
** Execute better_test

如您所见,任务b仅运行一次(第一个)。 我相信你的test:setuptest以某种方式取决于test:cleanup任务。 所以它比预期的要早。

Rake::Task["test"].enhance do
  Rake::Task["test:cleanup"].invoke
end

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM