I have a strange problem with testing my rails tasks. When I'm running all the tests for my rake tasks they are being invoked multiple times, but when I run only one test file everything is suddenly working. Here is an example code:
rake task
namespace :after_party do
desc 'Deployment task: create_users_on_another_app'
task create_users_on_another_app: :environment do
...some code
AppClient.post(some_url, some_payload, some_header)
...some more code
AfterParty::TaskRecord.create version: '20190620160110'
end
end
end
rspec test
describe 'create_users_on_another_app' do
before do
allow(AppClient).to receive(:post).and_return(some_response)
end
it "creates users" do
expect(AppClient).to receive(:post).with(some_url, some_data, some_header)
puts "JUST BEFORE INVOKING THE TASK: "
Rake::Task['after_party:create_users_on_another_app'].invoke
puts "DONE"
end
end
in the console output i can see something like this:
> JUST BEFORE INVOKING THE TASK:
> Running deploy task 'create_users_on_another_app'
> Running deploy task 'create_users_on_another_app'
> DONE
so the task was invoked two times.
I have no idea why this is happening and I'm 100% sure I'm not invoking it in my code twice. I'm suspecting that either it is some rake configuration for rspec that I'm missing or the gem for rake tasks that I'm using - after_party
.
I'm having hard times debugging it, tried using show-stack
with binding.pry
while I'm in the rake task that is causing the issues but didn't manage to see at what point additional rake task was being fired.
anyone has seen such issue before?
EDIT: stack trace of running show-stack command inside it
block, just before the invoke
rake task:
=> #0 <main>
#1 [block] block in run <Byebug::PryProcessor#run(&_block)>
#2 [method] run <Byebug::PryProcessor#run(&_block)>
#3 [method] resume_pry <Byebug::PryProcessor#resume_pry()>
#4 [method] at_line <Byebug::PryProcessor#at_line()>
#5 [method] at_line <Byebug::Context#at_line()>
#6 [block] block (2 levels) in <top (required)>
#7 [block] block in run <RSpec::Core::Example#run(example_group_instance, reporter)>
#8 [block] block in with_around_and_singleton_context_hooks <RSpec::Core::Example#with_around_and_singleton_context_hooks()>
#9 [block] block in with_around_example_hooks <RSpec::Core::Example#with_around_example_hooks()>
#10 [block] block in run <RSpec::Core::Hooks::HookCollections#run(position, scope, example_or_group)>
#11 [block] block in run_around_example_hooks_for <RSpec::Core::Hooks::HookCollections#run_around_example_hooks_for(example)>
#12 [method] call <RSpec::Core::Example::Procsy#call(*args, &block)>
#13 [block] block (2 levels) in <module:MinitestLifecycleAdapter>
#14 [method] instance_exec <RSpec::Core::Example#instance_exec(*args, &block)>
#15 [method] execute_with <RSpec::Core::Hooks::AroundHook#execute_with(example, procsy)>
#16 [block] block (2 levels) in run_around_example_hooks_for <RSpec::Core::Hooks::HookCollections#run_around_example_hooks_for(example)>
#17 [method] call <RSpec::Core::Example::Procsy#call(*args, &block)>
#18 [block] block (3 levels) in <top (required)>
#19 [method] perform_enqueued_jobs <ActiveJob::TestHelper#perform_enqueued_jobs(?, ?)>
#20 [block] block (2 levels) in <top (required)>
#21 [method] instance_exec <RSpec::Core::Example#instance_exec(*args, &block)>
#22 [method] execute_with <RSpec::Core::Hooks::AroundHook#execute_with(example, procsy)>
#23 [block] block (2 levels) in run_around_example_hooks_for <RSpec::Core::Hooks::HookCollections#run_around_example_hooks_for(example)>
#24 [method] call <RSpec::Core::Example::Procsy#call(*args, &block)>
#25 [block] block in run <RSpec::Retry#run()>
#26 [method] run <RSpec::Retry#run()>
#27 [method] run_with_retry <RSpec::Core::Example::Procsy#run_with_retry(opts=?)>
#28 [block] block (2 levels) in setup <self.setup(UNKNOWN) (undefined method)>
#29 [method] instance_exec <RSpec::Core::Example#instance_exec(*args, &block)>
#30 [method] execute_with <RSpec::Core::Hooks::AroundHook#execute_with(example, procsy)>
#31 [block] block (2 levels) in run_around_example_hooks_for <RSpec::Core::Hooks::HookCollections#run_around_example_hooks_for(example)>
#32 [method] call <RSpec::Core::Example::Procsy#call(*args, &block)>
#33 [method] run_around_example_hooks_for <RSpec::Core::Hooks::HookCollections#run_around_example_hooks_for(example)>
#34 [method] run <RSpec::Core::Hooks::HookCollections#run(position, scope, example_or_group)>
#35 [method] with_around_example_hooks <RSpec::Core::Example#with_around_example_hooks()>
#36 [method] with_around_and_singleton_context_hooks <RSpec::Core::Example#with_around_and_singleton_context_hooks()>
#37 [method] run <RSpec::Core::Example#run(example_group_instance, reporter)>
#38 [block] block in run_examples <RSpec::Core::ExampleGroup.run_examples(reporter)>
#39 [method] run_examples <RSpec::Core::ExampleGroup.run_examples(reporter)>
#40 [method] run <RSpec::Core::ExampleGroup.run(reporter=?)>
#41 [block] block (3 levels) in run_specs <RSpec::Core::Runner#run_specs(example_groups)>
#42 [block] block (2 levels) in run_specs <RSpec::Core::Runner#run_specs(example_groups)>
#43 [method] with_suite_hooks <RSpec::Core::Configuration#with_suite_hooks()>
#44 [block] block in run_specs <RSpec::Core::Runner#run_specs(example_groups)>
#45 [method] report <RSpec::Core::Reporter#report(expected_example_count)>
#46 [method] run_specs <RSpec::Core::Runner#run_specs(example_groups)>
#47 [method] run <RSpec::Core::Runner#run(err, out)>
#48 [method] run <RSpec::Core::Runner.run(args, err=?, out=?)>
#49 [method] invoke <RSpec::Core::Runner.invoke()>
#50 [top] <top (required)>
#51 [eval] <main>
#52 [main] <main>
also attaching stack trace from inside the rake task itself:
=> #0 <main>
#1 [block] block in run <Byebug::PryProcessor#run(&_block)>
#2 [method] run <Byebug::PryProcessor#run(&_block)>
#3 [method] resume_pry <Byebug::PryProcessor#resume_pry()>
#4 [method] at_line <Byebug::PryProcessor#at_line()>
#5 [method] at_line <Byebug::Context#at_line()>
#6 [block] block (2 levels) in <top (required)>
#7 [block] block in execute <Rake::Task#execute_without_bugsnag(args=?)>
#8 [method] execute <Rake::Task#execute_without_bugsnag(args=?)>
#9 [method] execute_with_bugsnag <Rake::Task#execute_with_bugsnag(args=?)>
#10 [block] block in invoke_with_call_chain <Rake::Task#invoke_with_call_chain(task_args, invocation_chain)>
#11 [method] mon_synchronize <MonitorMixin#mon_synchronize()>
#12 [method] invoke_with_call_chain <Rake::Task#invoke_with_call_chain(task_args, invocation_chain)>
#13 [method] invoke <Rake::Task#invoke(*args)>
#14 [block] block (2 levels) in <top (required)>
#15 [block] block in run <RSpec::Core::Example#run(example_group_instance, reporter)>
#16 [block] block in with_around_and_singleton_context_hooks <RSpec::Core::Example#with_around_and_singleton_context_hooks()>
#17 [block] block in with_around_example_hooks <RSpec::Core::Example#with_around_example_hooks()>
#18 [block] block in run <RSpec::Core::Hooks::HookCollections#run(position, scope, example_or_group)>
#19 [block] block in run_around_example_hooks_for <RSpec::Core::Hooks::HookCollections#run_around_example_hooks_for(example)>
#20 [method] call <RSpec::Core::Example::Procsy#call(*args, &block)>
#21 [block] block (2 levels) in <module:MinitestLifecycleAdapter>
#22 [method] instance_exec <RSpec::Core::Example#instance_exec(*args, &block)>
#23 [method] execute_with <RSpec::Core::Hooks::AroundHook#execute_with(example, procsy)>
#24 [block] block (2 levels) in run_around_example_hooks_for <RSpec::Core::Hooks::HookCollections#run_around_example_hooks_for(example)>
#25 [method] call <RSpec::Core::Example::Procsy#call(*args, &block)>
#26 [block] block (3 levels) in <top (required)>
#27 [method] perform_enqueued_jobs <ActiveJob::TestHelper#perform_enqueued_jobs(?, ?)>
#28 [block] block (2 levels) in <top (required)>
#29 [method] instance_exec <RSpec::Core::Example#instance_exec(*args, &block)>
#30 [method] execute_with <RSpec::Core::Hooks::AroundHook#execute_with(example, procsy)>
#31 [block] block (2 levels) in run_around_example_hooks_for <RSpec::Core::Hooks::HookCollections#run_around_example_hooks_for(example)>
#32 [method] call <RSpec::Core::Example::Procsy#call(*args, &block)>
#33 [block] block in run <RSpec::Retry#run()>
#34 [method] run <RSpec::Retry#run()>
#35 [method] run_with_retry <RSpec::Core::Example::Procsy#run_with_retry(opts=?)>
#36 [block] block (2 levels) in setup <self.setup(UNKNOWN) (undefined method)>
#37 [method] instance_exec <RSpec::Core::Example#instance_exec(*args, &block)>
#38 [method] execute_with <RSpec::Core::Hooks::AroundHook#execute_with(example, procsy)>
#39 [block] block (2 levels) in run_around_example_hooks_for <RSpec::Core::Hooks::HookCollections#run_around_example_hooks_for(example)>
#40 [method] call <RSpec::Core::Example::Procsy#call(*args, &block)>
#41 [method] run_around_example_hooks_for <RSpec::Core::Hooks::HookCollections#run_around_example_hooks_for(example)>
#42 [method] run <RSpec::Core::Hooks::HookCollections#run(position, scope, example_or_group)>
#43 [method] with_around_example_hooks <RSpec::Core::Example#with_around_example_hooks()>
#44 [method] with_around_and_singleton_context_hooks <RSpec::Core::Example#with_around_and_singleton_context_hooks()>
#45 [method] run <RSpec::Core::Example#run(example_group_instance, reporter)>
#46 [block] block in run_examples <RSpec::Core::ExampleGroup.run_examples(reporter)>
#47 [method] run_examples <RSpec::Core::ExampleGroup.run_examples(reporter)>
#48 [method] run <RSpec::Core::ExampleGroup.run(reporter=?)>
#49 [block] block (3 levels) in run_specs <RSpec::Core::Runner#run_specs(example_groups)>
#50 [block] block (2 levels) in run_specs <RSpec::Core::Runner#run_specs(example_groups)>
#51 [method] with_suite_hooks <RSpec::Core::Configuration#with_suite_hooks()>
#52 [block] block in run_specs <RSpec::Core::Runner#run_specs(example_groups)>
#53 [method] report <RSpec::Core::Reporter#report(expected_example_count)>
#54 [method] run_specs <RSpec::Core::Runner#run_specs(example_groups)>
#55 [method] run <RSpec::Core::Runner#run(err, out)>
#56 [method] run <RSpec::Core::Runner.run(args, err=?, out=?)>
#57 [method] invoke <RSpec::Core::Runner.invoke()>
#58 [top] <top (required)>
#59 [eval] <main>
#60 [main] <main>
EDIT 2: added more info
I've checked what would happen if I place binding.pry
like that (and inside the rake task as well)
it "creates users" do
expect(AppClient).to receive(:post).with(some_url, some_data, some_header)
binding.pry # no1 before rake task invokation
Rake::Task['after_party:create_users_on_another_app'].invoke
binding.pry # no3 after rake task invokation
puts "DONE"
end
below after party rake task code
namespace :after_party do
desc 'Deployment task: create_users_on_another_app'
task create_users_on_another_app: :environment do
...some code
binding.pry # no2 inside the task
AppClient.post(some_url, some_payload, some_header)
...some more code
AfterParty::TaskRecord.create version: '20190620160110'
end
end
end
and the output was that code execution stopped at no1
, then we went into the rake task and stopped at no2
, afterwards the task was ran AGAIN (so again stopped at no2
) and afterwards it was stopping at no3
puts "JUST BEFORE INVOKING THE TASK: "
twice? – Grzegorzit
statement. Second is from inside the rake task itself (every time the rake task is being invoked the stack trace appears the same) – beniutekRunning deploy task 'create_users_on_another_app'
message showing in the console. Set up a breakpoint there (you should pause there twice), and let's compare stack traces from both of those pauses. – Grzegorzit
statement it only gets called once (the result is the first stacktrace). When I set the breaking point inside the rake task itself it gets called twice (that's the second stacktrace, when I'm checking this stacktrace in to second invokation of rake task it is the same as in the first one). – beniutek