blocknotes / database_recorder

Record application queries, verify them against stored queries, and replay them

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Database Recorder

Gem Version Linters Specs ActiveRecord Specs MySQL Specs PostgreSQL

Record database queries for testing and development purposes. Store queries information on files or Redis.

Main features:

  • store the history of the queries of a test when it run (for monitoring);
  • eventually check if the current queries match the recorded ones (to prevent regressions);
  • [EXPERIMENTAL] optionally replay the recorded queries replacing the original requests.

Sample output: test.yml

Creating an environment variable to enable it with RSpec:

image1

Install

With RSpec

  • Add to your Gemfile: gem 'database_recorder', require: false (:development, :test groups recommended)
  • Add in rails_helper.rb:
require 'database_recorder'
DatabaseRecorder::RSpec.setup
  • In the tests add :dbr metadata, examples:
  # Activate DatabaseRecorder with the default options
  it 'returns 3 posts', :dbr do
    # ...
  end

  # Verify queries comparing with the stored ones:
  it 'returns more posts', dbr: { verify_queries: true } do
    # ...
  end

Or eventually apply the metadata per path:

RSpec.configure do |config|
  config.define_derived_metadata(file_path: %r{/spec/models/}) do |metadata|
    metadata[:dbr] = true
  end
end

With plain Ruby

DatabaseRecorder::Config.db_driver = :pg
DatabaseRecorder::Core.setup
pp DatabaseRecorder::Recording.new(options: { name: 'pg_file' }).start do
  PG.connect(DB_CONFIG).exec("INSERT INTO tags(name, created_at, updated_at) VALUES('tag1', NOW(), NOW())")
  PG.connect(DB_CONFIG).exec("SELECT * FROM tags")
end

For more examples check here.

Config options

These options are available, they must be set before calling DatabaseRecorder::Core.setup:

# Database driver to use: :active_record | :mysql2 | :pg
DatabaseRecorder::Config.db_driver = :pg

# Log queries format (default: '[DB] %sql [%name]')
DatabaseRecorder::Config.log_format = '>>> %name -- %sql'

# To print/log the queries while executing the specs: false | true | :color
DatabaseRecorder::Config.print_queries = true

# Replay the recordings intercepting the queries
DatabaseRecorder::Config.replay_recordings = true

# To store the queries: :file | :redis | nil
DatabaseRecorder::Config.storage = :redis
# nil to avoid storing the queries

# File storage options
DatabaseRecorder::Config.storage_options = { recordings_path: '/some/path' }

# Redis storage options
DatabaseRecorder::Config.storage_options = { connection: Redis.new }

History of the queries

Using the print_queries config option is possible to see the executed queries while running the specs. It can be used to identify easily what is going on in a specific example without having to analyze the log files.

Using the :file storage, the history is also recorded to files (default path: spec/dbr) in YAML format. This is useful for checking what's happening with more details, it includes the query results and some extra data.

Test queries' changes

This feature can be used to prevent queries regressions. It requires to have previously stored the history of the queries (which could be versioned if using file storage). It can be activated using dbr: { verify_queries: true } metadata.

To work correctly in requires prepared_statements: true option in the database.yml config file, in the connection block options (available for both Postgres and MySQL).

Replay the recorded queries

This feature is not stable (at this stage), so use it carefully and supports only deterministic tests (so it doesn't work with Faker, random data or random order specs) and only Postgres is supported for now. It requires to have previously stored the history of the queries. Using this feature can improve the test suite performances (especially using redis storage). It can be activated using replay_recordings config option.

Some workarounds to make it works:

  • With RSpec, run the tests with bin/rspec --order defined
  • Set a specific seed for Faker (optionally with an ENV var): Faker::Config.random = Random.new(42)
  • Set a specific Ruby seed (optionally with an ENV var): srand(42)

Do you like it? Star it!

If you use this component just star it. A developer is more motivated to improve a project when there is some interest.

Or consider offering me a coffee, it's a small thing but it is greatly appreciated: about me.

Contributors

License

The gem is available as open-source under the terms of the MIT.

About

Record application queries, verify them against stored queries, and replay them

License:MIT License


Languages

Language:Ruby 90.7%Language:HTML 6.3%Language:Shell 1.1%Language:JavaScript 1.0%Language:CSS 0.8%