为了进行彻底的测试,我的服务(UI+后端)通过多个部署环境进行迁移:ex DEV、STAGE、DEMO 和 PROD。当该服务迁移这些测试环境时,其 UI 会等待来自后端的异步更新,这作为测试压力源可能会异常缓慢;因此,加快速度不是一种选择,也不是嘲笑响应。
UI 测试涉及等待异步更新响应以确定将专门呈现哪些 React 组件。这些 React 组件将是具有不可预测内容/文本的部分/div,因此不是一个选项。Cypress contains
处理缓慢异步更新的典型解决方案是使用固定延迟Cypress wait:一堆毫秒、十分之几秒,甚至几秒。然而,固定延迟越长,您的测试就越脆弱。
这是我的脆弱 Cypress 测试代码的示例:
cy.get('div.main')
.then( ($divMain) => {
cy.wait(5000) // wait 5 seconds
const boolStateA = $divMain.find('section.A').length > 0;
const boolStateB = $divMain.find('section.B').length > 0;
if (boolStateA( {
// Do ...
} else if ( boolStateB ) {
// Do something else ...
}
})
Run Code Online (Sandbox Code Playgroud)
然而,等待 5 秒后,并不能绝对确定其中一个组件是否实际渲染。如果两者均未呈现或均未呈现,则这是意外状态。
那么我怎样才能等待这些组件中的任何一个都不使用cy.wait()or进行渲染呢cy.contains?
谢谢
要等待<section class="A">or之一<section class="B">,请使用多个选择器。
Cypress 将等待第一个出现,您可以添加一个超时(因为 5 秒略高于默认超时)。
cy.get('div.main')
.find('section.A, section.B', {timeout:5_000})
.then($section => {
if ($section.hasClass("A") {
}
if ($section.hasClass("B") {
}
})
Run Code Online (Sandbox Code Playgroud)
另一个例子:Cypress 断言 A 或 B
cypress 的建议是让您的测试具有确定性。意思是,弄清楚如何确保您的产品在测试运行时始终处于已知状态。这通常是通过模拟、路由或向后端发送消息来提供(或可能获取)预定状态来完成。
内联超时可能比 cy.wait() 好一点,但这并不能解决您的未知状态问题。
cy.get('.mobile-nav', { timeout: 10000 })
.should('be.visible')
.and('contain', 'Home')
Run Code Online (Sandbox Code Playgroud)
或者,您可以更新应用程序以包含测试等待的隐藏完成状态。
例子:
<div data-cy="SectionLoaded">SectionA</div>
Run Code Online (Sandbox Code Playgroud)
通过这种方式,测试只需要等待一件事,它就会一直在那里。您的测试可以有一个条件,该条件获取该元素的 .text() 然后对其进行操作。如果您想单击其中一个,则可能看起来像这样。
cy.get('[data-cy=SectionLoaded]', { timeout: 10000 }).then(($loadedSection) => {
cy.get(`[data-cy=${$loadedSection.text()}]`).click()
Run Code Online (Sandbox Code Playgroud)
cypress.io 提供了更多相关信息,包括其他最佳实践和解决方法:
@GrayDwarf:谢谢您的回复
我确实用过赛普拉斯contains
cy.get('div[data-cy="sales_listing_section"]')
.contains(
'h1.header-title[data-cy="sale_items_header"]',
'Items for Sale',
{timeout: 10000}
)
.then(() => {
Run Code Online (Sandbox Code Playgroud)
cy.get('div.main-content')
.then(($sectionBody) => {
// @ts-ignore
cy.waitUntil(() => {
return ($sectionBody.find('div[data-cy="sales_listing_section"]').length > 0)
}, {
errorMsg: `ERROR: Sales section has not loaded.`,
timeout: 10000, // waits up to 10000 ms, default to 5000
interval: 500, // performs the check every 500 ms, default to 200
verbose: true,
customCheckMessage: `CHECK: If Sales section has loaded`
})
.then(() => {
cy.log('Sales section', 'Loading finished');
})
})
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
23055 次 |
| 最近记录: |