在 Ruby 中计算天数

Calculating days in Ruby

我有一个问题,我正在尝试确定网页上的某个警报是否正确计算总和。我正在使用水豚和黄瓜。

我有一个警报计算 30 天内过期的记录。选择此警报时,记录列在 table 中,日期按以下格式显示,“2016 年 2 月 1 日”

我想做的是以某种方式获取今天的日期,将其与 table 中返回的日期进行比较,并确保它距离警报中的日期 >= 30 天。

我可以使用 Time.strftime 等将今天的日期设置为相同的格式

当我尝试这样的事情时:

And(/^I can see record "([\d]*)" MOT is calculated due within 30 days$/) do |selection1|


  today = Time.now.strftime('%l %b %Y')
  thirty_days = (today + 30)
  first_30day_mot = first('#clickable-rows > tbody > tr:nth-child(' + selection1 + ') > td:nth-child(3)')

if today + first_30day_mot <= thirty_days
  puts 'alert correct'
else
  (error handler here)
  end
end

如您所见,这真是一团糟。

我一直收到错误 TypeError: no implicit conversion of Fixnum into String

如果有人能想出更巧妙的方法来做到这一点,请让我摆脱痛苦。

谢谢

selection1 显式转换为字符串(或者,使用字符串插值更好):

first_30day_mot = first("#clickable-rows > tbody > tr:nth-child(#{selection1}) > td:nth-child(3)")

此外,我怀疑它下面的一行应该转换为整数以将其添加到 today:

first_30day_mot.to_i <= 30

UPD 好的,我终于有时间仔细看看了。天数计算不需要所有这些巫毒魔法:

 # today = Time.now.strftime('%l %b %Y') # today will be a string " 3 Feb 2016"
 # thirty_days = (today + 30) this was causing an error

 # correct:

 # today = DateTime.now # correct, but not needed
 # plus_30_days = today + 30.days  # correct, but not needed
 first_30day_mot = first("#clickable-rows > tbody > tr:nth-child(#{selection1}) > td:nth-child(3)")

 if 30 > first_30day_mot.to_i
   ...

希望对您有所帮助。

我强烈建议不要使用 Cucumber 进行此类测试。你会发现它的:

  1. 很难设置
  2. 运行时间成本高
  3. 没有提供足够的收益来证明 setup/runtime 成本

而是考虑为提供日期的事物编写单元测试。一般来说,一个好的单元测试可以很容易地 运行 比场景快 10 到 100 倍。

虽然在一个场景中你不会经历那么多的痛苦,但一旦你有很多这样的场景,痛苦就会累积起来。使用 Cucumber 的部分艺术在于为您编写的每个场景都获得足够的效果。

您的尝试至少有几处​​错误。

  1. 您正在将日期转换为字符串,然后尝试将时间长度与字符串进行比较。您应该将字符串转换为日期,然后比较它们

  2. #first returns 页面中的元素不是元素的内容

从你的代码中并不能 100% 清楚你要做什么,但从测试命名来看,我认为你只想确保第三个 td 单元格中的日期(采用 2016 年 2 月 1 日的格式) ) 的给定行距现在不到 30 天。如果是这样,下面应该做你想做的事

mot_element = first("#clickable-rows > tbody > tr:nth-child(#{selection1}) > td:nth-child(3)")
date_of_mot = Date.parse(mot_element.text)

if (date_of_mot - Date.today) < 30
  puts 'alert correct'
else
  #error handler
end

除此之外,我不确定您为什么将 #first 与该选择器一起使用,因为它似乎应该只匹配页面上的一个元素,因此您可能想将其换成 #find,这将使您从水豚的等待行为中受益。如果您确实需要#first,您可以考虑传递 minimum: 1 选项以确保它等待一段时间以匹配元素出现在页面上(如果这是单击按钮转到某个按钮后的第一步)例如新页面)