如何使用 Cypress Cucumber 预处理器实现对单个测试的重试?
How to achieve retries for individual tests using Cypress Cucumber Preprocessor?
我目前面临的挑战是实现单独的测试重试,以稳定一小组特定的测试,这些测试依赖于某些后台处理,因此往往不稳定。我将 Cypress 9.2.0 与 TypeScript 和 Cypress Cucumber Preprocessor 4.3.1 一起使用。
为了提供更多细节,应用程序接收在后台处理的事件(通常最多需要 1-2 秒),然后创建数据记录。然后这些记录显示在UI中的table.
在某些 Cucumber 场景中,我对这些情况进行了端到端的测试。由于处理有时需要更长的时间,我想预防性地包括仅适用于这些测试用例的重试,更具体地说是检查 table.[=12 中最终显示的场景的“Then”步骤=]
由于不幸的是,像标准 Cypress 测试中的单独测试重试不适用于 Cucumber 预处理器,并且 cypress.json
中的全局测试重试也有问题,我想知道是否有另一种方法可以实现这一点?
正常赛普拉斯测试重试的文档:https://docs.cypress.io/guides/guides/test-retries
我找到了解决我的问题的方法,尽管一般来说这个解决方案可能并不完全理想。但首先,我还想提一下我之前尝试过但对我不起作用的方法:
Individual Test Retries 遗憾的是,在使用 Cypress Cucumber 预处理器时无法使用特定测试步骤。
Global Test Retries 不幸的是,问题中已经提到了与 Cucumber 预处理器有关的错误。
我尝试过的另一种方法是使用 cy.should() with a callback 但也没有成功。
第四种方法基于conditional testing and finally the one that brought me to the following solution, also considering the thoughts from this post如何在元素不可用时不中断赛普拉斯测试:
Then('the results related to some search keyword {string} are shown in the table', (search: string) => {
checkTableWithRetries(search, 2);
});
function checkTableWithRetries(searchCriteria: string, retries: number) {
cy.get('table').then(($table) => {
if (checkIfTableRowExists($table) || retries === 0) {
cy.get('table').find('tbody').contains('td', searchCriteria);
} else {
const time = retries === 1 ? 10000 : 5000;
cy.wait(time);
search(searchCriteria);
checkTableWithRetries(searchCriteria, retries - 1);
}
});
}
function checkIfTableRowExists(element: JQuery<HTMLTableElement>) {
return element.find('tbody').find('tr').length === 1;
}
function search(search: string) {
cy.getByTestId('search-input').clear().type(`${search}`).should('have.value', `${search}`);
cy.intercept('GET', `/api/endpoint**`).as('search');
cy.getByTestId('search-button').click();
cy.wait('@search');
}
如果一个元素被创建并显示在 table 中,代码确保我可以连续多次检查不同的延迟。如果重复x次后元素仍然不存在,则可以认为确实有错误。
澄清一下,使用的函数 cy.getByTestId()
不是标准的 Cypress 命令,而是根据官方最佳实践部分 here.
中的建议作为自定义命令添加的
Cypress.Commands.add('getByTestId', (selector, ...options) => {
return cy.get(`[data-test=${selector}]`, ...options);
});
我目前面临的挑战是实现单独的测试重试,以稳定一小组特定的测试,这些测试依赖于某些后台处理,因此往往不稳定。我将 Cypress 9.2.0 与 TypeScript 和 Cypress Cucumber Preprocessor 4.3.1 一起使用。
为了提供更多细节,应用程序接收在后台处理的事件(通常最多需要 1-2 秒),然后创建数据记录。然后这些记录显示在UI中的table.
在某些 Cucumber 场景中,我对这些情况进行了端到端的测试。由于处理有时需要更长的时间,我想预防性地包括仅适用于这些测试用例的重试,更具体地说是检查 table.[=12 中最终显示的场景的“Then”步骤=]
由于不幸的是,像标准 Cypress 测试中的单独测试重试不适用于 Cucumber 预处理器,并且 cypress.json
中的全局测试重试也有问题,我想知道是否有另一种方法可以实现这一点?
正常赛普拉斯测试重试的文档:https://docs.cypress.io/guides/guides/test-retries
我找到了解决我的问题的方法,尽管一般来说这个解决方案可能并不完全理想。但首先,我还想提一下我之前尝试过但对我不起作用的方法:
Individual Test Retries 遗憾的是,在使用 Cypress Cucumber 预处理器时无法使用特定测试步骤。
Global Test Retries 不幸的是,问题中已经提到了与 Cucumber 预处理器有关的错误。
我尝试过的另一种方法是使用 cy.should() with a callback 但也没有成功。
第四种方法基于conditional testing and finally the one that brought me to the following solution, also considering the thoughts from this post如何在元素不可用时不中断赛普拉斯测试:
Then('the results related to some search keyword {string} are shown in the table', (search: string) => {
checkTableWithRetries(search, 2);
});
function checkTableWithRetries(searchCriteria: string, retries: number) {
cy.get('table').then(($table) => {
if (checkIfTableRowExists($table) || retries === 0) {
cy.get('table').find('tbody').contains('td', searchCriteria);
} else {
const time = retries === 1 ? 10000 : 5000;
cy.wait(time);
search(searchCriteria);
checkTableWithRetries(searchCriteria, retries - 1);
}
});
}
function checkIfTableRowExists(element: JQuery<HTMLTableElement>) {
return element.find('tbody').find('tr').length === 1;
}
function search(search: string) {
cy.getByTestId('search-input').clear().type(`${search}`).should('have.value', `${search}`);
cy.intercept('GET', `/api/endpoint**`).as('search');
cy.getByTestId('search-button').click();
cy.wait('@search');
}
如果一个元素被创建并显示在 table 中,代码确保我可以连续多次检查不同的延迟。如果重复x次后元素仍然不存在,则可以认为确实有错误。
澄清一下,使用的函数 cy.getByTestId()
不是标准的 Cypress 命令,而是根据官方最佳实践部分 here.
Cypress.Commands.add('getByTestId', (selector, ...options) => {
return cy.get(`[data-test=${selector}]`, ...options);
});