Лучшие практики
Этот руководство призвано поделиться нашими лучшими практиками, которые помогут вам писать производительные и устойчивые тесты.
Используйте устойчивые селекторы
Используя селекторы, устойчивые к изменениям в DOM, у вас будет меньше или даже не будет проваленных тестов, когда, например, класс будет удален из элемента.
Классы могут применяться к нескольким элементам, и их следует избегать, если возможно, если только вы намеренно не хотите получить все элементы с этим классом.
// 👎
await $('.button')
Все эти селекторы должны возвращать один элемент.
// 👍
await $('aria/Submit')
await $('[test-id="submit-button"]')
await $('#submit-button')
Примечание: Чтобы узнать обо всех возможных селекторах, которые поддерживает WebdriverIO, посмотрите нашу страницу Selectors.
Ограничьте количество запросов элементов
Каждый раз, когда вы используете команду $
или $$
(включая их цепочки), 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()
Ленивая загрузка и цепочка обещаний
У WebdriverIO есть несколько трюков для написания чистого кода, поскольку он может лениво загружать элемент, что позволяет вам создавать цепочки обещаний и уменьшать количество 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')
Динамические тесты
Используйте переменные окружения для хранения динамических тестовых данных, например, секретных учетных данных, в вашей среде, а не жестко кодируйте их в тесте. Перейдите на страницу Parameterize Tests для получения дополнительной информации по этой теме.