모범 사례
이 가이드는 성능이 좋고 안정적인 테스트를 작성하는 데 도움이 되는 모범 사례를 공유하는 것을 목표로 합니다.
안정적인 선택자 사용하기
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')
체이닝을 사용해야 하는 유일한 경우는 다른 선택자 전략을 결합하고 싶을 때입니다. 이 예제에서는 요소의 섀도우 DOM 내부로 들어가는 전략인 Deep Selectors를 사용합니다.
// 👍
await $('custom-datepicker').$('#calendar').$('aria/Select')
목록에서 하나를 선택하기보다 단일 요소를 찾는 것이 좋습니다
항상 가능한 것은 아니지만 :nth-child와 같은 CSS 의사 클래스를 사용하여 부모의 자식 목록에서 요소의 인덱스를 기반으로 요소를 일치시킬 수 있습니다.
모든 테이블 행을 쿼리합니다.
// 👎
await $$('table tr')[15]
단일 테이블 행만 쿼리합니다.
// 👍
await $('table tr:nth-child(15)')
내장 어설션 사용하기
결과가 일치할 때까지 자동으로 기다리지 않는 수동 어설션은 불안정한 테스트를 유발하므로 사용하지 마세요.
// 👎
expect(await button.isDisplayed()).toBe(true)
내장 어설션을 사용하면 WebdriverIO는 실제 결과가 예상 결과와 일치할 때까지 자동으로 기다려 안정적인 테스트를 만듭니다. 이는 어설션이 통과하거나 시간 초과될 때까지 자동으로 재시도함으로써 달성됩니다.
// 👍
await expect(button).toBeDisplayed()
지연 로딩 및 프로미스 체이닝
WebdriverIO는 깔끔한 코드 작성에 있어 몇 가지 비법이 있습니다. 요소를 지연 로딩하여 프로미스를 체이닝하고 await의 수를 줄일 수 있습니다. 이를 통해 요소를 Element 대신 ChainablePromiseElement로 전달할 수 있으며 페이지 객체와 함께 더 쉽게 사용할 수 있습니다.
그렇다면 언제 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()