【问题标题】:Why do test:units and test:functionals insist on running in development environment?为什么 test:units 和 test:functionals 坚持在开发环境中运行?
【发布时间】:2010-11-02 17:25:02
【问题描述】:

我正在尝试测试一些特定于环境的设置(具体来说是中间件,但这似乎并不重要),但我无法让测试在正确的环境中运行。症状:

  • 如果我运行ruby test/unit/my_test.rb,一切都很好,因为它首先需要test/test_helper.rb,它将环境设置为"test",然后加载Rails 环境。
  • 如果我运行rake test,第一批(功能)运行良好,但第二批(单元)失败。失败是ENV['RAILS_ENV] 在批次之间以某种方式未设置,然后config/environment.rb 看到没有设置并使用默认值"development"。环境在config/environment.rb 的开头和该文件中配置块的开头是正确的,但到最后是错误的。我可以通过使用 puts 或删除 config/development.rb 导致它找不到文件来判断。
  • 如果我运行rake test:units,我会遇到与第二批rake test相同的问题(即全部失败)
  • 如果我运行rake test:functionals,我会得到与rake test:units 相同的结果
  • 如果我运行rake test RAILS_ENV=testrake test:units RAILS_ENV=testrake test:functionals RAILS_ENV=test,一切都很好!

我尝试过的一件事根本不起作用:

# in Rakefile:
task :set_test_env { ENV['RAILS_ENV'] = 'test' }
Rake::Task[:test].prerequisites.unshift :set_test_env
# and similarly for other test tasks

我什至尝试为每个测试任务创建一个单独的:set_test_env 任务,以便我确信它会在每个任务之前被调用,而不仅仅是一次。还是没有骰子。它确实被调用了,config/environment.rb 开头的环境是正确的,但里面出了点问题。

我无需在任何地方的代码中设置ENV['RAILS_ENV']

【问题讨论】:

  • 根据您关于 environment.rb 和删除 development.rb 的 cmets,查看您的 environment.rb 文件以及与 development.rb 文件丢失相关的堆栈跟踪或错误消息可能会有所帮助。跨度>
  • 自己做很容易。 (1) 启动一个新的 Rails 应用程序。 (2) 在 config/environtments/development.rb 的末尾添加“raise 'development!'”行。 (3) 从命令行运行“rake tests”(或只是“rake”)。
  • 啊。我想也许你有一个特殊情况,但问题可以在空白应用程序中重现。有趣的谜题。 :) 到目前为止,我能说的最好的是,Rails 系统在测试准备期间已加载,以检查待处理的数据库迁移,如果 ENV['RAILS_ENV'] 尚未设置,则将 RAILS_ENV 设置为 'development' .
  • 不可能完全这么简单。如果是这样,那么我帖子末尾的示例代码 (task :set_test_env { ENV['RAILS_ENV'] = 'test' }; Rake::Task[:test].prerequisites.unshift :set_test_env) 将解决问题,它没有。但我们走在正确的轨道上。
  • 问题是你在 development.rb 中有一些东西会破坏你的测试。找到更适合放置这些东西的地方,您的问题就解决了。将它移动到哪里取决于它到底在做什么,所以我的建议是发布你的 development.rb。

标签: ruby-on-rails ruby testing environment-variables


【解决方案1】:

在 test_helper.rb 文件的顶部我有代码

ENV["RAILS_ENV"] = "test"

如果您没有该行,则系统问题将在默认环境(即开发)中运行。

【讨论】:

  • 不,明白了。它在 Rails 中是默认的。我所有的测试文件都包含该文件。但这绝对是一件好事。
【解决方案2】:

在整个项目中搜索 RAILS_ENV 及其变体。查看您是否在应用程序或测试中的某个位置设置了它。

另外,您在哪个平台上运行?能否在另一台机器上运行测试,看看结果是否一样?

如果这是一个相对较新的开发,并且您正在使用像 Git 或 SVN 这样的 RCS,您应该查看最近的提交,如果您专门使用 Git,您应该查看 git bisect。如果您不使用 RCS,则应该使用。

如果这确实是一个新的应用程序问题,那么它可能是您的环境问题。

您安装/配置了哪些插件和 gem?我们可以看到回溯吗?

【讨论】:

  • 正如我在上面的评论中所说:为自己做很容易。 (1) 启动一个新的 Rails 应用程序。 (2) 在 config/environtments/development.rb 的末尾添加“raise 'development!'”行。 (3) 从命令行运行“rake tests”(或只是“rake”)。所以这不是我的代码的问题。我刚刚重新安装了 Rails 2.3.3 gem 再次尝试。
  • Gaius,不幸的是,您的“简单测试”并不能证明这一点。当 rake 启动时,它会在加载测试助手之前做很多事情。这些任务将在当前活动的环境中完成。默认情况下将是开发,其中一些谓词任务将加载默认环境。如果您在运行 rake 之前使用 export RAILS_ENV=test 在 shell 中设置 RAILS_ENV,那么您的简单案例将无法证明这一点
【解决方案3】:

我实际上根本不相信你有问题。我相信在某个时候你发现你的 rake 任务实际上是在开发环境中,你开始尝试找出为什么会这样。然后,您在开发配置文件中添加了一行来引发异常,这就是您的 rake 测试失败的原因。

