Тестирование Phoenix / Elixir при настройке уровня изоляции транзакции
У меня есть кусок кода, который выглядит примерно так:
Repo.transaction(fn ->
Repo.query!("set transaction isolation level serializable;")
# do some queries
end)
В моем тестовом наборе я постоянно сталкиваюсь с ошибкой:
(Postgrex.Error) ERROR 25001 (active_sql_transaction): SET TRANSACTION ISOLATION LEVEL must be called before any query
Мне интересно, делаю ли я что-то в корне неправильно или что-то не так в тестовой среде.
Спасибо!
1 ответ
Проблема заключается в том, что для целей тестирования все тесты заключены в транзакцию, поэтому их можно откатить, чтобы вы не загрязняли базу данных тоннами старых тестовых данных. Это может привести к сбоям, которые должны были пройти, и проходам, которые должны были пройти не в зависимости от того, как вы написали свои тесты.
Вы можете обойти это, но это, опять же, загрязнит вашу тестовую базу данных, и вам придется очистить ее самостоятельно:
setup do
[Other set up stuff]
Ecto.Adapters.SQL.Sandbox.checkin(MyApp.Repo) #This closes any open transaction, effectively.
Ecto.Adapters.SQL.Sandbox.checkout(MyApp.Repo, [sandbox: false]) # This opens a new transaction without sandboxing.
end
Эта задача установки входит в тестовый файл с вашими неудачными тестами, если у вас нет настройки. Если вы не делаете checkin
позвоните, и вы (скорее всего) получите сообщение о том, что другие запросы выполняются до того, как задан уровень транзакции, потому что вы вставляете что-то перед тестом
Смотрите здесь для кого-то, по сути, вызывает ту же проблему.
Не уверен, что вы все еще ищете ответ на этот вопрос, но я нашел для этого хорошее решение. На этот случай у меня есть такой блок настройки:
setup tags do
:ok =
if tags[:isolation] do
Sandbox.checkout(Repo, isolation: tags[:isolation])
else
Sandbox.checkout(Repo)
end
unless tags[:async] do
Sandbox.mode(Repo, {:shared, self()})
end
:ok
end
затем в тесте, который находится на пути сериализуемой транзакции, вы должны пометить ее "сериализуемой" следующим образом:
@tag isolation: "serializable"
test "my test" do
...
end
это позволит вам запускать тесты, которые встречаются в пути к сериализуемым и по-прежнему используют песочницу.