2016-02-05 162 views
0

我有一个问题,我试图解决网页上的某个警报是否正确计算总和。我正在使用水豚和黄瓜。在Ruby中计算天数

我有一个计算在30天内到期的记录的警报。当选择此提醒时,记录被列在一张表格中,并且日期以以下格式显示:“1 feb 2016”

我想要做的是以某种方式取今天的日期,将它与在并确保它距离警报日期大于等于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

如果任何人都可以想到的更合适的方法来做到这一点,请把我从我的痛苦。

感谢

+0

'first_30day_mot'是最有可能的字符串。可能是'to_i'会帮助 –

+0

我尝试过,但同样的错误出现了。 – Tom

+0

每当您尝试将整数添加到字符串或任何类似的操作时,都会出现该错误。您可以通过检查报告错误的行号处的值来调试代码。 –

回答

1

你的尝试至少有两件事情是错误的。

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

  2. #first返回页面不是元素

的它不是100%清楚你的代码的内容你要什么样的元素但是从测试命名我想你只是想确保给定行的第三个td单元格(它是2016年1月2日格式)中的日期距离现在还不到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,这会给你带来Capybaras等待行为的好处。如果你实际上需要#first,你可以考虑通过minimum: 1选项来确保它等待匹配元素出现在页面上(如果这是单击按钮进入新页面后的第一步,例如)

+0

谢谢,这正在做我所需要的。我对此很新,所以我对代码感到困惑。 – Tom

0

转换selection1字符串明确(或更好,使用字符串插值):

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

而且,我怀疑它下面一行应转换为整数,将其添加到today

first_30day_mot.to_i <= 30 

UPD OK,我终于有时间采取一个更彻底的样子。你不需要所有这些巫术魔法与微积分:

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

希望它有帮助。

+0

我没有太多的运气。你认为,捕获xpath/css中的文本,然后使用Date.strptime将其转换为int会更好吗?另外改变今天的输出为int – Tom

+0

请看更新,我再看一眼代码。 – mudasobwa

0

我强烈建议不要使用黄瓜做这样的测试。你会发现它的:

  1. 挺难设立
  2. 具有较高的运行成本
  3. 不给予足够的利益来证明安装/运行成本

而是考虑写对提供日期的事物进行单元测试。一般来说,好的单元测试可以比场景轻松运行10到100倍。

虽然有一个情况下,您将不会遇到那么多的痛苦,一旦你有很多像这样的痛苦会积累场景。部分使用Cucumber的艺术是为您写的每个场景获得充足的音乐。