如果您删除引发异常的行,那么您可能会发现测试都运行成功。

如果您尝试以下操作,您可能会发现它可以解释问题。

  1. 将环境设置为开发(仅用于跟踪目的)

    导出 RAILS_ENV=development

  2. 人为删除所有行 在您的环境中引发异常 文件。
  3. 将以下行添加到末尾 config/environments 中的每个文件

    puts "**** In #{ENV['RAILS_ENV']} environment config ****"
    
  4. 将以下行添加到 test/test_helper.rb 中,就在将环境设置为测试的行下方。

    puts "**** Loading test helper **** Environment = #{ENV['RAILS_ENV']}"
    
  5. 使用跟踪选项运行 rake 以跟踪当前活动环境的执行情况。

    rake -t test
    
  6. 检查输出以确定您的环境设置不正确。
  7. 再次运行测试,但这次在运行测试之前直接设置环境

    导出 RAILS_ENV=test

如果您确实有问题,那么也许您应该将 rake -t 的输出与跟踪代码一起发布。

这是我在一个全新项目中的测试的输出,并进行了一些最低限度的测试。您会注意到,在运行实际测试之前,环境始终是“测试”

** Invoke test (first_time)
** Execute test
** Invoke test:units (first_time)
** Invoke db:test:prepare (first_time)
** Invoke db:abort_if_pending_migrations (first_time)
** Invoke environment (first_time)
** Execute environment
**** In development environment config ****
** Execute db:abort_if_pending_migrations
** Execute db:test:prepare
** Invoke db:test:load (first_time)
** Invoke db:test:purge (first_time)
** Invoke environment
** Execute db:test:purge
** Execute db:test:load
** Invoke db:schema:load (first_time)
** Invoke environment
** Execute db:schema:load
** Execute test:units
**** Loading test helper **** Environment = test
**** In test environment config ****
Loaded suite /Library/Ruby/Gems/1.8/gems/rake-0.8.3/lib/rake/rake_test_loader
Started
.
Finished in 0.071771 seconds.

1 tests, 1 assertions, 0 failures, 0 errors
** Invoke test:functionals (first_time)
** Invoke db:test:prepare
** Execute test:functionals
**** Loading test helper **** Environment = test
**** In test environment config ****
Loaded suite /Library/Ruby/Gems/1.8/gems/rake-0.8.3/lib/rake/rake_test_loader
Started
.....
Finished in 0.133776 seconds.

5 tests, 6 assertions, 0 failures, 0 errors
** Invoke test:integration (first_time)
** Invoke db:test:prepare
** Execute test:integration

【讨论】:

  • 正如我在问题的第一句话中所说,问题是在我的 actual 应用程序中,我的 development.rb 中有很多初始化,这些初始化在我的测试中都被破坏了.删除我的调试“raise”行会导致各种破坏,因为我试图与实时(开发)系统而不是假版本进行交互。
  • 但是由于在“当前环境”中调用了 rake,因此在 raise 行中总是会失败。因此,一旦它加载当前环境(开发),它就会引发异常。
  • Gaius,问题是你在 development.rb 中有一些东西会破坏你的测试。找到更适合放置这些东西的地方,您的问题就解决了。将它移动到哪里取决于它到底在做什么。
  • @Sarah Mei:这让我感到困惑,为什么我在运行测试时必须担心 development.rb 中的内容。测试应在测试环境中独占运行。
【解决方案4】:

为了给你一个完整的答案,我必须看一下代码,但我会尽量给你一些可能有用的线索。

首先rake test 和所有其他变体(test:unitstest:functionals 等)的工作方式如下

  1. Rake 进程被调用,任务test当前环境(默认为开发环境)中执行,这就是为什么总是读取development.rb
  2. Rake 任务在单独的子进程中调用测试加载器(您可以使用pspstree 验证这一点),这是test_helper.rb 的来源和环境设置的位置进行测试。

当您运行ruby test/unit/my_test.rb 时,第一步被跳过,所以看起来问题出在那儿。也许你在development.rb 中做了一些对子进程有副作用的事情?

【讨论】:

    【解决方案5】:

    我几乎总是想强制我的测试在“测试”环境中运行自己及其先决条件,尤其是当 ENV['RAILS_ENV'] 设置为任何常见默认值时(以避免灾难性事故),但我还希望能够通过在命令行上调用 rake test:units RAILS_ENV=v_2_0_maint_test 在名为“v_2_0_maint_test”或类似的环境上运行测试。

    所以我有一个 test_tasks.rake 文件,它为我感兴趣的每个测试任务添加了一个先决条件。由于这个先决条件是前置的,因此任何其他先决条件(例如 db:test:prepare、db:fixtures:load ) 在相同的环境中运行。这声称只影响您想要影响的测试,它们的先决条件。

    namespace :test do |n|
      [ n[:units], n[:functionals], n[:integration] ].each do |t|
        t.prerequisites.unshift(:set_test_env_dammit)
      end
    
      task :set_test_env_dammit do |t|
        if [ nil, "", "development", "staging", "production" ].index ENV['RAILS_ENV']
          RAILS_ENV = "test"
        end
      end
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-11
      • 1970-01-01
      • 2021-11-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多