Hooks: Before and After
Knapsack Pro hooks are only available in Queue Mode.
Knapsack exposes four hooks to execute arbitrary code before or after certain events:
KnapsackPro::Hooks::Queue.before_queue do |queue_id|
puts 'before_queue - run before the test suite'
end
KnapsackPro::Hooks::Queue.before_subset_queue do |queue_id, subset_queue_id|
puts 'before_subset_queue - run before the next subset of tests'
end
KnapsackPro::Hooks::Queue.after_subset_queue do |queue_id, subset_queue_id|
puts 'after_subset_queue - run after the previous subset of tests'
end
KnapsackPro::Hooks::Queue.after_queue do |queue_id|
puts 'after_queue - run after the test suite'
end
RSpec
For legacy versions of knapsack_pro
older than 7.0, please click here.
If you use Knapsack Pro in Queue Mode with RSpec hooks:
before(:suite) { ... }
after(:suite) { ... }
Then you need to start using Queue Mode hooks:
KnapsackPro::Hooks::Queue.before_queue { ... }
KnapsackPro::Hooks::Queue.after_queue { ... }
Otherwise, Knapsack Pro would call before(:suite)
and after(:suite)
for each batch of tests fetched from the Queue API.
For example, what follows are the hooks run with two batches of tests:
before_queue
# First batch of tests from Knapsack Pro API
before :suite
first_spec.rb
second_spec.rb
after :suite
# Second batch of tests from Knapsack Pro API
before :suite
third_spec.rb
fourth_spec.rb
after :suite
after_queue
Here are examples of how to define hooks properly so that they are called only once:
- Before suite hook
- After suite hook
before_suite_block = proc {
puts 'RSpec before suite hook called only once'
}
unless KnapsackPro::Config::Env.queue_recording_enabled?
RSpec.configure do |config|
config.before(:suite) do
before_suite_block.call
puts 'Run this only when not using Knapsack Pro Queue Mode'
end
end
end
KnapsackPro::Hooks::Queue.before_queue do |queue_id|
before_suite_block.call
puts 'Run this only when using Knapsack Pro Queue Mode'
puts 'This code is executed within the context of RSpec before(:suite) hook'
end
after_suite_block = proc {
puts 'after suite hook called only once'
}
unless KnapsackPro::Config::Env.queue_recording_enabled?
RSpec.configure do |config|
config.after(:suite) do
after_suite_block.call
puts 'Run this only when not using Knapsack Pro Queue Mode'
end
end
end
KnapsackPro::Hooks::Queue.after_queue do |queue_id|
after_suite_block.call
puts 'Run this only when using Knapsack Pro Queue Mode'
puts "This code is executed outside of the RSpec after(:suite) hook context because it's " +
"impossible to determine which after(:suite) is the last one to execute until it's executed."
end
Get tests and the status of each batch of tests in RSpec
The KnapsackPro::Hooks::Queue.before_subset_queue
and KnapsackPro::Hooks::Queue.after_subset_queue
hooks get a 3rd variable - the queue
.
The queue
variable stores an enumerable collection with each batch of tests fetched from the Queue API. The batch has:
- a list of test file paths (
KnapsackPro::Batch#test_file_paths
returns an array like['a_spec.rb', 'b_spec.rb']
) - a status of the given set of tests in the batch (
KnapsackPro::Batch#status
returns:not_executed
,:passed
or:failed
)
Example usage:
KnapsackPro::Hooks::Queue.before_subset_queue do |queue_id, subset_queue_id, queue|
print "Tests from all batches fetched from the Queue API so far: "
puts queue.map(&:test_file_paths).inspect
queue.each(&:test_file_paths) # you can use each as well
print "Current batch tests: "
puts queue.current_batch.test_file_paths.inspect
print "Current batch status: "
puts queue.current_batch.status # returns :not_executed in the `before_subset_queue` hook
end
KnapsackPro::Hooks::Queue.after_subset_queue do |queue_id, subset_queue_id, queue|
print "Tests from all batches fetched from the Queue API so far: "
puts queue.map(&:test_file_paths).inspect
print "Current batch tests: "
puts queue.current_batch.test_file_paths.inspect
print "Current batch status: "
puts queue.current_batch.status # returns :passed or :failed in the `after_subset_queue` hook
end
percy-capybara
percy-capybara
>= 4
If you are using Knapsack Pro in Queue Mode with percy-capybara
>= 4, you need to configure the environment variables as explained in Percy's docs.
After that, you can use the following command:
npx percy exec --parallel -- rake knapsack_pro:queue:rspec
# or with the knapsack_pro binary
npx percy exec --parallel -- knapsack_pro queue:rspec
Here you can find the docs for the knapsack_pro
binary.
percy-capybara
< 4 (legacy)
For legacy versions of knapsack_pro
older than 7.0, please click here.
If you are using Knapsack Pro in Queue Mode with percy-capybara
< 4 and RSpec, replace:
before(:suite) { Percy::Capybara.initialize_build }
after(:suite) { Percy::Capybara.finalize_build }
with:
KnapsackPro::Hooks::Queue.before_queue { |queue_id| Percy::Capybara.initialize_build }
KnapsackPro::Hooks::Queue.after_queue { |queue_id| Percy::Capybara.finalize_build }
Otherwise, Knapsack Pro would call before(:suite)
and after(:suite)
for each batch of tests fetched from the Queue API.