设置事务隔离级别时的 Phoenix / Elixir 测试
Phoenix / Elixir testing when setting isolation level of transaction
我有一段代码看起来像这样:
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
我想知道我是否做错了根本性的事情,或者我是否遗漏了有关测试环境的某些内容。
谢谢!
问题是出于测试目的,所有测试都包含在一个事务中,因此它们可以回滚,这样您就不会用大量旧测试数据污染您的数据库。根据您编写测试的方式,这可能会导致本应通过的失败和本应失败的通过。
您可以解决它,但它会再次污染您的测试数据库,您必须自己清理它:
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
调用,您将(很可能)在设置事务级别之前收到有关其他查询 运行 的错误,因为您在测试之前插入了一些内容。
请参阅 here 以了解基本上提出相同问题的人。
不确定您是否仍在寻找这个问题的答案,但我找到了一个很好的解决方案。对于我有这样的设置块的情况:
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
然后在可序列化事务路径中的测试上,您必须用 "serializable" 标记它,如下所示:
@tag isolation: "serializable"
test "my test" do
...
end
这将使您 运行 您的测试在路径中遇到可序列化并且仍然使用沙箱。
我有一段代码看起来像这样:
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
我想知道我是否做错了根本性的事情,或者我是否遗漏了有关测试环境的某些内容。
谢谢!
问题是出于测试目的,所有测试都包含在一个事务中,因此它们可以回滚,这样您就不会用大量旧测试数据污染您的数据库。根据您编写测试的方式,这可能会导致本应通过的失败和本应失败的通过。
您可以解决它,但它会再次污染您的测试数据库,您必须自己清理它:
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
调用,您将(很可能)在设置事务级别之前收到有关其他查询 运行 的错误,因为您在测试之前插入了一些内容。
请参阅 here 以了解基本上提出相同问题的人。
不确定您是否仍在寻找这个问题的答案,但我找到了一个很好的解决方案。对于我有这样的设置块的情况:
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
然后在可序列化事务路径中的测试上,您必须用 "serializable" 标记它,如下所示:
@tag isolation: "serializable"
test "my test" do
...
end
这将使您 运行 您的测试在路径中遇到可序列化并且仍然使用沙箱。