大数据&云计算|Rspec的数据库事务:如何清理陈旧数据?
全文共1319字 , 预计学习时长7分钟
【大数据&云计算|Rspec的数据库事务:如何清理陈旧数据?】
本文插图
图源:devclass
测试用例之间的陈旧数据是RSpec中竞态条件的主要原因之一 , 包括数据库Redis、文件等 。 本文就将讨论如何清理数据库中的陈旧数据 。
Rails Rspec后台默认事务
如果使用rails-rspec , 默认情况下 , spec/rails_helper.rb中会启用以下配置:
RSpec.configuredo |config| config.use_transactional_fixtures=true end
这意味着“在事务内运行每个示例” , 即在示例结束时 , 所有数据库的变更都将回滚 。
如何让“事务装置”实现“在事务内运行每个示例”?
在深入研究Rails 4代码库 , 了解了它在后台的实际工作之后 , 我发现了以下内容 。 setup_fixtures函数中 , Rails为每个数据库连接调用begin_transaction 。
本文插图
Rails 4的setup_fixtures
在teardown_fixtures函数中 , Rails为每个数据库连接调用rollback_transaction 。
本文插图
Rails 4的teardown_fixtures
这也意味着 , 如果在应用程序中使用多个数据库 , 那么应用程序将为所有数据库创建事务 。
在示例之外创建的数据库记录将不会回滚
由于数据库事务围绕着每个示例 , 因此在示例范围之外创建的任何数据库记录都不会回滚 , 也就是说 , 在before(:all)、before(:context)或before(:suite)代码块中创建的任何数据库记录都不会回滚 。
这可能导致示例组之间而不是同一组的示例之间的竞态条件 , 因此处理hook问题时要十分小心 。
context"context 1"do before(:context) do create(:user) # WON"T BE ROLLED-BACK end beforedo create(:user) # will be rolled-back end # ... end context"context 2"do before(:context) do create(:user) # WON"T BE ROLLED-BACK end # ... end # BY NOW, THERE ARE 2 USER RECORDS COMMITED TO DATABASE
手动设置数据库事务
你还可以选择使用hook手动设置数据库事务 。
RSpec.configuredo |config| config.use_transactional_fixtures=false# DISABLE DEFAULT TRANSACTIONS end before(:example) do ActiveRecord::Base.connection.begin_transaction end after(:example) do conn =ActiveRecord::Base.connection conn.rollback_transactionif conn.transaction_open? end # OR around(:example) do |example| ActiveRecord::Base.transactiondo example.run # ROLLBACK after the example finishes. # This exception is silently swallowed by ActiveRecord. raiseActiveRecord::Rollback end end
[Rails 4 & Rails 5.0.x]数据库事务是按线程执行的
Rails 4中的数据库连接
由上可知 , ActiveRecord数据库连接是按线程执行的 。 因此 , Rails通过use_transactional_fixtures管理的默认数据库事务只在主线程中可用 。
从技术上说 , 根据事务回滚策略 , 一个线程的数据库记录将独立于其他线程 。 需要访问其他线程中的某个线程的数据库数据时请注意这一点 , 例如Selenium 。
[Rails 4 & Rails 5.0.x]JavaScript驱动程序(Selenium)和Capybara Webkit的验收测试问题
Selenium在另一个线程上运行 , 因此它不能与运行RSpec的主线程共享事务 。 为了让客户端应用程序访问数据库中的数据 , RSpec需要将改动提交 。 这类情况下可以允许提交数据 , 然后手动清理数据 。
[Rails 4 & Rails 5.0.x]DatabaseCleaner——回滚策略
要解决上述问题 , 首先需要禁用Rails派生的事务 , 将config.use_transactional_fixtures设置为false , 或干脆删除它 。 DatabaseCleaner是一个gem , 它提供了清理数据库的高级策略 , 例如删节、事务处理或删除 。
下面是利用DatabaseCleaner处理上述JS驱动程序问题的著名gist:
本文插图
[从Rails 5.1起]数据库事务在测试线程之间共享
线程之间的共享数据库事务由Rails团队的Eileen完成 , 并作为Rails 5.1的一部分内容发布 。
本文插图
加入了lock_thread
本文插图
为测试启用了lock_thread
此更新允许将启用JS的验收测试封装在RSpec的默认事务中 , 这已经消除了对DatabaseCleaner的需求 。
推荐阅读
- 凉茶|凉茶最大的问题不是添加西药,而是冒充饮料
- 上汽大众途观x|颜值比途观L高!上汽大众途观X将亮相2020北京车展,明年初上市
- 未来的大学生活“长啥样”? 来看学长为你写下的万字指南
- the|新冠肺炎成美国第三大致死原因 仅次于心脏病和癌症
- 多所在京大学录取线来了 各校设置多条投档线
- 旅行路上阿|成都反差最大景区,一边是游客专属一边本地人最爱,门票相差4倍
- 旅行在路上啊|成都反差最大景区,一边是游客专属一边本地人最爱,门票相差4倍
- 腾讯任天堂Switch国行《健身环大冒险》将于8月19日发布
- 珠海生活资讯交流|推动琴澳旅游合作, 大横琴文旅展示中心18日在横琴口岸正式开放
- 提供“让兴趣成为职业”的可能 “微经济”有大宝藏
