Haskell 如何使用hspec开始和回滚事务?

Haskell 如何使用hspec开始和回滚事务?,haskell,transactions,hspec,postgresql-simple,Haskell,Transactions,Hspec,Postgresql Simple,我正在尝试使用postgres事务回滚编写一个测试,就像使用的begin和rollback命令一样 但是,应用postgresql simple的begin和rollback命令似乎会导致我的“insert”命令不运行,也不会影响我的数据库 这是相关代码 import qualified Database.PostgreSQL.Simple as PGS import Test.Hspec (describe, it, SpecWith, hspec, before, after) testC

我正在尝试使用postgres事务回滚编写一个测试,就像使用的
begin
rollback
命令一样

但是,应用
postgresql simple
begin
rollback
命令似乎会导致我的“insert”命令不运行,也不会影响我的数据库

这是相关代码

import qualified Database.PostgreSQL.Simple as PGS
import Test.Hspec (describe, it, SpecWith, hspec, before, after)

testConnInfo :: PGS.ConnectInfo
testConnInfo = PGS.ConnectInfo
  { PGS.connectHost = "localhost"
  , PGS.connectPort = 5432
  , PGS.connectUser = "user"
  , PGS.connectPassword = ""
  , PGS.connectDatabase = "database"
  }

testConnection :: IO PGS.Connection
testConnection = do
  PGS.connect testConnInfo

runSpec :: IO ()
runSpec = do
  conn <- testConnection
  hspec $ test_addTask conn

test_addTask :: PGS.Connection -> SpecWith ()
test_addTask conn = describe "test_addTask" $ do
  it "adding_task_succeeds" $ do
    PGS.begin conn
    addTask conn "taskName"
    print "set breakpoint here"
    PGS.rollback conn
    return ()
import qualified Database.PostgreSQL.Simple as PGS
导入测试.Hspec(描述、it、SpecWith、Hspec、之前、之后)
testConnInfo::PGS.ConnectInfo
testConnInfo=PGS.ConnectInfo
{PGS.connectHost=“localhost”
,PGS.connectPort=5432
,PGS.connectUser=“用户”
,PGS.connectPassword=“”
,PGS.connectDatabase=“数据库”
}
testConnection::IO PGS.Connection
testConnection=do
PGS.connect testConnInfo
runSpec::IO()
runSpec=do
与()
test\u addTask conn=描述“test\u addTask”$do
它“添加任务成功”$do
开始康涅狄格州
添加任务连接“任务名称”
打印“在此处设置断点”
PGS.rollbackconn
返回()
我在
ghci
中运行它,在“setbreakpointhere”行设置断点;应在插入条目之后和回滚之前插入。在该断点处暂停时,我查询数据库以查看条目是否已插入,并查看此代码似乎未将任何条目插入数据库

但是,当我删除
PGS.begin conn
PGS.rollback conn
行时,代码会将条目插入数据库

为什么此代码不在“开始”和“回滚”行就位的情况下将条目插入数据库?


我如何编写hspec测试来启动和回滚,以便我的测试不会影响数据库中的值,并实际运行命令?

事务不是这样工作的。交易发生或不发生。如果不从DBs的角度提交事务,则不会发生任何事情。您从未在数据库中插入一行。您所做的只是通知您,如果没有其他问题,您可能希望将来插入它。@Cubic这是否意味着在使用事务回滚防止更改时无法测试调用数据库?您可以使用回滚防止更改。但是如果你阻止一个改变,那么当然不会发生改变。在任何情况下,这听起来像是您试图针对产品运行测试。不要。运行一个专用的测试数据库,一旦测试运行完成,我肯定会接受这个建议并使用测试数据库。在那里运行时,有没有一种方法可以在每次测试后使用回滚而不是对数据库进行nuking/truncating?也许不是,但我的印象是使用回滚将是一个更优雅的解决方案。回滚不是“撤消”。这是“一开始决不做”。整个事务点是将一组单独的操作分组为一个原子操作。无论如何,设置您的测试数据库应该是自动化的,所以它实际上不应该花费您任何费用。对于集成测试,您可以合理地重复使用同一数据库进行多次运行,如果您从未更改数据库,则无需重新构建数据库,但在测试过程中可能会出现问题,因此您需要设置系统来说明这一点。这不是事务的工作方式。交易发生或不发生。如果不从DBs的角度提交事务,则不会发生任何事情。您从未在数据库中插入一行。您所做的只是通知您,如果没有其他问题,您可能希望将来插入它。@Cubic这是否意味着在使用事务回滚防止更改时无法测试调用数据库?您可以使用回滚防止更改。但是如果你阻止一个改变,那么当然不会发生改变。在任何情况下,这听起来像是您试图针对产品运行测试。不要。运行一个专用的测试数据库,一旦测试运行完成,我肯定会接受这个建议并使用测试数据库。在那里运行时,有没有一种方法可以在每次测试后使用回滚而不是对数据库进行nuking/truncating?也许不是,但我的印象是使用回滚将是一个更优雅的解决方案。回滚不是“撤消”。这是“一开始决不做”。整个事务点是将一组单独的操作分组为一个原子操作。无论如何,设置您的测试数据库应该是自动化的,所以它实际上不应该花费您任何费用。对于集成测试,您可以合理地重复使用同一数据库进行多次运行,如果从未更改数据库,则无需重新构建数据库,但在测试过程中可能会出现问题,因此您需要设置您的系统以解决这一问题。