1. 패키지 설치
공식 문서에 따라 사용하는 패키지 매니저로 playwright를 설치해 준다.
npm init playwright@latest
npm을 사용할 경우 위와 같이 실행해 준다.
> create-playwright 패키지 설치 - Y
> TypeScript와 JavaScript 중 선택 - JavaScript
> E2E 테스트를 저장할 폴더 이름 지정 - src/tests
> GitHub Actions workflow에 추가 여부 - N
> Playwright browser 설치 여부 - Y
위와 같은 단계를 따라 설치하면 기본 config 파일과 샘플 테스트 코드가 같이 설치된다.
2. config 설정
playwright 설치 완료 후 생성된 playwright.config.js 파일을 수정해 준다.
2.1. baseURL 수정
use: {
/* Base URL to use in actions like `await page.goto('/')`. */
baseURL: 'http://localhost:5173',
...
},
위와 같이 use 설정 내의 baseURL 필드를 프로젝트의 base URL과 동일하게 수정한다.
2.2. (추가 예정)
(추가 예정)
3. 테스트 코드 작성
기본적인 설정이 완료되면 바로 테스트 코드를 작성하면 된다. 하지만 그전에 더 효율적인 테스트 코드 작성을 위하여 몇 가지 추가적인 설정을 더해준다.
3.1. Custom Routes 설정
기존의 src/router/index.js에서 각 path가 string 형태로 작성되어 있다면 불러오기 쉽도록 이를 변수화해 준다.
별도의 routes.js 파일을 생성하여 다음과 같은 형식으로 작성하여 적용한다.
const routes = {
login: '/login',
signup: '/signup',
findAuth: '/find-auth',
...
}
export default routes
3.2. Page Object Model(POM) 작성
테스트 시 반복되는 동작이나 로직을 캡슐화하여 페이지별로 생성한다.
예를 들어 로그인 페이지를 테스트한다면 ‘로그인 페이지로 이동’, ‘아이디와 비밀번호를 입력받아 로그인 버튼 클릭’, ‘로그인 실패 모달 노출 확인’ 등과 같은 로직을 정의하여 실제 테스트 코드에서 불러와 사용할 수 있다.
작성한 model들은 tests 폴더 아래의 models 폴더에 위치하도록 한다.
// src/tests/models/login.model.js
import routes from '@/router/routes'
export class LoginPage {
constructor(page) {
this.page = page
}
async navigate() {
await this.page.goto(routes.login)
}
async login(id, password) {
const idInput = this.page.getByTestId('login-id')
const passwordInput = this.page.getByTestId('login-pwd')
const loginButton = this.page.getByTestId('login-btn')
await idInput.fill(id)
await passwordInput.fill(password)
await loginButton.click()
}
}
3.3. test id 부여
테스트시에 페이지 요소를 선택하는 방법은 여러 가지이지만 그중에서 test id로 선택하는 방법을 사용한다.
선택하고자 하는 버튼 요소가 다음과 같을 때 직접 부여한 test id를 통해 요소를 불러와 클릭 등의 상호작용할 수 있다.
<button data-testid="login-btn">Login</button>
playwright에서 test id를 통해 요소를 가져올 때는 getByTestId()라는 메서드를 사용한다.
const loginButton = await page.getByTestId('login-btn')
await loginButton.click()
test id는 kebab case를 사용하고, 되도록 유일하도록 생성한다. 만약 같은 test id를 가진 요소가 여러 개 있다면 아래와 같은 메서드를 통해 명시적으로 하나만 불러오도록 한다.
const listItems = await page.getByTestId('my-list-item')
listItems.first()
listItems.last()
listItems.nth(3)
3.4. 테스트 코드 작성
테스트 코드는 각 페이지마다 하나의 파일을 생성하여 작성하고 tests 폴더 아래의 specs 폴더에 위치하도록 한다.
테스트 이름은 해당 테스트의 시나리오로 한다. 여러 개의 테스트 그룹에 공통되는 선행 동작이 필요하다면 beforeEach 메서드를 사용하여 적용한다.
위에서 작성한 로그인 페이지를 예시로 하면 다음과 같다.
// src/tests/specs/login.spec.js
import { test, expect } from '@playwright/test'
import { LoginPage } from '@/tests/models/login.model'
import routes from '@/router/routes'
test.describe('로그인', () => {
let loginPage
test.beforeEach(async ({ page }) => {
loginPage = new LoginPage(page)
await loginPage.navigate()
})
test('사용자 로그인 성공 후 홈 화면으로 이동', async ({ page }) => {
await loginPage.login('test001', 'test001!')
await page.waitForURL(routes.home)
const { pathname } = new URL(page.url())
expect(pathname).toBe(routes.home)
})
test('아이디 또는 비밀번호 틀릴시 로그인 실패 모달 노출', async () => {
await loginPage.login('test002', 'test002')
const hasModal = await loginPage.hasFailModal()
expect(hasModal).toBeTruthy()
})
})
4. 정리
위와 같은 방법으로 테스트 코드를 작성했을 때의 tests 폴더의 구조는 다음과 같다.
📦tests
┣ 📂models
┃ ┣ 📜login.model.js
┃ ┗ 📜signup.model.js
┣ 📂specs
┃ ┣ 📜login.spec.js
┃ ┗ 📜signup.spec.js
┗ 📂utils
┣ 📜hasInputTxt.js
┗ 📜hasModal.js
위에서 따로 언급은 하지 않았지만 모달 노출 확인, 에러 메시지 확인 등 여러 개의 model에서 공통적으로 사용하는 로직의 경우는 utils 폴더에 작성하여 사용한다.
참고:
[1] Fast and reliable end-to-end testing for modern web apps | Playwright
'FE' 카테고리의 다른 글
Vue 프로젝트에 Airbnb ESLint 적용하기 (0) | 2024.12.08 |
---|---|
[vue-i18n] 2. 번역 리소스 (0) | 2024.12.07 |
[vue-i18n] 1. 시작하기 (0) | 2024.12.07 |
국제화(i18n)와 지역화(L10n) (1) | 2024.12.07 |
TailwindCSS 설치 (0) | 2024.12.07 |