Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I undo File System changes made in my Rails/RSpec tests?

In my Rails/Rspec tests I'm CRUD'ing file resources. I'd like to be able to undo any of those changes after my tests complete the same way that database changes are undone with transactions.

  1. If I add a file for a test, I'd like to have the file removed after the test.
  2. If I modify a file for a test, I'd like have the file restored to its prior state after the test.
  3. If I delete a file for a test, I'd like to have the file restored

Is there a feature in RSpec or perhaps a different Gem that monitors file system changes and can restore to a previous state? Or must I undo these changes manually?

I'm currently running Rails3, RSpec2, and Capybara.

like image 434
plainjimbo Avatar asked Dec 06 '25 03:12

plainjimbo


1 Answers

I took Brian John's advice on all of his points, but I thought that I'd post some code from my solution in case anyone else was looking to do something similar. I also added a check for a custom metadata tag, so that I only do this when I flag a test group with a :file symbol

spec_helper.rb

Note that below I'm backing up my #{Rails.root}public/system/ENV/files directory (where ENV = "test" or "develop") because I'm using this for testing paperclip functionality and that's where my files get stored.

Also, instead of just doing an rm -r on the directory structure I'm restoring with the --delete rysnc command from my backup file, which will remove any files that were created during the test.

RSpec.configure do |config|
  # So we can tag tests with our own symbols, like we can do for ':js'
  # to signal that we should backup and restore the filesystem before
  config.treat_symbols_as_metadata_keys_with_true_values = true

  config.before(:each) do
    # If the example group has been tagged with the :file symbol then we'll backup
    # the /public/system/ENV directory so we can roll it back after the test is over
    if example.metadata[:file]
      `rsync -a #{Rails.root}/public/system/#{Rails.env}/files/ #{Rails.root}/public/system/#{Rails.env}/files.back`
    end
  end

  config.after(:each) do
    # If the example group has been tagged with the file symbol then we'll revert
    # the /public/system/ENV directory to the backup file we created before the test
    if example.metadata[:file]
      `rsync -a --delete #{Rails.root}/public/system/#{Rails.env}/files.back/ #{Rails.root}/public/system/#{Rails.env}/files/`
    end
  end
end

sample_spec.rb

Note that I've tagged the it "should create a new file" with the :file symbol

require 'spec_helper'

describe "Lesson Player", :js => true do

  it "should create a new file", :file do
    # Do something that creates a new file
    ...
  end

end
like image 197
plainjimbo Avatar answered Dec 08 '25 17:12

plainjimbo