Cypress 是一个基于 JavaScript 的 End to End 测试框架,它易于使用,且具有高度自动化测试能力,特别适合前端工程师使用。但是,在使用 Cypress 进行测试的过程中,有时会遇到一些报错。本文将会探讨 Cypress 常见的错误以及解决方案,也会介绍一些优化技巧和最佳实践。
报错解决方案
1. Command timed out after 30000ms
这个错误通常是由于网络问题引起的,Cypress 默认在 30 秒之内没有完成执行就会报超时错误。可以通过在 cypress.json 文件中修改 defaultCommandTimeout 来解决这个问题,如下所示:
{ "defaultCommandTimeout": 60000 }
2. Cypress detected that a command made a cross-origin request
这个错误通常是由于在测试过程中跨域请求引起的,Cypress 是基于 Electron 构建的,在 Electron 中,Cypress 禁止了跨域请求。可以使用 cy.request 命令代替 cy.visit 命令,或者在测试环境中使用代理工具,在代理的请求中添加跨域请求头信息。
3. Cannot read property 'click' of null
这个错误通常是由于在执行某个命令时元素不存在引起的。可以通过添加 { failOnStatusCode: false } 选项忽略错误,如下所示:
cy.get('.btn').click({ failOnStatusCode: false })
4. CypressError: Timed out retrying
这个错误通常是由于元素选择器不对引起的。可以通过在 Chrome DevTools Console 中使用 $ 命令来检查元素是否存在,然后更新选择器,如下所示:
cy.get('.new-btn').click() //选择器有问题 cy.get('.new-button').click() //更改选择器
5. Uncaught ReferenceError: XYZ is not defined
这个错误通常是由于变量未声明或未正确引用引起的。可以通过确保变量名正确、变量已声明、变量在正确的作用域中等操作来解决这个问题。
6. Uncaught (in promise) TypeError: Cannot read property 'value' of undefined
这个错误通常是由于尝试访问或操作空值或未定义变量引起的。可以通过添加 { force: true } 选项来解决这个问题,如下所示:
cy.get('.input').invoke('val', 'test', { force: true }).should('have.value', 'test')
优化技巧
1. 使用自定义命令
Cypress 允许你创建一个自定义命令来处理在测试代码中复杂或者重复的操作。可以在 Cypress.Commands.add() 方法中声明自定义命令,如下所示:
Cypress.Commands.add('login', (username, password) => { cy.get('#username').type(username) cy.get('#password').type(password) cy.get('#login-btn').click() })
2. 避免测试数据重复
在测试过程中,如果测试数据重复会降低测试质量和可靠性。可以通过使用 cypress-testing-library 或类似的工具来避免测试数据重复。
3. 在测试过程中添加等待
在测试时添加等待可以防止在执行某些命令时出现报错。可以使用 cy.wait() 命令来实现,如下所示:
cy.get('.input').type('test') cy.wait(1000) cy.get('.button').click()
4. 使用 cy.wrap() 命令
cy.wrap() 命令可以让你链式调用多个 Cypress 命令,如下所示:
cy.wrap({ name: 'John Doe' }) .should('have.property', 'name', 'John Doe') .then(obj => { obj.name = 'Jane Doe' return obj }) .should('have.property', 'name', 'Jane Doe')
5. 在 beforeEach 和 afterEach 中重置测试环境
重置测试环境可以确保每个测试用例之间是独立的,不会相互影响。可以在 beforeEach 和 afterEach 钩子函数中实现,如下所示:
beforeEach(() => { cy.visit('/') }) afterEach(() => { cy.clearCookies() })
最佳实践
以下是一些使用 Cypress 时的最佳实践:
1. 使用 .find()
方法选择元素
在选择元素时,使用 .find() 方法可以使元素选择器更易于理解和维护,如下所示:
cy.get('.parent-element') .find('.child-element') .should('have.text', 'Test')
2. 使用 cy.tick()
模拟时间
在测试需要模拟时间的场景下,可以使用 cy.tick() 方法来模拟时间流逝,如下所示:
cy.clock().then(clock => { cy.get('.element').click() clock.tick(1000) cy.get('.element').should('have.class', 'active') })
3. 限制测试代码长度
限制测试代码长度可以使代码更易于维护和理解,也可以降低出错的可能性。可以使用 ES2015+ 中的模板字符串来组织测试代码,如下所示:
-- -------------------- ---- ------- ----- -------- - ---------- ----- -------- - -------------- ----------------- -- -- - ---------- --- --- ---- ---- -- -- - ------------------ ---------------------------------- ---------------------------------- ---------------------------- -------------------------- ------------- -- --
结论
Cypress 是一个强大且易于使用的 End to End 测试框架。本文介绍了 Cypress 的常见报错以及解决方案,同时分享了一些优化技巧和最佳实践。希望这些技巧和实践对您的测试工程师工作有所帮助。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/66f3c697f40ec5a964e4ce00