🎈 조건문 사용 시 주의사항
플레이라이트에서 boundingBox 함수는 요소의 좌표와 사이즈를 반환해준다. 이는 화면에 그려진 후 측정가능하기 때문에 await을 사용해야 한다.
await page.locator('div').boundingBox();
boundingBox의 반환값을 보면 다음과 같다. 요소가 화면에 보이지 않는 경우 null을 반환하게 된다.
Promise<null | {
x: number;
y: number;
width: number;
height: number;
}>
이를 사용해서, 만약 width의 값이 1000이하 인지를 테스트해야한다고 해보자. boundingBox가 null일 수 있기 때문에 아래와 같이 조건문을 통해서 검증을 진행하도록 작성하였다.
test('bounding box', async ({ page }) => {
await page.goto('http://127.0.0.1:5500/index.html');
const boundingBox = await page.locator('div').boundingBox();
if (boundingBox) {
expect(boundingBox.width).toBeLessThanOrEqual(1000);
}
});
하지만 이렇게 테스트 코드를 작성하게 되면 문제가 발생한다. 해당 테스트 케이스가 검증로직을 수행하지 않고 통과할 수 있기 때문이다.
아래와 같이 div는 존재하지만 화면에 그려지지 않은 경우에는 검증 로직을 수행하지 않게 된다.
<div style="display: none;"></div>
만약 화면에 보이는 경우에만 테스트한다면 해당 테스트 코드는 어느정도 정상이라고 할 수 있다. 하지만 반드시 화면에 그려져야 하는 대상인 경우에는 이는 잘못 작성 된 테스트 코드라고 할 수 있다.
그래서 boundingBox가 존재하지 않는 경우 테스트에 실패하도록 하는 코드가 필요하다.
아래와 같이 boundingBox가 존재하지 않는 경우 test.fail 을 활용해서 테스트에 실패하도록 만들 수 있다.
test('bounding box', async ({ page }) => {
await page.goto('http://127.0.0.1:5500/index.html');
const boundingBox = await page.locator('div').boundingBox();
if (boundingBox) {
expect(boundingBox.width).toBeLessThanOrEqual(1000);
return;
}
test.fail(true, 'Bounding box is null');
});
✨ if문을 사용하는 경우에는 else 부분까지 고려해서 테스트 코드를 작성해야한다.
📯 반복문 사용 시 주의 사항
Locator의 대상이 하나가 아닌 여러 대상을 통해서 검증하는 코드를 작성해야 하는 경우가 종종 있다.
예를 들어, 각 리스트의 width가 100인지를 테스트 한다고 하자.
html은 다음과 같다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
li {
width: 100px;
}
</style>
<title>Document</title>
</head>
<body>
<ul>
<li>리스트1</li>
<li>리스트2</li>
<li>리스트3</li>
<li>리스트4</li>
</ul>
</body>
</html>
텍스트를 검증하는 경우에는 아래와 같이 toHaveText를 통해 간단하게 처리할 수 있다.
test('list', async ({ page }) => {
await page.goto('http://127.0.0.1:5500/index.html');
const text = Array(4).fill(0).map((_, i) => `리스트${i + 1}`);
await expect(page.getByRole('listitem')).toHaveText(text);
});
하지만 width를 검증하는 경우에는 개별 리스트에 반복문을 통해 하나하나 검증해주어야 한다. 이때 all을 사용하면 대상이 되는 모든 Locator를 배열로 반환발을 수 있다.
all을 사용하는 경우에는 아래와 같이 await을 사용해야한다. 왜냐하면 실제 화면에 그려진 대상을 가져와야하기 때문이다.
await page.getByRole('listitem').all();
테스트 코드를 작성하면 다음과 같다. 실행해보면 정상적으로 통과하는 것을 볼 수 있다.
test('list', async ({ page }) => {
await page.goto('http://127.0.0.1:5500/index.html');
const all = await page.getByRole('listitem').all();
for (const listItem of all) {
await expect(listItem).toHaveCSS('width', '100px');
}
});
하지만 여기에도 문제가 존재한다. 바로 all로 반환받은 배열에 아무런 아이템이 존재하지 않는 경우이다.
HTML 코드에서 스타일만 아래와 같이 변경 후 테스트를 다시 실행해보자. 이때도 정상적으로 통과하는 것을 확인할 수 있다.
<style>
li {
width: 500px;
display: none;
}
</style>
page.getByRole('listitem') 는 visible이 false인 경우를 제외하고 대상을 찾게 된다. 이러한 특성 때문에 all 함수를 호출하면 빈 배열이 반환되게 된다.
그래서 아래와 같이 배열에 원하는 만큼의 아이템이 존재하지 않는 경우에 대해서 처리하는 코드가 존재해야 해당 테스트 케이스에 대한 신뢰도가 올라가게 된다.
test.fail(all.length < 4, 'Less than 4 list items found');
모든 반복문에 대해서 위와 같은 처리가 필요한게 아니다. 아래와 같이 테스트할 대상을 배열에 직접 테스트 코드로 작성하는 경우에는 반복문 호출이 자연스럽게 암시되므로 위의 코드를 추가하지 않아도 된다.
const list = ['리스트1', '리스트2', '리스트3', '리스트4'];
for (const item of list) {
await expect(page.getByText(item)).toHaveCSS('width', '100px');
}
'테스트 > Playwright' 카테고리의 다른 글
[Playwright] 클립 보드 허용 (0) | 2025.04.06 |
---|---|
[Playwright] 드래그 앤 드랍 (0) | 2025.03.24 |
[Playwright] 스텝 사용하기 (0) | 2025.03.02 |
[Playwright] Select 테스트 (0) | 2025.03.01 |
[Playwright] Locator의 메서드 (0) | 2025.02.08 |