-
-
Notifications
You must be signed in to change notification settings - Fork 497
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cleaning up unused cassettes #283
Comments
Good question. Personally, I explicitly set the name of my cassettes when I use them so that spec-nesting or verbiage changes of spec descriptions don't affect them. As far as I know, the library does not provide a means to identify unused cassettes. It would probably be rather difficult to ascertain that information in any reliable way, since it depends on whether or not you ran your entire suite and whether any conditionals (or RSpec filters) might have been in play during the previous run which would affect the loaded/used cassettes. That being said, you can do it yourself with something like this: # In spec_helper.rb, for example:
require 'set'
USED_CASSETTES = Set.new
module CassetteReporter
def insert_cassette(name, options = {})
USED_CASSETTES << VCR::Cassette.new(name, options).file
super
end
end
VCR.extend(CassetteReporter)
RSpec.configure do |config|
config.after(:all) {
puts (Dir['spec/cassettes/**/*.yml'].map { |d| File.expand_path(d) } - USED_CASSETTES.to_a).inspect
}
end And then run your entire suite. That would output a list of all cassettes which were defined in your Does that help? |
@nbibler's suggestion above is a good one. Closing, since there's nothing actionable to do here. |
@nbibler Great, thanks for the suggestion :) That looks wonderful |
Maybe it should be formed as a rake task or a module, that can be easily included into any project without copy-pasting? |
Can't get this to work. Do anyone have a new solution? |
Little modified solution: https://gist.github.com/dmitry/f4c7e4dbcf89673f5ede |
@dmitry can you confirm this works in VCR latest version, please? |
@douglascamata yes it works, but you might have to change the directory it searches for cassettes. Note that @dmitry's version deletes the files for you. Here's my version: https://gist.github.com/dideler/062a6d6722e137db55b2 |
I sometimes run subsets of tests — I wonder how we could improve the script to handle these cases rather than output the whole list of 'unused' cassettes when in fact the tests have simply not been chosen to run? |
Slightly more general version of @dideler 's solution here. require 'set'
USED_CASSETTES = Set.new
RSpec.configure do |config|
config.after(:suite) do
cassettes = Dir[File.join(VCR.configuration.cassette_library_dir, '**/*.yml')].map { |d| File.expand_path(d) } - USED_CASSETTES.to_a
if cassettes.any?
puts "\nUnused cassettes:"
puts cassettes.map { |f| f.sub(Rails.root.to_s, '') }
end
end
end
module CassetteReporter
def insert_cassette(name, options = {})
USED_CASSETTES << VCR::Cassette.new(name, options).file
super
end
end
VCR.extend(CassetteReporter) |
Thanks for these ideas! I'm about to implement something similar, It looks as though the posted ideas will only work if the entire test suite is run. It would be great if this could run dependably every time our CI runs, but as we use concurrence, I don't think it would. Any ideas on how to make a solution work in that situation? |
@BenAkroyd write everything into the database/file, once all the parallel concurrency specs/tests are finished just combine everything into one array and check. Or you can make a hook |
Slightly modified version of @BookOfGreg 's solution.
|
I've decided to turn the solution above into custom RSpec formatter, so it would be possible to do require 'rspec/core/formatters/base_text_formatter'
class VCRFormatter < RSpec::Core::Formatters::BaseTextFormatter
# Track list of used cassettes
module CassetteTracker
def self.use(cassette_name, options = {})
used_cassettes << VCR::Cassette.new(cassette_name, options).file
end
def self.used_cassettes
@used_cassettes ||= Set.new
end
def self.spec(group)
folders << group.described_class.to_s.gsub('::', '_')
end
def self.folders
@folders ||= Set.new
end
def self.unused_cassettes
Dir.glob("#{VCR.configuration.cassette_library_dir}/**/*.yml").filter_map do |full_path|
next if used_cassettes.include?(full_path)
path = full_path.delete_prefix("#{VCR.configuration.cassette_library_dir}/")
folder = path.split('/', 2).first
next unless folders.include?(folder)
path
end
end
def self.unused_folders
Dir.glob("#{VCR.configuration.cassette_library_dir}/*/").filter_map do |full_path|
path = full_path.delete_prefix("#{VCR.configuration.cassette_library_dir}/")
folder = path.delete_suffix('/')
next if folders.include?(folder)
path
end
end
end
# Extension of VCR to notify about cassettes
module CassetteReporter
def insert_cassette(name, options = {})
CassetteTracker.use(name, options)
super
end
end
def start(_notification)
VCR.extend(CassetteReporter)
end
def example_group_started(notification)
CassetteTracker.spec(notification.group)
end
def dump_summary(_notification)
output.puts '', 'List of unused cassettes in visited folders:'
CassetteTracker.unused_cassettes.each { |c| output.puts " - #{c}" }
output.puts '', 'List of unvisited folders:'
CassetteTracker.unused_folders.each { |c| output.puts " - #{c}" }
end
end
RSpec::Core::Formatters.register VCRFormatter |
Anyone know of a good way to clean up cassettes that are not being used in any specs? Often, I find myself renaming cassettes due to refactoring of specs and lose track of which ones are no longer in use.
The text was updated successfully, but these errors were encountered: