POM?
Playwright에서 제공하는 POM(Page Object Model) 개념은, 테스트 코드 작성의 용이성 및 유지 보수 관리를 최적화하면서 테스트 케이스를 작성할 수 있는 접근 방식중의 하나이다. class를 사용함으로써 중복을 줄이고 장황한 테스트 코드의 추상화를 통해 유지 관리를 단순화한다.
How?
Init
// playwright.dev 기준 작성
import { Locator, Page, expect } from '@playwright/test';
export class InitPage {
readonly page: Page;
private getStartedLocator: Locator;
constructor({ page }: { page: Page }) {
this.page = page;
this.getStartedLocator = page.getByRole('heading', {
name: 'Playwright enables reliable end-to-end testing for modern web apps.',
});
}
async goto(link: string) {
await this.page.goto(link);
}
async initializeToMainPage() {
await this.goto('https://playwright.dev/');
await expect(this.getStartedLocator).toBeVisible();
}
}
- 위와 같이, 테스트를 하고자 하는 페이지 인스턴스를 생성하는 클래스를 작성함으로써 캡슐화가 가능하다.
import { test, expect } from '@playwright/test';
import { InitPage } from './common/InitPage';
// before
test('test with normal test code', async ({ page }) => {
const getStartedLocator = await page.getByRole('heading', {
name: 'Playwright enables reliable end-to-end testing for modern web apps.',
});
await page.goto('https://playwright.dev/');
await expect(getStartedLocator).toBeVisible();
});
// after
test('go to main page', async ({ page }) => {
const testPage = new InitPage({ page });
await testPage.initializeToMainPage();
});
- POM을 적용한 이후의 코드가 가독성 및 유지 보수의 용이성의 측면에서 좋아졌다. 또한 테스트 케이스별 개별적인 인스턴스를 생성하기 때문에 테스트 케이스간의 의존성을 낮출 수 있었다.
Extends
import { Page, Locator, expect } from '@playwright/test';
import { InitPage } from './InitPage';
export class PageObjectModelPage extends InitPage {
private pageObjectModelPageLocator: Locator;
constructor({ page }: { page: Page }) {
super({ page });
this.pageObjectModelPageLocator = page.getByRole('heading', {
name: 'Page object models',
});
}
async initPageObjectModelPage() {
await super.initializeToMainPage();
await this.page.getByLabel('Search').click();
await this.page.getByPlaceholder('Search docs').fill('page object');
await this.page
.getByRole('link', { name: 'Page object models', exact: true })
.click();
await expect(this.pageObjectModelPageLocator).toBeVisible();
}
}
- 테스트 케이스별, 기본적으로 필요한 메서드의 중복이 지속될 경우 상속으로 이를 개선할 수 있다.
import { test, expect } from '@playwright/test';
import { PageObjectModelPage } from './common/PageObjectModelPage';
// before
test('test with normal test code', async ({ page }) => {
// InitPage 클래스에서 사용되던 locator
const getStartedLocator = await page.getByRole('heading', {
name: 'Playwright enables reliable end-to-end testing for modern web apps.',
});
await page.goto('https://playwright.dev/');
await expect(getStartedLocator).toBeVisible();
await page.getByLabel('Search').click();
await page.getByPlaceholder('Search docs').fill('page object');
await page
.getByRole('link', { name: 'Page object models', exact: true })
.click();
});
// after
test('go to page object models page', async ({ page }) => {
const pageObjectModelPage = new PageObjectModelPage({ page });
await pageObjectModelPage.initPageObjectModelPage();
});
- 11번가의 Tech Talk을 통해 처음 접했을 때와 달리 직접 사용해보니, 사용 경험이 매우 만족스러움을 느꼈다.
Reference
'Etc' 카테고리의 다른 글
Copy right 자동 생성용 플러그인 만들기 (Webpack) (1) | 2024.09.18 |
---|---|
소스맵 정리 (0) | 2023.09.28 |
TTF, OTF 폰트별 특징 (0) | 2023.07.28 |
리액트와 함께하는 테스트 격리(번역) (0) | 2023.04.17 |
TIL | Reflow, Repaint (0) | 2022.08.28 |