如何为Ruby ActiveRecord测试套件执行数据库迁移?
解决ActiveRecord测试中"Could not find table 'users'"的问题
问题重现
你在使用ActiveRecord+SQLite的Ruby应用编写测试时遇到了如下错误:
Failure/Error: user = described_class.create(name: name) ActiveRecord::StatementInvalid: Could not find table 'users'
你的Gemfile内容:
source "https://rubygems.org" gem "sinatra-activerecord" gem "sqlite3" group :test do gem 'database_cleaner' end group :test, :development do gem "rspec-rails", ">= 2.1.0" gem "pry" end
spec_helper配置:
RSpec.configure do |config| ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: 'db/test.db') end
解决方案步骤
1. 确认迁移文件存在且正确
首先得确保你有创建users表的迁移文件:
- 检查
db/migrate目录下,有没有类似20240520123456_create_users.rb的文件(前缀是时间戳) - 如果没有,运行这个命令生成迁移:
rake db:create_migration NAME=create_users - 打开生成的迁移文件,写入创建users表的代码:
class CreateUsers < ActiveRecord::Migration[6.1] def change create_table :users do |t| t.string :name t.timestamps end end end
2. 完善spec_helper的测试环境配置
修改你的spec_helper.rb,加上迁移执行和DatabaseCleaner的完整配置,确保测试前数据库结构正确:
require 'sinatra/activerecord' require 'sinatra/activerecord/rake' require 'database_cleaner' RSpec.configure do |config| # 建立测试数据库连接 ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: 'db/test.db') # 在整个测试套件运行前执行一次迁移,确保表结构最新 config.before(:suite) do ActiveRecord::Migration.maintain_test_schema! # 如果上面的命令不生效,也可以手动调用迁移任务: # Rake::Task['db:migrate'].invoke end # 配置DatabaseCleaner,每次测试后清理数据 config.before(:each) do DatabaseCleaner.strategy = :transaction DatabaseCleaner.start end config.after(:each) do DatabaseCleaner.clean end end
3. 手动运行测试环境的迁移
在终端里执行以下命令,确保测试数据库创建并完成迁移:
# 先确保db目录存在 mkdir -p db # 运行测试环境的迁移 rake db:migrate RACK_ENV=test
注:SQLite的数据库文件会自动创建,但迁移命令会帮你生成对应的表结构。
4. 验证表是否存在
如果还是有问题,可以用Pry调试确认:
- 在你的测试代码里加一行
binding.pry - 运行测试,进入Pry会话后执行:
User.table_exists? # 应该返回true ActiveRecord::Base.connection.tables # 应该能看到'users'在列表里
内容的提问来源于stack exchange,提问作者Kayla Fitzgerald
相关产品推荐
相关产品推荐

