等待服务 return 赛普拉斯测试中的非空响应

wait for service to return a non-empty response in Cypress test

在我的 Cypress 测试套件中,我有一个命令 API 调用电子邮件服务以查找具有特定主题的电子邮件和 return 电子邮件的内容。

Cypress.Commands.add('getMostRecentEmail', subject => {
  const requestUrl = new URL('api/mails', 'localhost')
  requestUrl.port = '3000'
  requestUrl.searchParams.append('subject', subject)

  // TODO: wait for the following request to return a non-empty response.body

  return cy.request('GET', requestUrl.toString()).then(response => {
    return response.body[0].content[0].value
  })
})

当我在本地 运行 测试时,这工作正常,但是当 运行 在 CI 上测试时,它第一次失败,但当 Cypress 自动重试测试时成功.据推测这是因为第一次尝试检索电子邮件时尚未收到电子邮件(电子邮件是在上述代码执行之前立即发送的)。

response.body 是服务return发送的匹配邮件数,第一次请求时,这个是空的,所以response.body[0]undefined.

Cypress 将此测试报告为“flakey”,因为它在第一次尝试时没有成功。

要解决此问题,我想在检索第一封电子邮件的内容之前等待 return 非空响应的请求。

为您的请求创建一个可以递归调用的函数:

function makeRequestRecursively() {
    cy.request('GET', requestUrl.toString()).then(response => {
        let value = response.body[0].content[0].value;
        if (response.body[0].content[0].value != undefined) {
            return value;
        }
        else {
            // Recursively call the function after 0.5 seconds. You can adjust or remove this.
            setTimeout(function (){
                return makeRequestRecursively();        
            }, 500);
        }
    }
}

替换:

return cy.request('GET', requestUrl.toString()).then(response => {
    return response.body[0].content[0].value
})

与:

return makeRequestRecursively()

看看 https://slides.com/bahmutov/email-testing presentation. In particular, the blog post https://www.cypress.io/blog/2021/05/24/full-testing-of-html-emails-using-ethereal-accounts/#retry-email-task 讨论如何重试接收电子邮件,因为它只能在未知时间后发生。