У меня проблема с тестированием моего приложения с базой данных 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
в блоке before, похоже, исправляются некоторые тесты.
- Изменение числа подключений, разрешенных к тестовой базе данных, на
1
действительно работает для тестов контроллера, но является проблемой в моих тестах возможностей, потому что кажется, что требуется как минимум подключение.
Таким образом, проблема, похоже, связана с преимуществами возможности базы данных PostgreSQL обрабатывать несколько запросов. Но что я не понимаю, что выполнение одного теста пройдет успешно, а выполнение всех тестов провалит некоторые тесты. Я искал в интернете похожие проблемы, но смог найти какой-нибудь хороший пост или вопрос.
При необходимости я могу опубликовать другой тест, который также не проходит, но я думаю, что он связан с одной и той же проблемой.
Есть предложения?