使用PostgreSQL数据库测试应用程序时遇到问题。在当前的设置中,我们将PostgreSQL用于生产环境,将SQLite3用于开发和测试环境。因为这可能导致意外行为,所以开发和测试环境需要切换到PostgreSQL。
切换测试环境是最困难的部分。在运行一个规格文件时,某些测试可以正常运行,但是在使用Guard一起运行所有测试时,则失败。在我的开发中手动运行测试时,其行为符合预期。
这是个例子。失败的测试是我切换到第二个用户并测试@items是否可以包含任何内容的最后一个测试。它返回一个空数组。
# /spec/controllers/materials_controller_spec.rb
describe MaterialsController do
def create_users
@user_1 = FactoryBot.create(:user)
@user_2 = FactoryBot.create(:user)
@admin = FactoryBot.create(:super_admin)
@private_group = Group.find_or_create_by(name: "Private")
@shared_group = Group.find_or_create_by(name: "Shared")
@project_group = Group.find_or_create_by(name: "Project")
@project = FactoryBot.create(:project)
@user_1.projects << @project
@user_2.projects << @project
sign_in @user_1
end
def create_my_private_material
@my_private_material = FactoryBot.create(:material, user: @user_1, group: @private_group, name: "Test01")
end
def create_my_private_material_2
@my_private_material_2 = FactoryBot.create(:material, user: @user_1, group: @private_group)
end
def create_your_private_material
@your_private_material = FactoryBot.create(:material, user: @user_2, group: @private_group)
end
def create_my_project_material
@my_project_material = FactoryBot.create(:material, user: @user_1, group: @project_group, project: @project)
end
def create_your_shared_material
@your_shared_material = FactoryBot.create(:material, user: @user_2, group: @shared_group)
end
def create_all_materials
create_my_private_material
create_my_private_material_2
create_your_private_material
create_my_project_material
create_your_shared_material
end
describe "GET #index" do
before do
create_users
create_all_materials
end
context "as material owner" do
it "renders the index template" do
get :index
expect(assigns(:items)).to contain_exactly(@my_project_material, @my_private_material_2, @my_private_material)
expect(response).to render_template("index")
end
end
context "as being the owner and a current project set using the project scope" do
before do
@user_1.current_project_id = @project.id
@user_1.save
end
it "should assing only the the materials the belong to the current project" do
get :index, params: { scope: 'project' }
expect(assigns(:items)).to contain_exactly(@my_project_material)
end
end
context "as not being the material owner and no default project" do
before do
sign_out @user_1
sign_in @user_2
end
it "filters out the materials based on group and project" do
get :index
expect(assigns(:items)).to contain_exactly(@your_private_material, @your_shared_material)
end
end
context "as not being the owner, with a current project and using the project scope" do
before do
@user_2.current_project_id = @project.id
@user_2.save
sign_out @user_1
sign_in @user_2
end
it "should assign only the materials the belong to the project" do
get :index, params: { scope: 'project', project_id: @project.id }
expect(assigns(:items)).to contain_exactly(@my_project_material)
end
end
end
我已经进行了一些调试,发现了两件事:
DatabaseCleaner.clean_with :truncation
时似乎可以修复某些测试。1
确实适用于控制器测试,但是在我的功能测试中却是一个问题,因为它似乎至少需要连接。因此,问题似乎与PostgreSQL数据库能够处理多个请求的优势有关。但是我不了解运行一个测试会通过,但是运行所有测试却会使某些测试失败。我已经在互联网上搜索了类似的相关问题,但是可以找到任何好的帖子或问题。
如果需要,我也可以发布失败的其他测试,但我认为这与同一个问题有关。
有什么建议吗?