본문 바로가기
테스트/Playwright

[Playwright] 조건문, 반복문 사용 시 주의사항

by 맨날개발 2025. 3. 30.

🎈 조건문 사용 시 주의사항

플레이라이트에서 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