Dump Hook
A library that helps cache your data received from performing user actions in tests. We use it in our acceptance tests to enhance performance of preparing data for the tests. It contains ways to cache Postgres and MySql DBs and you need to take care about other sources your own.
Installation
gem 'dump_hook'For Rspec/Capybara add to rails_helper.rb:
require "dump_hook"
RSpec.configure do |config|
  config.include DumpHook
endFor Cucumber/Capybara add to env.rb:
require "dump_hook"
World(DumpHook)Configuration
There are several parameters to run and manage it.
DumpHook.setup do |config|
  config.database = ActiveRecord::Base.configurations[Rails.env]["database"]
  config.actual = Date.today.monday.to_s(:number)
endDb settings:
- 
database- database name - 
host- DB server - 
port- DB server port - 
username- user to connect - 
password- password to connect, works just for MySql - 
database_type-postgres/mysql, by default it'spostgres 
It looks like database is a single required parameter. Others may be default for your DB connection. In relation to
password for postgres you need to use the url way in database parameter in order to set password. You may use
the gem database_url to get this url.
config.database = postgresql://username:password@localhost/databaseDump hook settings
- 
actual- an attribute to manage how long or when you need to create a new dump for your actions. For instance, you may set it toDate.currentto recreate your dumps every day. By default it's empty and your dumps will not recreate. - 
remove_old_dumps- whenactualis pointed your old dumps will be removed. By default it'strue. - 
dumps_location- by default it'stmp/dump_hook. You may pass something more exciting, e.g your current git branch or some path to store your dumps in your repo and generate them using CI. - 
recreate- by default it'sfalse. It recreates your dumps in the current session. It helps when you changeexecute_with_dump's body. You can set it throughENVvariableDUMP_HOOK=recreatefor some certain tests. 
 $ DUMP_HOOK=recreate rails test test/system/your_test.rbUsage
Attention! It works for clear DB. In case when you have some previous data you may come across with conflicts or
incorrect data which may influence your tests. Yet one vital moment you cannot use the transactional way in your tests
as dump_hook will not be able to store anything. Our benchmarks don't note some difference for our system tests and we
prefer to use the same way as in the production environment. We hope you go by this rule too.
There is just single method what wrap your actions and restore dump again
execute_with_dump(name, opts={}, &block)- 
name- identity what explain meaning of this background - 
opts[:actual]- the same to the global parameteractualwhat override it - 
opts[:created_on]- Date time to use in Time travelling for time dependent tests. In this caseactualis unnecessary and ignored. If you want to recreate such dumps you need to clean them manually. 
Capybara example
execute_with_dump("user_data") do
  create_superadmin
  login_as_superadmin
  go_to_users
  add_user("John Doe")
  add_user("Adam Smith")
  add_user("Robert Martin")
  add_user("Kent Beck")
  logout
endCucumber example
You can use the capybara way or create a wrap step to have all actions in your features
Given(/^There is "(.*?)" background with:$/) do |name, steps_order|
  execute_with_dump(name) do
    steps steps_order.to_s
  end
endand use it in your scenarios
Feature: User can modify project
  Background:
    Given There is "project_modification" background with:
    """
    There is the user data
    I login as superadmin
    I create a project "Time tracking"
    I logout
    """
  Scenario: I can rename project
    Given I login as "John Doe"
      And I go to the projects
      And I click "Edit" for "Time tracking" project
     When I fill out "name" with "Time management"
      And I click "Save"
     Then I see the notification "Project is updated"  In this example There is the user data is step what wraps the capybara example
How to add new sources or hooks
Disclaimer: We are working on enhancements
If you need to add yet one source, e.g "we have yet one service and need to dump its data" you may use something similar
module YourServiceHook
  def store_dump(filename)
    super
    data = YourServiceAPI.import
    File.open(your_service_filename(filename), "w") do |f| 
      f.write(data)
    end
  end
  def restore_dump(filename)
    super
    buffer = File.open(your_service_filename(filename)).read
    YourServiceAPI.export(buffer)
  end
  
  def your_service_filename
    filename.gsub(".dump", ".your_service")
  end
endand add it after DumpHook module
include DumpHook
include YourServiceHookTODO
- Dump other sources like 
cookies, Elastic Search, etc. - Enhance ways of adding hooks to extend current sources without overriding(In progress)
 - Add some sugar to create common dumps for CI or 
parallel_tests 
License
The gem is available as open source under the terms of the MIT License.