使用 Cucumber 测试重复的 cron 作业

发布于 2024-11-18 23:11:15 字数 1637 浏览 0 评论 0原文

如果我的用户的某个折扣即将到期,我想在上午 10 点通知他们。我正在使用 heroku 的每小时 cron。我使用的是 Rails 3.0.9 和 Ruby 1.8.7。我在 lib/tasks/cron 中有以下 cron.rake:

# Notify users with expiring claims
puts "Notifying users with expiring claims..."
if Time.zone.now.hour == 10
  Claim.expiring_tomorrow.reject(&:redeemed?).compact.each do |claim|
    Mailer.delay.notify_customer_claim_expiration(claim)
    claim.update_attribute(:expiration_notified, true)
  end
end
puts "done."

效果很好。我的问题是我必须在黄瓜中测试三个不同的场景:

Scenario: Not receiving a expiration reminder too early
Scenario: Receiving a expiration reminder only once
Scenario: Not receiving a reminder for a redeemed claim

因此我编写了以下功能:

Feature: Being reminded that a claimed discount is expiring

  Background:
    Given the hourly cron job exists

  Scenario: Not receiving a expiration reminder too early
    And the hourly cron job has fired

  Scenario: Receiving a expiration reminder only once
    And the hourly cron job has fired

  Scenario: Not receiving a reminder for a redeemed claim
    And the hourly cron job has fired

具有以下 cron.steps 步骤定义:

And /^the hourly cron job exists$/ do
  require "rake"
  @rake = Rake::Application.new
  Rake.application = @rake
  Rake.application.rake_require "lib/tasks/cron"
end

And /^the hourly cron job has fired$/ do
  Rake::Task["cron"].invoke
end

如果我单独运行每个场景,它们就会通过。如果我运行整个功能,它会在第二个(不是第一个)场景中失败:

RuntimeError: Don't know how to build task 'cron'

看起来 Rake 没有持续经过第一个场景,或者需要在第二个场景运行之前重置...?

谢谢...G

I want to notify my users at 10AM if one of their Discounts is expiring soon. I am using heroku's hourly cron. I am on Rails 3.0.9 with Ruby 1.8.7. I have the following cron.rake in lib/tasks/cron:

# Notify users with expiring claims
puts "Notifying users with expiring claims..."
if Time.zone.now.hour == 10
  Claim.expiring_tomorrow.reject(&:redeemed?).compact.each do |claim|
    Mailer.delay.notify_customer_claim_expiration(claim)
    claim.update_attribute(:expiration_notified, true)
  end
end
puts "done."

That works great. My problem is that I have to test three different Scenarios in cucumber:

Scenario: Not receiving a expiration reminder too early
Scenario: Receiving a expiration reminder only once
Scenario: Not receiving a reminder for a redeemed claim

and so I wrote the following Feature:

Feature: Being reminded that a claimed discount is expiring

  Background:
    Given the hourly cron job exists

  Scenario: Not receiving a expiration reminder too early
    And the hourly cron job has fired

  Scenario: Receiving a expiration reminder only once
    And the hourly cron job has fired

  Scenario: Not receiving a reminder for a redeemed claim
    And the hourly cron job has fired

with the following cron.steps Step definition:

And /^the hourly cron job exists$/ do
  require "rake"
  @rake = Rake::Application.new
  Rake.application = @rake
  Rake.application.rake_require "lib/tasks/cron"
end

And /^the hourly cron job has fired$/ do
  Rake::Task["cron"].invoke
end

If I run each Scenario individually, they pass. If I run the whole Feature, it fails on the second (not the first) Scenario with:

RuntimeError: Don't know how to build task 'cron'

It seems that the Rake is not persisting past the first Scenario or needs to be reset before the second Scenario runs...?

Thanks...G

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

怀念你的温柔 2024-11-25 23:11:15

谢谢你的帖子。我最终这样做了:

And /^a cron job exists$/ do
  require "rake"
  @rake = Rake::Application.new
  Rake.application = @rake

  # remove cron.rake from list of required files to force file to be reloaded
  loaded = $".reject {|file| file == Rails.root.join("lib", "tasks", "cron.rake").to_s }

  Rake.application.rake_require("lib/tasks/cron", [Rails.root.to_s], loaded)
  Rake::Task.define_task(:environment)
end

And /^the hourly cron job has fired$/ do
  @rake["cron"].invoke
end

Thanks for the post. I ended up doing this:

And /^a cron job exists$/ do
  require "rake"
  @rake = Rake::Application.new
  Rake.application = @rake

  # remove cron.rake from list of required files to force file to be reloaded
  loaded = $".reject {|file| file == Rails.root.join("lib", "tasks", "cron.rake").to_s }

  Rake.application.rake_require("lib/tasks/cron", [Rails.root.to_s], loaded)
  Rake::Task.define_task(:environment)
end

And /^the hourly cron job has fired$/ do
  @rake["cron"].invoke
end
只想待在家 2024-11-25 23:11:15
Rake::Task[].invoke 

将检查 rake 任务是否已被调用,如果没有则执行它。即,如果多次调用,它只会执行一次任务,

Rake::Task[].execute 

每次调用它时都会执行该任务。

Rake::Task[].invoke 

will check if the rake task has already been called, and execute it if not. Ie it will only execute the task once if called multiple times

Rake::Task[].execute 

will just execute the task every time you call it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文