Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 在“rake测试”之后执行rake任务`_Ruby On Rails_Ruby_Minitest_Rake Task - Fatal编程技术网

Ruby on rails 在“rake测试”之后执行rake任务`

Ruby on rails 在“rake测试”之后执行rake任务`,ruby-on-rails,ruby,minitest,rake-task,Ruby On Rails,Ruby,Minitest,Rake Task,我正在尝试为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:se

我正在尝试为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:cleanup
test
rake任务完成运行之前被调用。在前面的任务完成后,是否仍可以调用cleanup-rake任务

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

$ 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标准语法调用多个任务:

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:setup
test
在某种程度上取决于
test:cleanup
任务。因此,它的调用比预期的要早。

事实证明,这与rake无关,而与Minitest执行测试的方式有关。我在问题中提到,rake任务似乎是以正确的顺序调用的,但是由于某种原因,测试是在稍后执行的。原因是Minitest使用ruby内核方法
在_exit
执行测试。测试文件在调用
rake测试时被读入,但所有测试都是在ruby程序结束时执行的,即使在我后续的rake任务之后也是如此。这里有一篇博客文章更详细地解释了这个问题:。

谢谢Marcin。我也尝试过这种方法,但是在执行清理任务之后,测试仍然会运行。它们是按顺序调用的,但是第二个任务并不等待第一个任务完成。我真的觉得它与rake的关系不大,更多的是与minitest如何执行测试有关。我在答案中添加了一些其他想法,可能是您的
test:setup
test
已经调用了cleanup(不确定为什么,但可能是您或某个gem添加了一个依赖项来运行
cleanup
),所以这根本不是第二次了。你找到解决办法了吗?
Rake::Task["test"].enhance do
  Rake::Task["test:cleanup"].invoke
end