防止 Rails 测试删除种子数据
我正在使用 seeds.rb 来填充一些状态模型参考数据:
State.create :name => 'Alabama', :abbreviation => 'AL'
State.create :name => 'Alaska', :abbreviation => 'AK'
# ...
虽然我没有使用状态装置(因为它一开始就是种子数据,我认为纯粹为了测试而复制它并不干燥),Rails测试框架似乎在测试期间删除了所有状态种子数据。 (我正在删除、重新创建、迁移和重新播种测试数据库,并在单元测试运行之前确认数据存在。)
结果是此断言在 seeds.rb 中成功,但在单行测试中失败:
assert_equal 51, State.all.size
1) Failure:
test_state_seeds_are_present(StateTest) [/test/unit/state_test.rb:24]:
<51> expected but was
<0>.
1 tests, 1 assertions, 1 failures, 0 errors
我尝试过两者都在基测试类固定装置语句中显式列出非状态模型,以及翻转事务固定装置标志(如预期的那样,这仅影响测试期间创建的记录)。当然,正在考虑的测试本身并不是删除这些记录。
状态记录始终被删除。有没有办法告诉 Rails 不再处理种子数据?我是否需要复制灯具中的所有数据以确保重新加载?如果没有重大政治事件,我预计国家数据将相对稳定。
蒂亚
I am using seeds.rb to populate some State model reference data:
State.create :name => 'Alabama', :abbreviation => 'AL'
State.create :name => 'Alaska', :abbreviation => 'AK'
# ...
Although I am not using state fixtures (since it's seed data to begin with, I think it wouldn't be DRY to have to duplicate this purely for tests), the Rails testing framework seems to delete all the State seed data during testing. (I am dropping, recreating, migrating and reseeding the test db, and confirmed the data is there prior to a unit test running.)
The result is this assertion succeeding in seeds.rb but failing in a one-line test:
assert_equal 51, State.all.size
1) Failure:
test_state_seeds_are_present(StateTest) [/test/unit/state_test.rb:24]:
<51> expected but was
<0>.
1 tests, 1 assertions, 1 failures, 0 errors
I have tried both explicitly listing non-State models in the base test class fixtures statement, as well as flipping the transactional fixtures flag (as expected, this only affects records created during the test). Naturally the test under consideration is not itself deleting these records.
The State records are always deleted. Is there a way to tell Rails to just get its hands off the seed data? Do I need to duplicate all the data in fixtures to make sure it gets re-loaded? Short of a major political event, I would expect the state data to be relatively stable.
tia
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
测试从数据库中删除所有数据,然后加载您的灯具(如果有)。
您需要让测试助手在测试运行之前加载种子文件。有几种方法可以做到这一点,请查看我的类似问题: 如何自动将 db:seed 数据加载到测试数据库中?
最简单的方法可能就是在
添加
require "#{Rails.root}/db/seeds.rb"
顶部 test_helper.rb 文件的(假设您使用内置测试框架)。
Tests delete all the data from the database and then load your fixtures (if you have any).
You need to get your test helper to load the seed file before the tests run. There are a couple ways to do that, check out my similar question: How to load db:seed data into test database automatically?
The easiest way is probably just to add
require "#{Rails.root}/db/seeds.rb"
to the top of your test_helper.rb file (assuming you use the built-in testing framework).
“种子”功能未集成到测试架构中。测试是围绕固定装置构建的,每次运行测试套件时,Rails 都会从固定装置加载数据并替换现有内容。
然而,用种子数据填充数据库非常简单。
在 test_helper.rb 文件中,在
ActionSupport::TestCase
基类中添加一个新的设置方法。The "seed" feature is not integrated into the test architecture. Tests are built around fixtures and each time you run the test suite, Rails loads the data from the fixtures and replaces the existing content.
However, having the database populated with your seed data is really straightforward.
In your test_helper.rb file add a new setup method in the base
ActionSupport::TestCase
class.我同意 weppos 关于执行此操作的最佳方法的观点,但是为了完整性以及为了可能已经拥有夹具文件的人,您可以采用其他方法并从现有夹具中为数据库播种。
这是通过在 db/seeds.rb 文件中执行类似以下操作来完成的。
您也可以读取 Fixures 目录并创建要处理的文件名数组,我选择上述过程是因为我希望能够指定我的哪个过程我希望为 DB 提供许多现有的赛程。
I agree with weppos as to the best way to do this, however for the sake of completeness and for the sake of people who may already have fixture files you can take the other approach and seed your database from the existing fixtures.
This is accomplished by doing something like the following in the db/seeds.rb file
You could alternatively read the fixures directory and create an array of file names to process, I chose the above process as I wished to be able to specify which of my many existing fixtures I wished to seed the DB with.
我首先质疑是否需要编写这样的测试。您是在测试种子数据提取任务是否正常工作,还是想测试 State 类实现的行为?我假设是后者,所以我会编写专注于行为的测试并使用 Factory Girl (或类似的),因为你提到你没有使用固定装置。确保从
test/test_helper.rb
中删除fixtures :all
行。要将任务注入到运行测试的正常流程中,这是一种一直对我有用的方法:
只需将其放入名为
lib/tasks/testing.rake
的文件中,它就会被拾取当您下次运行rake test
或其他与测试相关的任务时。I question the need to write a test like that in the first place. Are you testing that the seed data rake task works properly or do you want to test the behavior of your implementation of the State class? I'm assuming the latter, so I would write tests that focus on the behavior and use Factory Girl (or similar) since you mention that you're not using fixtures. Make sure to remove the
fixtures :all
line fromtest/test_helper.rb
.To inject a task into the normal flow of running tests, this is an approach that has always worked for me:
Just put that in a file called
lib/tasks/testing.rake
and it will get picked up when you next runrake test
or other test-related task.我遇到了同样的问题,但标准答案对我不起作用。
我的问题涉及类文件中对常量和named_scopes进行数据库查找的位置。我找不到任何方法可以在正确的时间加载种子数据。
我确实找到了一种绕过删除的方法,即使我已经删除了丢失表的固定文件,这种情况仍然发生。
RAILS_ENV=测试耙数据库:种子
ruby -Itest 测试/单位/*.rb
I had the same problem, but the standard answer didn't work for me.
My problem involved places in the class files which did a database lookup for constants and named_scopes. I could not find any way to have the seed data loaded at the right time.
I did find a way to by-pass the delete, which was happening even though I had deleted my fixture file for the missing table.
RAILS_ENV=test rake db:seed
ruby -Itest test/units/*.rb
默认情况下,您无法同时应用
seed
和fixtures
来设置同一表
的数据。例如。如果您设置名为
products.yml
的装置,它将在创建装置
期间“从产品中删除数据”。您可以:
种子
的舞台移至灯具
后面(手动加载种子);像这样:
>
这在某些遗留情况下会有所帮助,但弄乱
种子
和固定装置
可能会带来新问题。You can't apply both
seed
andfixtures
to setup a sametable
's data by default.eg. If you set up a fixtures named
products.yml
, it will "delete data from products" during creatingfixtures
.You can:
seed
's stage behind thefixtures
s(load seed manually);test_helper.rb
like this:
>
This would help in some legacy case, but messing
seeds
andfixtures
up may brings new problems.