задача rake вызывается несколько раз - PullRequest
0 голосов
/ 28 апреля 2020

У меня странная проблема с тестированием моих задач на рельсах. Когда я запускаю все тесты для моих рейковых задач, они вызываются несколько раз, но когда я запускаю только один тестовый файл, все вдруг работает. Вот пример кода:

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

rspe c 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

в выводе консоли я могу видеть что-то вроде этого:

> JUST BEFORE INVOKING THE TASK: 
> Running deploy task 'create_users_on_another_app'
> Running deploy task 'create_users_on_another_app'
> DONE

поэтому задача была вызвана два раза.

Я понятия не имею, почему это происходит, и я на 100% уверен, что не вызову его в своем коде дважды. Я подозреваю, что либо отсутствует какая-то конфигурация rake для rspe c, которую я пропускаю, либо гем для задач rake, который я использую - after_party.

У меня проблемы с отладкой попытался использовать show-stack с binding.pry, пока я нахожусь в задаче о граблях, которая вызывает проблемы, но не смог понять, в какой момент запускалась дополнительная задача рейка.

кто-нибудь видел такая проблема раньше?

EDIT: трассировка стека запуска команды show-stack внутри блока it, непосредственно перед задачей invoke rake:

=> #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> 

, также подключающей трассировку стека изнутри само задание по рейку:

=> #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> 

РЕДАКТИРОВАТЬ 2: добавлено больше информации

Я проверил, что произойдет, если я помещу binding.pry таким образом (и внутри задачи по рейку)

  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

ниже после кода задачи party rake

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

и выводом было то, что выполнение кода остановилось на no1, затем мы вошли в задачу rake и остановились на no2 после этого задание было запущено СНОВА (поэтому снова остановилось на no2) и после войны он остановился на no3

...