我正在使用 Ruby、Cucumber、Capybara 和 SitePrism 启动一个新的自动化测试项目。这是一个定义干净且易于维护的架构的机会。 然而,已经存在一个挑战,我没有找到任何优雅的解决方案,它正在测试异步行为。
我必须测试的众多异步行为之一是电子邮件发送,销售完成后,系统向买家发送电子邮件,我需要测试电子邮件是否正确发送,但是,电子邮件发送不正确立即,它被放入队列中,并且需要一些时间来执行(大约1-3分钟)。
系统使用一个工具在测试环境中将发送的电子邮件存储在数据库中。我正在访问该数据库,搜索电子邮件主题并断言收件人。
场景定义如下所示:
Scenario: Send sale email
Given I'm logged in as "send_sale_email"
When I make a sale
Then the system should send a sale confirmation email
并且,关于步骤定义:
Then "the system should send a sale confirmation email" do
buyer_email = '[email protected]'
email_subject = "Sale confirmation #{@sale_number}"
email_recipients = get_email_recipients(email_subject)
expect email_recipients.to include(buyer_email)
end
但是当销售完成并且测试访问数据库时,电子邮件尚未发送,并且无法保证何时发送。我做了一个时不时重试的方法,它有效:
Then "the system should send a sale confirmation email" do
buyer_email = '[email protected]'
email_subject = "Sale confirmation #{@sale_number}"
sleep_time = 30
max_retries = 6
retry_count = 0
begin
email_recipients = get_sent_email_recipients(email_subject)
expect(email_recipients).to include(buyer_email)
rescue RSpec::Expectations::ExpectationNotMetError => e
if retry_count <= max_retries
retry_count += 1
sleep sleep_time
retry
end
raise e
end
end
这样就等待了3分钟左右,但是在测试中加入睡眠看起来不太好,而且系统中有多种这样的操作,有些可能需要重新加载页面并搜索一些东西。我知道我可以分离重试逻辑以供重用,但随着时间的推移,它会成为维护噩梦吗?有没有更精细的方法来测试异步行为?
我会做以下事情:
expect().to receive().with()
测试异步任务在创建时是否实际执行应该单独完成。在这些测试中,您可能需要使用
sleep
它将让您进行干净、快速的功能测试