最佳实践
本指南旨在分享我们的最佳实践,帮助您编写高性能和稳健的测试。
使用稳健的选择器
使用对DOM变化具有弹性的选择器,当例如某个元素的类被移除时,您将减少甚至不会有测试失败的情况。
类可以应用于多个元素,如果可能的话应该避免使用,除非您故意想要获取具有该类的所有元素。
// 👎
await $('.button')
所有这些选择器都应该返回单个元素。
// 👍
await $('aria/Submit')
await $('[test-id="submit-button"]')
await $('#submit-button')
注意: 要了解WebdriverIO支持的所有可能的选择器,请查看我们的选择器页面。
限制元素查询的数量
每次使用$或$$命令(包括链式调用)时,WebdriverIO都会尝试在DOM中定位元素。这些查询成本很高,所以您应该尽量限制它们的使用。
查询三个元素。
// 👎
await $('table').$('tr').$('td')
只查询一个元素。
// 👍
await $('table tr td')
唯一应该使用链式调用的时候是当您想要组合不同的选择器策略时。 在示例中,我们使用Deep Selectors,这是一种进入元素的shadow DOM的策略。
// 👍
await $('custom-datepicker').$('#calendar').$('aria/Select')
优先定位单个元素而不是从列表中取一个
这并不总是可行的,但使用CSS伪类如:nth-child,您可以根据父元素子列表中的索引匹配元素。
查询所有表格行。
// 👎
await $$('table tr')[15]
查询单个表格行。
// 👍
await $('table tr:nth-child(15)')
使用内置断言
不要使用不会自动等待结果匹配的手动断言,因为这会导致测试不稳定。
// 👎
expect(await button.isDisplayed()).toBe(true)
通过使用内置断言,WebdriverIO将自动等待实际结果与预期结果匹配,从而产生稳健的测试。 它通过自动重试断言直到通过或超时来实现这一点。
// 👍
await expect(button).toBeDisplayed()
懒加载和promise链
在编写干净代码方面,WebdriverIO有一些技巧,它可以懒加载元素,这允许您链式调用promises并减少await的使用量。这也允许您将元素作为ChainablePromiseElement而不是Element传递,并更容易与页面对象一起使用。
那么什么时候必须使用await呢?
您应该始终使用await,但$和$$命令除外。
// 👎
const div = await $('div')
const button = await div.$('button')
await button.click()
// 或
await (await (await $('div')).$('button')).click()
// 👍
const button = $('div').$('button')
await button.click()
// 或
await $('div').$('button').click()
不要过度使用命令和断言
当使用expect.toBeDisplayed时,您隐式地也等待元素存在。当您已经有一个执行相同操作的断言时,没有必要使用waitForXXX命令。
// 👎
await button.waitForExist()
await expect(button).toBeDisplayed()
// 👎
await button.waitForDisplayed()
await expect(button).toBeDisplayed()
// 👍
await expect(button).toBeDisplayed()
与元素交互或断言其文本等内容时,不需要等待元素存在或显示,除非元素可能明确不可见(例如opacity: 0)或明确禁用(例如disabled属性),在这种情况下等待元素显示是有意义的。
// 👎
await expect(button).toBeExisting()
await expect(button).toHaveText('Submit')
// 👎
await expect(button).toBeDisplayed()
await expect(button).toHaveText('Submit')
// 👎
await expect(button).toBeDisplayed()
await button.click()
// 👍
await button.click()
// 👍
await expect(button).toHaveText('Submit')
动态测试
使用环境变量在您的环境中存储动态测试数据,例如秘密凭据,而不是将它们硬编码到测试中。有关此主题的更多信息,请前往参数化测试页面。
对代码进行lint检查
使用eslint对代码进行lint检查,您可以在早期发现潜在的错误,使用我们的lint规则确保始终应用一些最佳实践。
不要暂停
使用pause命令可能很诱人,但这样做是个坏主意,因为它不具有弹性,从长远来看只会导致测试不稳定。
// 👎
await nameInput.setValue('Bob')
await browser.pause(200) // 等待提交按钮启用
await submitFormButton.click()
// 👍
await nameInput.setValue('Bob')
await submitFormButton.waitForEnabled()
await submitFormButton.click()