0058. Playwright를 활용한 종단 테스트 맛보기
리액트 테스팅에 대한 장정을 마무리하는 주제는 종단(End to End) 테스트입니다. 리액트 애플리케이션에서 컴포넌트 단위 테스트(Vitest+React Testing Library)와 통합 테스트를 잘 구성했다 하더라도, 실제 사용자가 접속해 브라우저 상에서 여러 페이지를 오가며 작업하는 시나리오 전반을 검증하고자 할 때는 종단(End-to-End) 테스트가 유용합니다. 종단 테스트는 애플리케이션의 전 과정을 통째로 체험하는 관점에서 진행되므로, 사용자 경험과 가장 유사한 형태로 기능 동작을 점검할 수 있습니다.
푸딩캠프 이야기
토이스토리 2기에 풀스택으로 개발팀이 구성되고 있습니다!
때깔 좋은 프로젝트는 PM, 디자이너, 개발자가 함께 모여 각자의 실력을 발휘하여 만들어집니다. 또한 서로 다른 관점을 가진 직군이 협업했을 때 다양성 측면에서 밀도있는 만듦새 좋은 프로젝트를 만들 수 있습니다.
나만의 포트폴리오로써 토이 프로젝트를 개발하는 푸딩캠프의 프로그램인 토이스토리의 2기는 풀스택으로 팀 빌딩을 하고 있습니다. 풀스택 개발팀에 참여해 토이 프로젝트를 출시해 운영해보세요. 그냥 프로젝트도 아닌 결제 시스템까지 연동한 프로젝트를 만들어보세요!
팀에 합류하기
Playwright를 활용한 종단 테스트 맛보기
리액트 테스팅에 대한 장정을 마무리하는 주제는 종단(End to End) 테스트입니다. 리액트 애플리케이션에서 컴포넌트 단위 테스트(Vitest+React Testing Library)와 통합 테스트를 잘 구성했다 하더라도, 실제 사용자가 접속해 브라우저 상에서 여러 페이지를 오가며 작업하는 시나리오 전반을 검증하고자 할 때는 종단(End-to-End) 테스트가 유용합니다. 종단 테스트는 애플리케이션의 전 과정을 통째로 체험하는 관점에서 진행되므로, 사용자 경험과 가장 유사한 형태로 기능 동작을 점검할 수 있습니다.
(1) 종단 테스트란?
1) 종단 테스트 개념과 장점
종단 테스트란, 단어 그대로 끝단에서 끝단까지 전체 애플리케이션 흐름을 확인하는 테스트입니다. 컴포넌트 단위 테스트나 통합 테스트에서는 실제 브라우저 환경이나 네트워크 요청 과정을 완벽히 재현하기 어려운 경우가 많은데, 종단 테스트는 실제 브라우저를 띄우거나 헤드리스(화면 없이 동작하는) 모드로 브라우저를 제어하여, 사람이 직접 클릭하고 입력하는 과정을 자동화하는 식으로 시나리오를 검증합니다.
종단 테스트의 가장 큰 장점은 사용자 경험과 최대한 가까운 방식으로 애플리케이션을 시험한다는 점입니다. UI 요소가 제대로 보이는지, 라우팅이 잘 작동하는지, 특정 버튼을 클릭했을 때 페이지가 원하는 대로 이동하는지 등 광범위한 영역을 한 번에 확인할 수 있습니다. 반면, 상대적으로 테스트 실행 시간이 길어지고, 테스트가 실패했을 때 어떤 부분이 문제인지 빠르게 파악하기가 어려운 경우도 생깁니다. 따라서 대규모 프로젝트에서는 단위 테스트와 통합 테스트로 작은 단위의 기능을 탄탄히 검증하고, 종단 테스트로 최종 사용자 시나리오를 점검하는 식으로 구분하여 운영하는 편이 효율적입니다.
2) Playwright
우리가 사용할 도구는 Playwright로, Microsoft에서 개발한 오픈소스 웹 테스트 및 자동화 라이브러리입니다. 다음은 주요한 특징입니다.
크로스 브라우저 지원하나의 API로 Chromium, Firefox, WebKit을 포함한 모든 최신 렌더링 엔진을 테스트할 수 있습니다.Windows, Linux, MacOS에서 테스트가 가능하며, 모바일 웹 테스트도 지원합니다.Windows, Linux, MacOS에서 테스트가 가능하며, 모바일 웹 테스트도 지원합니다.하나의 API로 Chromium, Firefox, WebKit을 포함한 모든 최신 렌더링 엔진을 테스트할 수 있습니다.자동화 기능요소가 실행 가능할 때까지 자동으로 기다리는 auto-waiting 기능을 제공합니다.동적 웹 환경에 최적화되어 있어, 필요한 조건이 충족될 때까지 검사를 자동으로 재시도합니다.동적 웹 환경에 최적화되어 있어, 필요한 조건이 충족될 때까지 검사를 자동으로 재시도합니다.요소가 실행 가능할 때까지 자동으로 기다리는 auto-waiting 기능을 제공합니다.테스트 환경각 테스트는 독립된 브라우저 컨텍스트에서 실행되어 완전히 격리된 환경을 제공합니다.인증 상태를 컨텍스트에 저장하여 반복적인 로그인 작업을 줄일 수 있습니다.인증 상태를 컨텍스트에 저장하여 반복적인 로그인 작업을 줄일 수 있습니다.각 테스트는 독립된 브라우저 컨텍스트에서 실행되어 완전히 격리된 환경을 제공합니다.개발자 도구Codegen, Playwright Inspector, Trace Viewer 등 다양한 개발 도구를 제공합니다.Visual Studio Code용 플러그인을 통해 편리한 실행과 디버깅이 가능합니다.Visual Studio Code용 플러그인을 통해 편리한 실행과 디버깅이 가능합니다.Codegen, Playwright Inspector, Trace Viewer 등 다양한 개발 도구를 제공합니다.성능빠른 테스트 속도로 유명하며, 병렬 테스트 실행을 지원합니다.빠른 테스트 속도로 유명하며, 병렬 테스트 실행을 지원합니다.
(2) Playwright 기본 사용법과 설정
Playwright를 사용하기 위해서는 먼저 프로젝트에 Playwright 패키지를 설치해야 합니다. 예를 들어 아래처럼 명령어를 통해 Playwright 및 관련 종속성을 설치합니다.
pnpm install -D playwright/test
Playwright는 자체적으로 테스트 러너 기능을 제공하므로, 별도의 테스트 러너(Jest, Vitest 등)와 병행하지 않고도 단독으로 실행이 가능합니다. 설치 후에 pnpx playwright install 명령을 사용하면, 필요한 브라우저 바이너리(Chromium, Firefox, WebKit)를 자동으로 다운로드하게 됩니다.
playwright.config.js 파일에 브라우저 종류, 테스트 타임아웃, 스크린샷 설정 등 여러가지 설정을 담습니다. 예를 들어, 테스트 실패 시 스크린샷을 자동으로 찍어주거나, 특정 브라우저만 테스트하도록 지정할 수 있습니다.
테스트 스크립트를 작성하겠습니다. package.json 파일을 열고 다음 스크립트를 추가합니다.
이제 pnpm test:playwright 를 실행하면 됩니다.
테스트를 실행할 때엔 개발 웹서버를 구동한(pnpm dev) 후에 실행해야 합니다. 실제 웹 서버에 접속해서 동작하기 때문입니다.
(3) 간단한 시나리오 예제: 로그인 페이지 테스트
Playwright로 종단 테스트를 작성할 때 핵심 개념은 브라우저 인스턴스(Page)를 생성하여, 그 안에서 사용자가 하는 행동을 시뮬레이션하는 것입니다. 사용자의 동작은 주로 페이지 이동, 텍스트 입력, 버튼 클릭 등으로 이루어지며, Playwright는 이를 위한 API를 제공합니다.
아래 예시는 가상의 로그인 페이지가 있다고 가정하고, 사용자가 올바른 이메일과 비밀번호를 입력한 뒤 로그인에 성공하는 시나리오를 테스트하는 코드입니다.
이 코드는 Playwright에서 제공하는 테스트 함수(test)를 하나 정의하고, 테스트 내부에서 page 객체를 통해 브라우저 조작을 수행합니다. page.goto(...)로 해당 URL에 접속하고, page.fill(...)로 텍스트 필드에 값을 입력하며, page.click(...)로 버튼을 누릅니다. 마지막에는 expect 구문을 사용해, 이동된 페이지에서 특정 요소(h1)가 특정 텍스트(“홈 화면입니다”)를 가지고 있는지를 확인합니다.
만약 이 과정 중 어느 단계에서든 오류가 발생하면, Playwright가 오류 스크린샷을 찍거나 테스트를 실패 상태로 보고하게 됩니다. 이를 통해 QA(품질 보증) 단계에서 “실제 사용자와 똑같이 애플리케이션을 써보는” 과정을 자동화할 수 있습니다.
(4) 추가 기능: 시맨틱 셀렉터, 스크린샷 및 영상 기록, 병렬 실행
Playwright는 기본적인 종단 테스트 외에도 여러 부가적인 기능을 제공합니다. 예를 들어, 시맨틱 셀렉터(getByRole, getByText, getByLabelText 등)를 사용할 수 있어, 단순한 CSS 셀렉터를 이용하는 것보다 접근성(ARIA 속성)을 활용한 직관적인 테스트를 작성하기 쉬워집니다.
또한, 설정을 통해 테스트 실행 시나 실패 시 스크린샷을 남길 수 있고, 비디오를 녹화하여 테스트가 어떻게 진행되었는지 기록으로 보관할 수도 있습니다. 이는 UI가 복잡하거나 간헐적인 오류가 발생하는 상황을 분석하는 데 큰 도움이 됩니다. 예를 들어, Playwright 설정 파일(playwright.config.js)에서 모든 테스트가 실패하면 스크린샷을 찍어 저장하라거나, 동시에 여러 브라우저나 여러 디바이스 뷰포트에서 테스트를 실행하라는 식의 지시사항을 줄 수 있습니다.
병렬 실행도 가능하기 때문에, 여러 테스트 케이스를 한꺼번에 분산해 빠르게 처리할 수도 있습니다. 단, 종단 테스트가 많아지면 전체 테스트 시간도 길어지므로, 필요한 시나리오에 우선순위를 두고 관리하는 것이 좋습니다.
Playwright 테스트 러너 API
그럼 Playwright API에 대해 자세히 살펴보겠습니다.
(0) 예제용 Login.jsx 전체 코드
뉴스레터에 담기엔 소스 코드량이 많아 푸딩캠프 웹페이지에 수록하겠습니다.
https://puddingcamp.com/page/0416c651-8dbb-4667-baa6-76840fd70667
그 다음 테스트를 위해 main.jsx 파일 내용을 잠시 바꿉니다.
(1) test() & test.describe()
Playwright는 자체적으로 테스트 러너를 내장하고 있으며, @playwright/test 패키지에서 제공하는 test 함수를 통해 테스트를 작성할 수 있습니다.
test(name, callback) : 하나의 테스트를 정의합니다.test.describe(name, callback) : 관련된 여러 테스트를 그룹화하여 가독성과 유지보수를 쉽게 만들어줍니다.
(2) test.beforeAll(), test.afterAll(), test.beforeEach(), test.afterEach()
각 테스트(또는 테스트 그룹) 전/후에 수행할 코드를 등록할 수 있습니다.
(3) 주요 Playwright Assertion API
Playwright 테스트 러너는 expect 함수를 통해 다양한 검증 메서드를 제공합니다.
1) expect(locator).toHaveText()
특정 요소(locator)가 지정한 텍스트를 가지고 있는지 검증합니다.
2) 그 외 자주 쓰이는 expect 메서드들
toBeVisible() : 요소가 화면에 표시되는지 확인toBeHidden() : 요소가 화면에서 보이지 않는지 확인toHaveCount(number) : 해당 셀렉터로 찾은 요소 개수가 특정 개수와 일치하는지 확인toHaveValue(value) : 입력 요소의 값이 특정 값인지 확인toHaveAttribute(name, value) :요소의 특정 속성이 기대값인지 확인toContainText(text) : 요소가 특정 텍스트를 포함하는지 확인toMatchURL(url or regex) : 페이지 주소가 특정 URL 또는 정규식과 일치하는지 확인 (또는 expect(page).toHaveURL(...) 형태로도 사용)
(4) Playwright Page 객체 API
종단 테스트를 위해 가장 많이 사용하게 되는 API는 Page 객체에서 제공됩니다. page는 실제 브라우저(또는 브라우저 탭)를 나타낸다고 생각하면 됩니다.
1) page.goto(url, [options])
지정한 URL로 페이지를 이동합니다.
두 번째 인자로 timeout, waitUntil 같은 옵션을 줄 수 있습니다.
2) page.fill(selector, text, [options])
입력 필드에 텍스트를 채웁니다.
fill은 기존 텍스트를 지우고 새 텍스트로 교체합니다.
기존 값 뒤에 추가 입력을 원한다면 page.type()을 사용할 수도 있습니다.
3) page.click(selector, [options])
해당 셀렉터의 요소를 클릭합니다.
클릭 전 요소가 동작 가능 상태로 로드될 때까지 기다립니다(Playwright의 Auto-waiting 기능).
4) page.locator(selector)
DOM 요소를 찾기 위한 Locator 객체를 반환합니다. 그 후 locator 객체로부터 추가 동작(ex. click, fill 등)을 수행할 수 있습니다.
5) 시맨틱 셀렉터: page.getByRole(), page.getByText(), page.getByLabelText(), ...
Playwright는 접근성(ARIA) 속성을 활용한 시맨틱 셀렉터를 제공합니다.
page.getByText(text) : 특정 텍스트를 포함하는 요소를 찾을 때 사용page.getByLabel(labelText) : 라벨 텍스트로 매핑되는 input요소를 찾을 때 사용그 외 getByPlaceholder, getByAltText, getByTitle, etc. 다양한 셀렉터 지원
6) page.screenshot([options])
해당 시점의 페이지 스크린샷을 찍어 파일로 저장합니다.
7) 그 외 자주 쓰이는 Page 메서드
page.type(selector, text) : 해당 입력 필드에 글자를 하나씩 ‘타이핑’해 넣습니다.page.selectOption(selector, values) : <select> 요소에서 특정 값을 선택합니다.page.check(selector), page.uncheck(selector): 체크박스의 체크 여부를 설정합니다.page.reload([options]) : 현재 페이지를 재로딩합니다.page.waitForSelector(selector, [options]) : 해당 셀렉터가 나타날 때까지 기다립니다.
(5) Browser, Context 관련 API
보통 Playwright 테스트 러너(@playwright/test)를 이용하면, 테스트마다 자동으로 브라우저 & 컨텍스트가 생성/종료됩니다. 그러나 필요하다면 직접 브라우저와 컨텍스트를 제어할 수도 있습니다.
이 방식을 직접 쓰는 경우는 대개 커스텀 자동화 스크립트가 필요하거나, Playwright의 테스트 러너가 아닌 다른 러너와 병행해 테스트할 때입니다. 보통은 @playwright/test에서 test 함수에 ({ page }) 매개변수를 주입받아 쓰는 정도로 충분합니다.
(6) 예제 시나리오 코드 종합
아래는 위에서 소개한 API들을 섞어서, 간단한 로그인 시나리오 테스트를 좀 더 풍부하게 작성한 예시입니다.
위 예시에서는
test.describe를 통해 ‘로그인’ 관련 테스트를 한 데 모아둠test.beforeEach로 매 테스트가 시작되기 전에 로그인 페이지로 이동page.fill, page.click 등으로 사용자의 동작을 시뮬레이션최종적으로 expect(...).toHaveText(...)로 결과 화면을 검증
이처럼 Playwright는 실제 브라우저에서 일어나는 사용자 시나리오를 풍부하게 재현해낼 수 있으며, 실패 시 스크린샷/비디오/트레이스 등을 남겨 디버깅에 활용할 수 있습니다.
(7) Playwright API 총 정리
정리하면, Playwright 종단 테스트에서는 다음과 같은 API들을 주로 활용하게 됩니다.
테스트 러너 APItest(), test.describe(), test.beforeAll(), test.afterAll(), test.beforeEach(), test.afterEach()
검증(Assertion) APIexpect(locator).toHaveText(), toBeVisible(), toBeHidden(), toHaveValue(), 등등
Page 객체 조작 APIpage.goto(), page.fill(), page.type(), page.click(), page.locator()시맨틱 셀렉터(page.getByRole(), page.getByText(), page.getByLabelText(), …)page.waitForURL(), page.screenshot(), etc.
Browser/Context 관리 API (직접 사용 시)chromium.launch(), browser.newContext(), context.newPage(), etc.
설정 파일(playwright.config.js) 옵션브라우저 종류, 타임아웃, 스크린샷/비디오/트레이스 기록, 병렬 실행 등
이러한 API들을 적절히 조합하여 "실제 브라우저에서 사용자가 행동하는 것과 거의 동일한 방식"으로 테스트를 자동화할 수 있습니다. 종단 테스트는 UI와 라우팅, 네트워크 요청을 모두 포함하는 실제 구동 환경을 점검하는 데 탁월하므로, 핵심 시나리오 위주로 배치하여 사용성을 확보하고, 다른 세부 기능은 단위/통합 테스트와 함께 병행하는 전략을 취하는 것이 가장 효율적입니다.
Playwright 설정 파일(playwright.config.js)에서의 주요 옵션
Playwright는 설정 파일(playwright.config.js 또는 playwright.config.ts)을 통해 브라우저 종류, 뷰포트 크기, 스크린샷/비디오 저장, 병렬 실행 등을 손쉽게 설정할 수 있습니다.
use 옵션 안에 screenshot, video, trace 등을 지정하여 각 테스트가 어떻게 기록되고 보관될지 제어할 수 있습니다.projects 배열을 통해 여러 브라우저(Chromium, Firefox, WebKit)에서 테스트를 병렬로 수행할 수 있습니다.
종단 테스트 도입 시 유의점
종단 테스트는 분명히 강력한 장점을 지니고 있지만, 동시에 몇 가지 주의해야 할 점이 있습니다.
첫째, 테스트 작성과 유지보수에 상당한 비용이 들 수 있습니다. 한 번 작성해둔 종단 테스트가 소소한 UI 변경으로 인해 깨져버리면, 해당 시나리오를 다시 수정해야 하며, 이러한 과정을 자주 겪을수록 개발 효율이 떨어질 수 있습니다.
둘째, 테스트가 자주 깨지는 원인을 빠르게 파악하기가 어렵다는 점도 고려해야 합니다. 단위 테스트는 특정 함수나 컴포넌트에 문제가 있음을 즉시 알려주지만, 종단 테스트는 전체 시나리오가 실패했을 때 어느 단계에서 오류가 발생했는지 찾기 위해 코드를 하나씩 추적해야 할 수 있습니다.
그러므로 종단 테스트는 적절한 분량, 즉 핵심 시나리” 위주로 운영하는 편이 좋습니다. 로그인, 회원가입, 결제 같은 치명적인 기능은 종단 테스트로 검증하고, 자잘한 UI 동작은 단위 테스트(혹은 통합 테스트)로 보완하는 식으로 계층적으로 나누면, 전체 테스트 전략이 더욱 효율적입니다.