E2E 테스트는 소프트웨어 애플리케이션의 전체 흐름을 처음부터 끝까지 사용자 관점에서 검증하는 테스트 방법이다. 이는 단위 테스트나 통합 테스트가 개별 모듈이나 컴포넌트 간 상호작용을 확인하는 것과 달리, 실제 사용자가 겪을 수 있는 시나리오를 브라우저나 애플리케이션을 통해 자동으로 실행하고 확인한다.
주요 목적은 다양한 시스템 컴포넌트(예: 프론트엔드, 백엔드, 데이터베이스, 네트워크 서비스)가 통합된 상태에서의 기능적 정확성과 사용자 경험의 무결성을 보장하는 것이다. Playwright는 최근 등장한 강력한 E2E 테스트 자동화 도구로, 마이크로소프트가 개발하여 크로미움, 파이어폭스, 웹킷 엔진을 모두 지원한다.
이 문서는 E2E 테스트의 기본 개념과 중요성을 설명하고, Playwright를 활용한 테스트 자동화의 설치, 기본 사용법, 고급 기능, 모범 사례를 다룬다. 또한 Selenium, Cypress와 같은 다른 도구와의 비교를 통해 상황에 맞는 도구 선택에 도움을 준다.
E2E 테스트(End-to-End Testing)는 소프트웨어 애플리케이션의 전체 흐름을 처음부터 끝까지 시뮬레이션하여 검증하는 테스트 자동화 방법이다. 사용자 시나리오를 기반으로 실제 사용자가 애플리케이션과 상호작용하는 것과 유사한 환경에서, 프론트엔드 UI부터 백엔드 API, 데이터베이스에 이르기까지 모든 구성 요소의 통합 동작을 확인한다. 주로 웹 애플리케이션에서 로그인부터 결제까지의 핵심 비즈니스 프로세스가 의도대로 작동하는지 검증하는 데 활용된다.
단위 테스트가 개별 함수나 모듈의 고립된 로직을 검사하고, 통합 테스트가 여러 모듈 간의 상호작용을 점검한다면, E2E 테스트는 이 모든 것이 조합된 최종 제품의 사용자 관점에서의 완성도를 평가한다. 단위 및 통합 테스트가 개발자 중심의 "코드가 올바르게 작성되었는가"에 초점을 맞춘다면, E2E 테스트는 사용자 중심의 "시스템이 올바르게 동작하는가"에 초점을 맞춘다. 이 세 가지 테스트는 서로를 보완하며, 아래 표와 같이 역할과 범위에서 차이를 보인다.
테스트 유형 | 테스트 범위 | 주목적 | 실행 속도 |
|---|---|---|---|
단일 함수/모듈 | 코드 로직의 정확성 검증 | 매우 빠름 | |
모듈 간 인터페이스 | 컴포넌트 간 통신 검증 | 보통 | |
전체 애플리케이션 | 사용자 시나리오 및 비즈니스 흐름 검증 | 느림 |
E2E 테스트를 도입할 때는 몇 가지 장단점을 고려해야 한다. 주요 장점은 실제 사용 환경을 가장 잘 반영한 신뢰도 높은 피드백을 제공한다는 점이다. 이를 통해 다양한 시스템 컴포넌트 간의 상호의존성에서 발생하는 결함을 발견할 수 있다. 또한, 자동화된 회귀 테스트 스위트로 활용되어 새로운 기능 추가 시 기존 기능이 망가지지 않았는지 지속적으로 확인할 수 있다. 반면, 단점으로는 설정과 유지보수가 복잡하고, 실행 속도가 상대적으로 느리며, 테스트 실패 원인을 특정하기 어려울 수 있다는 점이 있다. 따라서 E2E 테스트는 핵심 시나리오에 제한적으로 적용하고, 빠른 피드백 루프를 위한 단위 및 통합 테스트와 조화롭게 활용하는 것이 바람직하다.
E2E 테스트(End-to-End Testing)는 소프트웨어 애플리케이션의 전체 흐름을 처음부터 끝까지 시뮬레이션하는 테스트 방법이다. 사용자의 관점에서 애플리케이션의 모든 구성 요소가 통합되어 제대로 작동하는지 검증하는 것이 목표이다. 이는 단일 기능이나 모듈을 검사하는 단위 테스트나 모듈 간 상호작용을 확인하는 통합 테스트와 구분되는 개념이다.
일반적인 E2E 테스트 시나리오는 실제 사용자가 수행할 작업, 예를 들어 웹 애플리케이션에 로그인하여 데이터를 조회하고 수정한 후 로그아웃하는 과정을 자동화된 스크립트로 재현한다. 이 과정에는 프론트엔드 사용자 인터페이스, 백엔드 API 서버, 데이터베이스, 네트워크, 외부 서비스 등 애플리케이션 스택의 모든 계층이 포함된다. 따라서 테스트는 시스템이 하나의 통합된 전체로서 비즈니스 요구사항과 사용자 요구를 충족시키는지 확인한다.
E2E 테스트의 핵심 가치는 실제 운영 환경과 유사한 조건에서의 신뢰성 검증에 있다. 개별 모듈은 정상적으로 동작하더라도 통합 시 발생할 수 있는 인터페이스 불일치, 데이터 흐름 오류, 사용자 경험 문제 등을 발견할 수 있다. 이는 소프트웨어 출시 전 최종적인 품질 보증의 중요한 단계로 간주된다[1].
단위 테스트는 개별 함수, 메서드, 클래스와 같은 가장 작은 코드 단위를 격리하여 검증하는 테스트이다. 주로 특정 입력에 대한 출력이 예상대로 나오는지 확인하는 데 초점을 맞춘다. 통합 테스트는 이러한 단위 모듈들이 결합되어 상호작용할 때, 예를 들어 API 호출이나 데이터베이스 연동과 같이 여러 컴포넌트 간의 인터페이스와 데이터 흐름이 올바르게 작동하는지 검증한다.
반면, E2E 테스트(End-to-End Test)는 실제 사용자 시나리오를 완전히 재현한다. 프론트엔드 UI부터 백엔드 서버, 데이터베이스에 이르기까지 애플리케이션의 모든 계층을 포함하는 통합된 흐름을 테스트한다. 사용자가 브라우저에서 버튼을 클릭하고, 데이터가 제출되며, 결과가 화면에 표시되는 전 과정을 자동화된 스크립트로 검증하는 것이 대표적인 예시이다.
이들의 차이점은 테스트 범위와 목표, 그리고 실행 속도와 안정성에서 명확히 드러난다. 아래 표는 주요 차이점을 요약한 것이다.
구분 | 단위 테스트 | 통합 테스트 | E2E 테스트 |
|---|---|---|---|
테스트 범위 | 단일 함수/모듈 | 모듈 간 상호작용 | 전체 애플리케이션 (UI to DB) |
목표 | 코드 로직의 정확성 | 컴포넌트 간 인터페이스 정합성 | 사용자 시나리오의 완전한 성공 |
실행 속도 | 매우 빠름 | 보통 | 상대적으로 느림 |
외부 의존성 | 모의 객체(Mock)로 대체 | 일부 실제 의존성 사용 (DB 등) | 모든 실제 인프라 사용 |
실패 원인 | 주로 코드 버그 | 인터페이스 불일치, 환경 문제 | 네트워크, 서버, UI, DB 등 광범위 |
따라서, 테스트 피라미드 모델에서는 빠르고 안정적인 단위 테스트를 기반으로, 그 위에 통합 테스트, 그리고 가장 상단에 상대적으로 수가 적지만 핵심 시나리오를 커버하는 E2E 테스트를 두는 것이 권장된다. E2E 테스트는 시스템 전반의 건강 상태를 확인하는 최종 검증 단계 역할을 하지만, 실행 비용이 높고 유지보수가 어려울 수 있으므로 전략적인 도입이 필요하다.
E2E 테스트 도입을 결정할 때는 그 장점과 함께 수반되는 비용과 주의점을 종합적으로 고려해야 한다. 가장 큰 장점은 사용자 관점에서의 시스템 전체 동작을 검증한다는 점이다. 이는 프론트엔드와 백엔드, 데이터베이스, 외부 서비스 등 모든 구성 요소가 통합된 상태에서의 비즈니스 로직과 사용자 흐름을 테스트할 수 있음을 의미한다. 따라서 단위 테스트나 통합 테스트로는 발견하기 어려운, 구성 요소 간 상호작용에서 발생하는 문제를 조기에 포착할 수 있다. 또한 실제 사용자 환경과 유사한 조건에서 테스트가 수행되므로, 소프트웨어의 신뢰성과 품질에 대한 확신을 높여준다.
반면, E2E 테스트는 상대적으로 높은 유지보수 비용과 실행 시간을 요구한다는 단점이 있다. UI나 API 명세가 변경될 때마다 테스트 스크립트도 함께 수정해야 하며, 이는 레거시 시스템이나 빠르게 변화하는 애자일 환경에서 부담이 될 수 있다. 또한 테스트 실행 환경(예: 네트워크 상태, 서버 응답 시간, 타사 서비스 의존성)의 변동성으로 인해 테스트 결과가 불안정해지는 플레이크 테스트 현상이 발생하기 쉽다. 이러한 특성상 모든 시나리오를 E2E 테스트로 커버하려는 시도는 비효율적일 수 있다.
따라서 효과적인 도입을 위해서는 테스트 피라미드 모델을 준수하는 전략이 권장된다. 즉, 많은 수의 저비용 단위 테스트를 기반으로, 적절한 수의 통합 테스트를 두고, 가장 꼭대기에 소량의 핵심 E2E 테스트를 배치하는 것이다. 도입 시에는 테스트 범위를 신중하게 선정해야 하며, 주로 핵심 비즈니스 가치를 전달하는 중요한 사용자 여정(예: 회원가입, 주문 결제)에 집중하는 것이 일반적이다. 또한 테스트의 격리성과 재현성을 보장하기 위해 목 서버를 활용하거나 테스트 데이터를 철저히 관리하는 방안도 함께 고려해야 한다.
Playwright는 마이크로소프트가 주도하여 개발한 최신 웹 자동화 및 E2E 테스트 도구이다. 2020년에 처음 공개된 이후, 빠른 성장을 거듭하며 현대적 웹 애플리케이션 테스트를 위한 강력한 대안으로 자리 잡았다. 이 도구는 개발자가 단일 API를 사용하여 Chromium, Firefox, WebKit 등 여러 브라우저 엔진을 대상으로 안정적인 테스트를 작성하고 실행할 수 있도록 설계되었다.
주요 특징으로는 모든 최신 브라우저를 네이티브 수준으로 지원한다는 점을 꼽을 수 있다. WebKit 엔진을 통한 Safari의 완전한 지원은 크로스 브라우저 테스트의 신뢰성을 크게 높인다. 또한, Playwright는 자동 대기(auto-waiting) 메커니즘을 내장하여 요소가 사용 가능해질 때까지 자동으로 기다리므로, 테스트 스크립트에 불필요한 대기 시간을 명시적으로 추가할 필요가 없다. 네트워크 활동 차단, 모의 객체(Mock) 생성, 다중 페이지 및 도메인 컨텍스트 처리와 같은 고급 기능도 제공한다.
Playwright는 Node.js, Python, Java, .NET 등 여러 프로그래밍 언어를 공식 지원하여 다양한 기술 스택의 팀이 활용할 수 있다. 테스트 실행 중 자동으로 스크린샷과 비디오를 캡처할 수 있으며, 헤드리스 및 헤드 풀 모드 모두에서 작동한다. 이러한 특징들은 복잡한 사용자 시나리오를 정확하게 재현하고, 회귀 버그(Regression Bug)를 효과적으로 찾아내는 데 큰 장점으로 작용한다.
지원 브라우저 | 지원 언어 | 주요 실행 모드 |
|---|---|---|
Chromium (Chrome, Edge) | Node.js (JavaScript/TypeScript) | |
헤드 풀(Headful) | ||
WebKit (Safari) | ||
.NET (C#) |
Playwright는 마이크로소프트가 개발한 최신 웹 자동화 및 E2E 테스트 도구이다. 2020년에 처음 공개되었으며, Node.js 런타임을 기반으로 Chromium, Firefox, WebKit 엔진을 네이티브로 제어하여 브라우저 자동화를 수행한다. 주로 웹 애플리케이션의 E2E 테스트를 작성하고 실행하는 데 사용되지만, 웹 스크래핑이나 반복 작업 자동화와 같은 일반적인 자동화 작업에도 활용된다.
이 도구의 핵심은 브라우저 컨텍스트라는 개념이다. 각 테스트는 격리된 브라우저 컨텍스트 내에서 실행되어 쿠키나 로컬 스토리지와 같은 상태를 공유하지 않는다. 이를 통해 테스트 간 간섭을 방지하고 신뢰성을 높인다. 또한 Playwright는 기본적으로 헤드리스 모드로 브라우저를 실행하지만, 필요시 헤드 풀 모드로 전환하여 실행 과정을 직접 관찰할 수 있다.
주요 기능을 요약하면 다음과 같다.
기능 영역 | 설명 |
|---|---|
다중 브라우저 지원 | |
다중 언어 지원 | JavaScript, TypeScript, Python, .NET, Java 언어 바인딩을 제공한다. |
자동 대기 | 요소가 나타나거나 클릭 가능해질 때까지 자동으로 대기하여 플레이키 테스트 작성을 단순화한다. |
네트워크 제어 | 네트워크 요청을 가로채거나 모의 응답을 제공할 수 있다. |
다중 환경 | 데스크톱 브라우저뿐만 아니라 모바일 에뮬레이션도 지원한다. |
Playwright는 Selenium이나 Puppeteer와 같은 기존 도구의 한계를 해결하기 위해 설계되었다. 특히 Cypress와 비교될 수 있으나, Playwright는 다중 브라우저와 다중 탭/도메인을 원활하게 지원하며, 공식적으로 더 많은 프로그래밍 언어를 옵션으로 제공한다는 점에서 차별점을 가진다.
Playwright는 웹 자동화 및 E2E 테스트를 위한 강력한 API를 제공하는 Node.js 라이브러리이다. 기존 도구들과 구별되는 몇 가지 핵심적인 특징을 가지고 있다.
가장 두드러진 특징은 Chromium, Firefox, WebKit 엔진을 모두 네이티브로 지원한다는 점이다. 이를 통해 단일 API로 세 가지 주요 렌더링 엔진을 대상으로 테스트를 실행할 수 있으며, 이는 크로스 브라우저 테스트의 신뢰성을 크게 높인다. 또한 헤드리스 브라우저와 헤드 모드 모두에서 테스트가 가능하며, 모바일 뷰포트 에뮬레이션을 포함한 다양한 브라우저 컨텍스트를 쉽게 생성할 수 있다. 자동 대기(Auto-wait) 기능은 요소가 사용 가능해질 때까지, 네트워크 활동이 안정될 때까지 자동으로 대기하여 플레이킹 테스트(Flaky Test)를 줄이는 데 기여한다.
Playwright의 장점은 다음과 같이 요약할 수 있다.
특징 | 장점 |
|---|---|
다중 브라우저/엔진 지원 | 단일 코드베이스로 Chrome, Firefox, Safari를 테스트하여 크로스 브라우저 호환성 보장이 용이하다. |
뛰어난 성능과 신뢰성 | 자동 대기(Auto-wait)와 격리된 브라우저 컨텍스트로 빠르고 안정적인 테스트 실행이 가능하다. |
강력한 네트워크 제어 | 네트워크 요청을 가로채고 조작(Mocking)하여 오프라인 상태나 느린 네트워크 조건을 시뮬레이션할 수 있다. |
풍부한 자동화 기능 | 스크린샷, PDF 생성, 비디오 녹화, 다중 탭/창 제어 등 개발 및 테스트에 유용한 기능을 내장하고 있다. |
현대적인 API 디자인 |
이러한 특징들 덕분에 Playwright는 복잡한 SPA(Single Page Application) 테스트, PWA(Progressive Web App) 검증, 그리고 CI/CD 파이프라인에 통합된 자동화된 테스트 스위트 구축에 매우 효과적인 도구로 자리 잡았다.
Playwright는 크로미움 기반 브라우저(Google Chrome, Microsoft Edge), WebKit(Safari) 및 Firefox를 공식적으로 지원합니다. 이는 현대 웹 애플리케이션 테스트에 필요한 주요 브라우저 엔진을 모두 포괄함을 의미합니다.
지원 프로그래밍 언어로는 JavaScript, TypeScript, Python, Java, 그리고 .NET(C#)을 제공합니다. 이를 통해 다양한 기술 스택을 가진 개발 팀이 자신에게 익숙한 언어로 E2E 테스트를 작성할 수 있습니다. 각 언어별 API는 일관성을 유지하도록 설계되어, 한 언어에서 익힌 개념을 다른 언어로 쉽게 전환할 수 있습니다.
지원 항목 | 내용 |
|---|---|
브라우저 | Chromium, Firefox, WebKit |
언어 | JavaScript, TypeScript, Python, Java, .NET (C#) |
운영체제 | Windows, macOS, Linux |
Playwright는 각 브라우저의 정확한 바이너리를 자동으로 다운로드하고 관리합니다. 이는 테스트 환경의 일관성을 보장하며, 별도의 브라우저 설치나 복잡한 WebDriver 관리 없이도 즉시 테스트를 시작할 수 있게 합니다. 또한, 헤드리스 모드와 헤드 모드 모두에서 실행할 수 있어, CI/CD 환경과 로컬 디버깅 모두에 적합합니다.
Node.js 16 버전 이상이 시스템에 설치되어 있어야 한다. 공식 문서에서 권장하는 LTS 버전을 사용하는 것이 좋다. Node.js 설치 후, 프로젝트 디렉토리에서 다음 명령어를 실행하여 Playwright를 설치한다.
```bash
npm init playwright@latest
```
이 명령어는 대화형 설치 도구를 실행시켜, 테스트 작성에 사용할 프로그래밍 언어(TypeScript 또는 JavaScript)와 테스트 디렉토리 위치, GitHub Actions 설정 여부 등을 선택할 수 있게 한다. 설치 과정에서 @playwright/test 패키지와 함께 필요한 브라우저 드라이버들이 자동으로 다운로드된다.
설치가 완료되면 프로젝트 루트에 playwright.config.ts(또는 .js) 파일이 생성된다. 이 설정 파일에서는 테스트 실행에 관한 다양한 옵션을 관리한다. 기본적으로 Chromium, Firefox, WebKit 브라우저를 사용한 테스트가 구성되어 있으며, 테스트 타임아웃, 기본 URL, 리포트 생성 방식 등을 여기서 조정할 수 있다. 또한, tests 디렉토리와 그 안에 예제 테스트 파일(example.spec.ts)이 생성되어 기본적인 사용법을 참고할 수 있다.
설치된 브라우저들은 기본적으로 사용자 프로필 없이 실행되는 헤드리스 모드로 설정되어 있다. 필요에 따라 설정 파일에서 headless: false 옵션을 변경하여 브라우저 UI를 볼 수 있도록 할 수 있다. 초기 설정을 검증하기 위해 npx playwright test 명령어로 예제 테스트를 실행해볼 수 있다.
Node.js는 Playwright를 실행하기 위한 필수 런타임 환경이다. 먼저 공식 웹사이트나 패키지 관리자를 통해 Node.js를 설치해야 한다. 권장 버전은 LTS(Long-Term Support) 릴리스이며, 설치 후 터미널에서 node --version 명령어로 설치를 확인할 수 있다.
Node.js 설치가 완료되면, 프로젝트 디렉토리를 생성하고 npm이나 yarn 같은 패키지 관리자를 이용해 Playwright 패키지를 설치한다. 일반적으로 개발 의존성(devDependencies)으로 설치하는 것이 일반적이다. 다음은 npm을 사용한 설치 명령어 예시이다.
```bash
npm init playwright@latest
```
이 명령어는 대화형 CLI를 실행하여 프로젝트를 초기화하고, 필요한 모든 패키지를 자동으로 설치한다. 설치 과정에서 테스트 스크립트를 작성할 언어(TypeScript 또는 JavaScript)와 Playwright Test 러너의 기본 구성을 선택할 수 있다.
설치가 완료되면 package.json 파일에 다음과 같은 의존성이 추가된다.
패키지 이름 | 설명 |
|---|---|
| 핵심 테스트 러너와 라이브러리 |
| 브라우저 자동화를 위한 핵심 라이브러리 |
또한 프로젝트 루트에 playwright.config.ts(또는 .js) 설정 파일과 기본 테스트 예제가 포함된 tests 디렉토리가 생성된다. 설정 파일에서는 기본 타임아웃, 브라우저 종류, 기본 URL 등의 테스트 실행 환경을 관리할 수 있다.
Playwright는 테스트 실행에 필요한 브라우저 바이너리를 자동으로 다운로드하고 관리합니다. npx playwright install 명령어를 실행하면, 기본적으로 크로미움, 파이어폭스, 웹킷 엔진을 사용하는 브라우저들이 시스템에 설치됩니다. 이 과정은 프로젝트 초기 설정이나 CI/CD 환경에서 처음 실행될 때 한 번만 수행하면 됩니다.
설치되는 브라우저는 플랫폼별 독립적인 디렉터리에 저장되며, 테스트 실행 시 Playwright 라이브러리가 이 경로를 자동으로 인식합니다. 이를 통해 개발 환경과 CI 환경 간의 브라우저 버전 차이로 인한 불일치 문제를 방지할 수 있습니다. 특정 브라우저만 설치하거나, 특정 채널의 브라우저를 설치하는 것도 가능합니다.
명령어 | 설명 |
|---|---|
| 모든 기본 브라우저(Chromium, Firefox, WebKit)를 설치합니다. |
| 크로미움 브라우저만 설치합니다. |
| 마이크로소프트 엣지 브라우저를 설치합니다. |
| 브라우저와 함께 운영체제 레벨의 종속성도 설치합니다[2]. |
설치된 브라우저는 자동으로 업데이트되지 않습니다. 새 버전을 사용하려면 명시적으로 설치 명령어를 다시 실행해야 합니다. 이 방식은 테스트 스위트의 안정성을 보장하며, 브라우저 버전이 갑자기 변경되어 테스트가 깨지는 상황을 예방합니다.
Node.js 프로젝트 내에서 Playwright를 사용하기 위한 기본적인 프로젝트 구조를 설정하는 과정이다. 일반적으로 npm init 또는 yarn init으로 초기화된 프로젝트 루트 디렉토리에서 진행한다.
주요 구성 요소는 다음과 같다.
파일/디렉토리 | 용도 |
|---|---|
| 테스트 실행, 브라우저 설정, 타임아웃, 리포트 등 전반적인 구성을 정의하는 핵심 설정 파일이다. |
| 실제 E2E 테스트 스크립트( |
| Playwright 설치 시 함께 제공되는 데모 테스트 파일이 포함된 디렉토리이다. |
|
|
설정 파일(playwright.config.ts)에서는 프로젝트 요구사항에 맞춰 여러 옵션을 조정할 수 있다. 예를 들어, 기본 테스트 디렉토리(testDir), 사용할 브라우저 종류(Chromium, Firefox, WebKit), 테스트 실행 시 뷰포트 크기, 헤드리스 모드 실행 여부, 타임아웃 시간, 리포트 생성 방식을 설정한다. 또한, 여러 프로젝트를 정의하여 서로 다른 브라우저나 기기 환경에서 병렬로 테스트를 실행하는 구성도 가능하다.
package.json 파일에는 playwright와 test 같은 npm 스크립트를 추가하여 테스트 실행을 편리하게 만든다. 예를 들어, "test": "playwright test" 스크립트를 등록하면 npm run test 명령어로 모든 테스트를 실행할 수 있다. 프로젝트 구성이 완료되면, tests 디렉토리에 첫 번째 테스트 스크립트를 작성하고 npx playwright test 명령으로 실행해 기본 동작을 확인하는 것이 일반적인 다음 단계이다.
테스트 스크립트는 일반적으로 *.spec.js 또는 *.test.js 확장자를 가지며, Playwright Test 러너를 사용해 작성합니다. 기본 구조는 test 함수와 expect 어설션으로 구성됩니다. test 함수는 개별 테스트 케이스를 정의하며, page 픽스처를 인자로 받아 브라우저 페이지와 상호작용합니다.
페이지 탐색은 page.goto(url) 메서드로 시작합니다. 요소를 선택하기 위해 page.locator(selector) 메서드를 사용하며, 이는 CSS 선택자나 XPath, 텍스트 내용 등을 기반으로 요소를 찾습니다. 선택된 요소는 다시 다른 메서드를 체이닝하여 상호작용할 수 있습니다.
상호작용 메서드 | 설명 |
|---|---|
| 요소를 클릭합니다. |
| 입력 필드에 텍스트를 채웁니다. |
| 키 입력을 하나씩 시뮬레이션합니다. |
| 셀렉트 박스에서 옵션을 선택합니다. |
| 체크박스나 라디오 버튼을 선택하거나 해제합니다. |
사용자 상호작용을 시뮬레이션한 후에는 어설션을 통해 예상 결과를 검증합니다. Playwright Test는 Jest와 유사한 expect API를 제공합니다. 가장 일반적인 어설션은 expect(locator).toBeVisible()이나 expect(locator).toHaveText()입니다. 또한 페이지 URL이나 입력값 등을 검증할 때는 expect(page).toHaveURL()이나 expect(inputLocator).toHaveValue()를 사용합니다. 네트워크 응답이나 다중 페이지 상황을 테스트하는 고급 어설션도 지원합니다[3].
Playwright를 사용한 E2E 테스트 스크립트는 일반적으로 *.spec.js 또는 *.test.js 확장자를 가진 파일에 작성된다. 기본적인 구조는 Playwright Test 러너가 제공하는 test 함수와 expect 어설션을 중심으로 구성된다.
테스트 파일은 크게 테스트 블록과 테스트 스텝으로 나뉜다. test.describe 블록은 관련 테스트 케이스를 그룹화하는 데 사용되며, 개별 테스트 케이스는 test('테스트 제목', async ({ page }) => { ... }) 형태로 정의된다. page 픽스처는 테스트마다 자동으로 제공되는 새로운 브라우저 컨텍스트와 페이지 객체를 의미하며, 이를 통해 브라우저 상호작용을 수행한다. 각 테스트는 서로 완전히 격리되어 실행되는 것이 기본 원칙이다.
일반적인 테스트 스크립트의 흐름은 다음과 같은 단계를 따른다.
1. 페이지 탐색: await page.goto('https://example.com')으로 시작 URL로 이동한다.
2. 요소 선택 및 조작: page.locator('selector')를 사용해 요소를 찾고, .click(), .fill() 등의 메서드로 사용자 액션을 시뮬레이션한다.
3. 상태 검증(어설션): expect() 함수를 사용해 페이지의 상태(텍스트, 가시성, URL 등)가 기대한 대로인지 확인한다.
단계 | 예시 코드 | 설명 |
|---|---|---|
탐색 |
| 지정된 URL 또는 경로로 이동한다. |
요소 선택 |
| CSS 선택자, 텍스트 등을 이용해 요소를 찾는다. |
조작 |
| 선택된 요소를 클릭하거나 값을 입력한다. |
어설션 |
| URL, 텍스트, 요소 개수 등을 검증한다. |
beforeEach나 afterEach 같은 훅을 사용하여 각 테스트 전후에 공통으로 실행될 코드(예: 로그인, 데이터 초기화)를 설정할 수 있다. 이는 테스트의 독립성을 유지하면서 반복 코드를 줄이는 데 도움이 된다.
페이지 탐색은 page.goto() 메서드를 사용하여 특정 URL로 이동하는 것으로 시작한다. 이 메서드는 페이지 로드가 완료될 때까지 기본적으로 대기한다. 페이지 내에서 요소를 선택하기 위해 Playwright는 다양한 Locator 전략을 제공한다. 가장 일반적인 방법은 page.locator() 메서드에 CSS Selector나 XPath를 전달하는 것이다. getByRole, getByText, getByLabel과 같은 의미론적(Semantic) 선택자도 사용 가능하며, 접근성과 테스트의 안정성을 높이는 데 유리하다.
선택한 요소에 대한 조작을 수행하기 전에, 요소가 화면에 표시되고 상호작용 가능한 상태가 될 때까지 자동으로 대기하는 것이 Playwright의 주요 장점이다. locator.click()이나 locator.fill()과 같은 메서드를 호출하면, 해당 요소가 준비될 때까지 내부적으로 대기한 후에 액션을 실행한다. 이는 명시적인 대기 시간(sleep)을 줄여주고 테스트의 신뢰성을 향상시킨다.
여러 요소를 선택해야 하는 경우 page.locator()는 첫 번째 일치 요소만 반환하는 반면, page.locator().all()을 사용하면 일치하는 모든 요소의 배열을 얻을 수 있다. 또한, locator.filter()를 통해 이미 선택된 요소 집합을 추가로 필터링하거나, locator.nth()를 사용하여 특정 인덱스의 요소를 선택할 수 있다. 프레임 내부의 요소를 선택할 때는 frame.locator() 패턴을 사용한다.
작업 | 예시 코드 | 설명 |
|---|---|---|
페이지 이동 |
| 주어진 URL로 이동 |
CSS 선택자로 요소 선택 |
| CSS 선택자로 버튼 찾아 클릭 |
텍스트로 요소 선택 |
| 정확한 텍스트를 가진 요소 클릭 |
모든 링크 선택 |
| 모든 앵커 태그를 배열로 가져옴 |
n번째 요소 선택 |
| 다섯 번째 리스트 항목 클릭 |
사용자 상호작용 시뮬레이션은 Playwright가 실제 사용자가 웹 페이지에서 수행하는 다양한 동작을 코드로 흉내 내는 기능이다. 이는 단순한 페이지 로드 이상의 복잡한 E2E 테스트를 구성하는 핵심 요소이다.
주요 상호작용 명령어는 .click(), .fill(), .type() 등이 있다. .click() 메서드는 버튼이나 링크를 클릭하고, .fill() 메서드는 입력 필드의 기존 값을 지우고 새로운 텍스트를 한 번에 채운다. 반면 .type() 메서드는 텍스트를 한 글자씩 입력하는 과정을 시뮬레이션한다. 드롭다운 선택은 .selectOption()으로, 체크박스나 라디오 버튼 선택은 .check() 및 .uncheck()로 처리한다. 또한 .hover()로 마우스 오버를, .dragTo()로 드래그 앤 드롭 동작을 구현할 수 있다.
더 복잡한 사용자 시나리오를 위해 키보드와 마우스 이벤트를 세밀하게 제어할 수도 있다. page.keyboard 객체를 사용해 Ctrl+C와 같은 키 조합(page.keyboard.press('Control+C'))을 보내거나, page.mouse 객체를 이용해 특정 좌표로 이동하고 클릭하는 동작을 수행할 수 있다. 파일 입력 필드에 대한 업로드 동작은 setInputFiles() 메서드로 간편하게 처리한다. 이러한 메서드들은 대부분 Promise를 반환하므로, await 키워드를 사용해 작업이 완료될 때까지 안정적으로 기다리는 것이 중요하다[4].
어설션은 테스트의 핵심으로, 예상하는 상태나 결과가 실제로 일치하는지 검증하는 단계이다. Playwright는 expect API를 통해 풍부한 어설션 메서드를 제공하며, 이를 통해 테스트의 신뢰성을 확보한다.
주요 어설션 메서드는 다음과 같은 범주로 나뉜다.
어설션 유형 | 설명 | 예시 메서드 |
|---|---|---|
일반 검증 | 값, 상태, 포함 관계 등을 확인 |
|
비동기 상태 | 비동기적으로 변하는 요소의 상태 확인 |
|
네트워크 | 네트워크 요청 및 응답 검증 |
|
예를 들어, 로그인 후 사용자 이름이 표시되는지 확인하려면 await expect(page.locator('.user-name')).toHaveText('홍길동');과 같은 코드를 사용한다. 요소의 가시성(toBeVisible), 활성화 상태(toBeEnabled), 속성값(toHaveAttribute) 등을 검증할 수 있어 UI의 다양한 상태를 포괄적으로 테스트할 수 있다.
부정 어설션을 위한 .not 접두사도 지원된다. await expect(page.locator('#popup')).not.toBeVisible();처럼 특정 요소가 보이지 않아야 하는 조건을 검증할 때 유용하다. 또한, soft 어설션을 사용하면 테스트 중 실패가 발생해도 즉시 중단되지 않고 나머지 검증을 계속 수행할 수 있어, 하나의 테스트 케이스에서 여러 상태를 한꺼번에 점검할 때 효율적이다.
Playwright는 E2E 테스트의 기본 기능을 넘어 다양한 고급 기능을 제공하여 더욱 견고하고 효율적인 테스트 자동화를 가능하게 한다.
테스트 실행 중 자동으로 스크린샷을 캡처하거나 전체 테스트 세션을 비디오로 기록할 수 있다. 이 기능은 테스트 실패 시 어떤 상태였는지 시각적으로 확인하는 데 유용하며, 특히 시각적 회귀 테스트의 기초 자료로 활용된다. 설정 파일에서 screenshot: 'on' 및 video: 'on' 옵션을 활성화하면 간단히 사용할 수 있다. 또한, 네트워크 인터셉트 기능을 통해 애플리케이션의 모든 HTTP 요청을 가로채고 조작할 수 있다. 이를 통해 불필요한 외부 API 의존성을 제거하거나, 특정 응답을 모의하여 다양한 시나리오(예: 서버 에러, 느린 응답)를 테스트할 수 있다. page.route() 메서드를 사용하여 요청을 가로채고 모의 응답을 반환하는 것이 일반적이다.
Playwright는 단일 스크립트로 크로미움, 파이어폭스, 웨킷 기반의 여러 브라우저를 동시에 테스트할 수 있다. 설정 파일에서 projects 항목을 구성하여 데스크톱, 모바일 뷰포트, 다양한 브라우저 환경을 정의하고 병렬 실행할 수 있다. 이는 크로스 브라우저 테스트를 간소화한다. 이러한 테스트는 CI/CD 파이프라인에 통합되어 지속적인 검증을 자동화하는 데 핵심적이다. 깃허브 액션스, 젠킨스, 서클CI 등 주요 CI 플랫폼에서 공식 예제를 제공하며, 헤드리스 모드로 실행하여 리소스 사용을 최소화할 수 있다.
기능 | 설명 | 주요 활용 사례 |
|---|---|---|
스크린샷/비디오 | 테스트 실행 증적 자동 기록 | 실패 분석, 시각적 회귀 테스트 |
네트워크 인터셉트 | API 요청 가로채기 및 모의 응답 | 외부 서비스 불안정성 격리, 에러 시나리오 테스트 |
다중 브라우저 테스트 | 단일 설정으로 여러 브라우저/기기 테스트 | 크로스 브라우저 호환성 보장 |
CI/CD 통합 | 지속적 통합 파이프라인에서 자동 실행 | 풀 리퀘스트별 또는 주기적인 빌드 검증 |
Playwright는 테스트 실행 과정을 시각적으로 기록하고 검증할 수 있는 강력한 스크린샷 및 비디오 캡처 기능을 기본 제공합니다. 이 기능은 테스트 실패 원인 분석, 회귀 테스트 시 UI 변경 사항 확인, 그리고 테스트 실행 흐름을 문서화하는 데 매우 유용합니다.
스크린샷 캡처는 page.screenshot() 메서드를 사용하여 전체 페이지나 특정 요소를 지정된 경로에 이미지로 저장할 수 있습니다. 주로 특정 조건을 검증하는 어설션 단계에서, 또는 테스트 실패 시의 화면 상태를 저장하기 위해 활용됩니다. Playwright Test 러너를 사용할 경우, 테스트 실패 시 자동으로 스크린샷을 찍도록 구성하는 것이 일반적입니다[5]. 비디오 캡처 기능은 테스트 케이스 전체의 사용자 상호작용 흐름을 영상으로 기록합니다. 이는 간헐적으로 발생하는 복잡한 버그를 재현하고 분석할 때 특히 효과적입니다. 비디오는 테스트가 성공했는지 실패했는지와 관계없이, 또는 실패한 테스트에 대해서만 선택적으로 기록할 수 있습니다.
기능 | 사용 방법 | 주요 활용 목적 |
|---|---|---|
스크린샷 |
| 특정 시점 UI 상태 검증, 실패 시점 화면 기록 |
비디오 | 구성 파일에서 | 테스트 전 과정의 행동 흐름 기록, 복잡한 버그 재현 및 분석 |
이러한 시각적 기록은 테스트 리포트와 통합되어, CI/CD 파이프라인에서 실행된 테스트 결과를 더욱 직관적으로 검토할 수 있게 해줍니다. 또한, 시각적 회귀 테스트를 위해 기준 스크린샷과 실제 실행 시의 스크린샷을 자동으로 비교하는 작업에도 활용될 수 있습니다.
네트워크 요청 가로채기 또는 Mocking은 Playwright가 제공하는 핵심 기능 중 하나로, 테스트 중인 애플리케이션이 외부 API나 서버로 보내는 요청을 가로채고 조작할 수 있게 합니다. 이를 통해 테스트는 외부 서비스의 상태나 응답 속도에 의존하지 않고 독립적으로 실행될 수 있습니다. 예를 들어, 느리거나 불안정한 서버 응답, 특정 에러 상태(예: 500 에러), 또는 테스트에 필요한 특정 데이터를 반환하도록 Mocking할 수 있습니다.
page.route() 메서드를 사용하여 요청을 가로채고 조작합니다. 이 메서드는 URL 패턴과 일치하는 요청이 발생했을 때 실행될 콜백 함수를 등록합니다. 콜백 함수 내에서는 원래 요청을 그대로 진행시키거나(route.continue()), 요청을 중단하고 직접 응답을 제공하거나(route.fulfill()), 요청을 다른 URL로 리다이렉트하는 등의 작업을 수행할 수 있습니다.
방법 | 설명 | 사용 예시 |
|---|---|---|
| 요청을 가로채지만, 헤더 등을 수정한 후 원래 목적지로 그대로 진행시킵니다. | 인증 토큰을 요청 헤더에 추가할 때 사용합니다. |
| 요청을 가로채고, 실제 네트워크 호출 없이 바로 모의 응답을 반환합니다. | 테스트용 고정 JSON 데이터를 반환하거나 특정 HTTP 상태 코드를 시뮬레이션할 때 사용합니다. |
| 요청을 중단시킵니다. | 특정 리소스(예: 광고, 트래커)의 로드를 방지할 때 사용합니다. |
이 기능은 특히 E2E 테스트의 신뢰성과 속도를 크게 향상시킵니다. 백엔드 API가 아직 개발 중이거나, 특정 시나리오(예: 결제 실패, 재고 부족)를 재현하기 어려울 때 유용합니다. 또한, 실제 데이터베이스를 변경하지 않고도 데이터 생성/삭제와 관련된 테스트 플로우를 안전하게 검증할 수 있습니다[6].
Playwright는 단일 API를 통해 Chromium, Firefox, WebKit을 포함한 여러 브라우저 엔진을 지원합니다. 이를 통해 개발자는 동일한 테스트 스크립트로 각 브라우저에서의 애플리케이션 동작을 일관되게 검증할 수 있습니다. 브라우저 컨텍스트를 활용하면 하나의 테스트 세션 내에서도 여러 브라우저 인스턴스를 병렬로 실행할 수 있어 테스트 효율을 극대화합니다.
다양한 기기와 뷰포트에서의 사용자 경험을 테스트하기 위해 Playwright는 미리 정의된 기기 에뮬레이션 프로필을 제공합니다. 이 프로필들은 'iPhone 13', 'Pixel 5'와 같은 실제 모바일 기기나 'Desktop Chrome HiDPI'와 같은 데스크톱 환경을 시뮬레이션합니다. 테스트는 특정 기기 프로필을 사용하는 브라우저 컨텍스트를 생성하여 실행할 수 있습니다.
테스트 유형 | Playwright 구현 방식 | 주요 목적 |
|---|---|---|
다중 브라우저 테스트 |
| 브라우저 간 호환성 및 일관성 검증 |
기기 에뮬레이션 |
| 다양한 화면 크기, 터치 이벤트, 사용자 에이전트에서의 반응형 디자인 및 기능 테스트 |
병렬 실행 | Playwright Test 러너의 기본 병렬 실행 기능 활용 | 전체 테스트 스위트의 실행 시간 단축 |
이러한 접근 방식은 CI/CD 파이프라인에 통합되어 풀 리퀘스트마다 모든 주요 환경에서 애플리케이션의 정상 작동을 자동으로 확인하는 데 필수적입니다. 또한, 하나의 테스트 스크립트로 데스크톱과 모바일 시나리오를 모두 커버함으로써 코드 재사용성을 높이고 유지보수 부담을 줄입니다.
Playwright 테스트를 CI/CD 파이프라인에 통합하면 코드 변경마다 자동으로 E2E 테스트를 실행하여 품질을 지속적으로 검증할 수 있다. 이를 통해 개발 초기부터 회귀 버그를 발견하고, 안정적인 배포를 보장한다. 대부분의 CI/CD 플랫폼(GitHub Actions, GitLab CI, Jenkins 등)은 Playwright 실행을 위한 도커 이미지나 사전 구성된 환경을 제공한다.
파이프라인 구성 시 주요 고려사항은 브라우저 설치, 테스트 실행, 결과물 수집이다. Playwright는 CI 환경에 맞춰진 playwright install 명령어를 제공하여 필요한 브라우저를 헤드리스 모드로 설치한다. 테스트 실행 후에는 실패한 테스트의 스크린샷, 트레이스, 비디오 등의 아티팩트를 저장하고 보고서를 생성해야 한다. Playwright Test의 --reporter 옵션을 사용하여 CI 친화적인 리포트(예: junit, html)를 생성할 수 있다.
다음은 GitHub Actions를 사용한 기본적인 워크플로우 구성 예시이다.
단계 | 목적 | 주요 명령어/설정 |
|---|---|---|
체크아웃 | 저장소 코드 가져오기 |
|
Node.js 설정 | 런타임 환경 구성 |
|
의존성 설치 |
|
|
브라우저 설치 | Playwright 브라우저 설치 |
|
테스트 실행 | E2E 테스트 수행 |
|
아티팩트 업로드 | 실패 결과물(스크린샷 등) 저장 |
|
성능 최적화를 위해 병렬 실행을 고려한다. Playwright Test는 --shard 옵션을 지원하여 테스트 스위트를 여러 조각으로 나누어 병렬 실행할 수 있다[7]. 또한, CI 서버의 리소스 제약을 고려하여 테스트 타임아웃을 설정하고, 불필요한 비디오 녹화는 비활성화하는 것이 좋다. 캐시를 활용하여 의존성 설치 및 브라우저 다운로드 시간을 단축할 수도 있다.
신뢰성 높은 셀렉터를 작성하는 것은 E2E 테스트 안정성의 핵심이다. data-testid와 같은 테스트 전용 속성을 사용하거나, 역할(role)과 이름(aria-label)을 기반으로 한 접근성 셀렉터를 우선적으로 활용하는 것이 좋다. 이는 UI 리팩토링 시 빈번히 변경되는 CSS 클래스나 복잡한 DOM 경로에 의존하는 것보다 테스트를 훨씬 견고하게 만든다. 또한 page.getByText()와 같은 Playwright의 내장 로케이터를 사용하면 가독성과 유지보수성을 높일 수 있다.
각 테스트는 완전히 독립적으로 실행될 수 있도록 격리되어야 한다. 이를 위해 테스트 전후에 데이터베이스를 초기화하거나, 각 테스트마다 고유한 사용자 계정과 테스트 데이터를 생성하는 전략이 필요하다. Playwright는 테스트 격리를 돕는 test.describe.configure({ mode: 'parallel' })과 같은 설정을 제공하며, beforeEach 훅을 활용해 테스트 실행 전 공통 준비 작업을 수행할 수 있다.
테스트 실행을 최적화하면 피드백 루프를 빠르게 만들 수 있다. 필요하지 않은 경우 스크린샷이나 비디오 녹화를 끄고, 관련된 테스트만 필터링하여 실행할 수 있다. 또한 Playwright의 내장 병렬 실행 기능을 활용하면 테스트 스위트 전체의 실행 시간을 크게 단축할 수 있다. CI/CD 파이프라인에서는 Docker 이미지나 GitHub Actions와 같은 환경에 브라우저를 캐싱하여 빌드 시간을 절약하는 것도 고려해야 한다.
신뢰성 높은 셀렉터를 작성하는 것은 E2E 테스트의 안정성과 유지보수성을 결정하는 핵심 요소이다. 불안정한 셀렉터는 테스트가 빈번히 실패하는 플레이크 테스트를 유발하며, 이는 테스트 스위트 전체의 신뢰도를 떨어뜨린다.
가장 권장되는 접근법은 테스트를 위해 명시적으로 추가된 data-testid와 같은 사용자 정의 데이터 속성을 활용하는 것이다. 이는 구현 세부 사항(예: CSS 클래스나 DOM 구조)과 분리되어, 리팩토링이나 UI 디자인 변경 시에도 테스트가 깨지지 않도록 보호한다. Playwright는 page.getByTestId()와 같은 편리한 로케이터 메서드를 제공하여 이를 쉽게 사용할 수 있게 한다. 만약 데이터 속성을 사용할 수 없다면, ARIA 역할과 ARIA 레이블을 기반으로 요소를 찾는 page.getByRole()을 우선적으로 고려해야 한다. 이는 접근성 기준을 준수하는 요소를 대상으로 하므로 안정적이며, 접근성 개선과 테스트 안정성 향상을 동시에 달성할 수 있다.
반면, CSS 선택자나 XPath를 사용할 때는 주의가 필요하다. 특히 구현에 지나치게 의존하거나 자주 변경될 수 있는 클래스명(예: .js-button)이나 복잡한 DOM 경로를 피해야 한다. 셀렉터는 가능한 한 간결하고, 고유하며, 의도를 명확히 반영해야 한다. 또한, page.locator()를 사용할 때는 자동으로 대기하는 내장 메커니즘을 활용하여, 요소가 사용 가능해질 때까지 명시적인 대기 문을 줄이는 것이 좋다. 테스트 간의 상호작용을 명확히 구분하기 위해, 특정 컨테이너 내에서만 셀렉터를 검색하는 것도 유용한 전략이다.
권장 접근법 | 설명 | Playwright 예시 |
|---|---|---|
테스트 ID |
|
|
ARIA 역할 | 접근성 역할과 레이블을 사용. 권장되는 대안. |
|
텍스트 | 사용자에게 보이는 텍스트를 사용. |
|
레이블 | 폼 입력 필드의 라벨 텍스트를 사용. |
|
각 테스트는 독립적으로 실행되어야 하며, 다른 테스트의 결과에 영향을 받지 않아야 합니다. 이를 위해 테스트 전후에 애플리케이션 상태를 알려진 기준선으로 초기화하는 작업이 필수적입니다. 일반적인 방법으로는 테스트 데이터베이스를 매 테스트마다 리셋하거나, 각 테스트 시나리오에 필요한 데이터를 사전에 설정(fixture)하고 테스트 후 정리하는 방식이 있습니다. Playwright는 beforeEach와 afterEach 같은 훅(hook)을 제공하여 이러한 설정 및 정리 코드를 체계적으로 관리할 수 있게 합니다.
테스트 데이터를 관리할 때는 하드코딩된 값을 지양하고, 대신 환경 변수나 외부 설정 파일을 활용하는 것이 좋습니다. 또한, 테스트 실행 시마다 고유한 식별자(예: 타임스탬프, UUID)를 생성하여 데이터 충돌을 방지할 수 있습니다. 예를 들어, 사용자 등록 테스트에서 매번 다른 이메일 주소를 사용하는 전략이 적용됩니다.
접근 방식 | 설명 | 예시 |
|---|---|---|
트랜잭션 롤백 | 테스트 내 데이터베이스 작업을 트랜잭션으로 감싸고 테스트 종료 후 롤백합니다. | 테스트 프레임워크와 DB 라이브러리를 연동하여 구현합니다. |
API 활용 | 테스트 전용 API 엔드포인트를 호출하여 데이터를 초기 상태로 되돌립니다. |
|
독립적 데이터 세트 | 각 테스트가 서로 겹치지 않는 고유한 데이터를 생성하고 사용합니다. | 테스트별로 고유한 사용자 ID나 이메일을 생성합니다. |
테스트 격리를 보장하면 테스트 결과의 신뢰도가 높아지고, 실패한 테스트의 원인을 쉽게 추적할 수 있습니다. 또한, 테스트를 병렬로 실행하여 전체 실행 시간을 단축하는 데도 기여합니다. 데이터 관리 전략은 애플리케이션의 아키텍처와 테스트 환경에 맞게 선택하여 구현해야 합니다.
테스트 실행 시간을 최적화하는 것은 개발 생산성과 CI/CD 피드백 루프 속도에 직접적인 영향을 미친다. Playwright는 병렬 실행, 캐싱, 선택적 테스트 실행 등 여러 내장 기능을 통해 효율적인 테스트 수행을 지원한다.
가장 효과적인 방법은 테스트를 병렬로 실행하는 것이다. Playwright Test는 기본적으로 worker 프로세스를 활용하여 테스트 파일을 병렬 실행한다. playwright.config.ts 파일에서 workers 옵션을 조정하여 동시에 실행할 worker의 수를 설정할 수 있다. 일반적으로 CPU 코어 수에 맞춰 설정하지만, 테스트 특성에 따라 조정이 필요하다. 또한, --shard 옵션을 사용하면 테스트 스위트를 여러 부분으로 나누어 여러 머신이나 CI/CD 작업에서 분산 실행할 수 있다.
불필요한 작업을 줄이는 것도 중요하다. 브라우저 컨텍스트와 페이지 생명 주기를 효율적으로 관리해야 한다. 관련성이 높은 테스트는 같은 브라우저 컨텍스트 내에서 실행하여 브라우저 인스턴스 시작 비용을 줄일 수 있다. storageState를 활용하여 인증 상태를 재사용하거나, 데이터베이스 픽스처를 공유하는 것도 실행 시간을 단축시킨다. 또한, 전체 테스트 대신 수정된 파일이나 실패한 테스트만 재실행하는 --grep 또는 --project 같은 필터링 옵션을 적극 활용한다.
최적화 기법 | 설명 | 설정/명령어 예시 |
|---|---|---|
병렬 실행 | 여러 worker를 통해 테스트 파일을 동시 실행 |
|
샤딩 | 테스트 스위트를 분할하여 병렬 처리 |
|
상태 재사용 | 로그인 상태나 픽스처 데이터를 캐싱하여 재사용 |
|
선택적 실행 | 특정 태그가 있거나 실패한 테스트만 실행 |
|
마지막으로, 테스트 자체의 설계를 검토한다. 각 테스트는 가능한 한 독립적이어야 하지만, 공통된 긴 설정 과정은 beforeAll 훅으로 한 번만 실행되게 구성한다. 불필요한 대기 시간을 줄이기 위해 await page.waitForLoadState('networkidle') 같은 일반적 대기보다는 await page.locator('button').click()과 같이 특정 요소의 상태를 명시적으로 기다리는 방식을 선호한다. 이러한 접근법을 종합적으로 적용하면 대규모 E2E 테스트 스위트의 실행 시간을 획기적으로 단축시킬 수 있다.
Selenium, Cypress, Playwright는 모두 널리 사용되는 E2E 테스트 자동화 도구이다. 각 도구는 고유한 아키텍처와 접근 방식을 가지며, 다음과 같은 특징으로 비교할 수 있다.
비교 항목 | Selenium | Cypress | Playwright |
|---|---|---|---|
아키텍처 | WebDriver 프로토콜 기반, 외부 서버 필요 | Node.js 내장 실행, 브라우저와 직접 통신 | 단일 API로 브라우저 자동 제어 |
실행 속도 | 상대적으로 느림 | 빠름 | 매우 빠름, 네이티브 이벤트 사용 |
브라우저 지원 | 멀티 브라우저 (별도 드라이버 필요) | Chromium 계열 중심 | |
언어 지원 | Java, Python, C#, JavaScript 등 다수 | JavaScript/TypeScript 전용 | JavaScript, TypeScript, Python, Java, C# |
기능 | 기본적인 브라우저 제어 | 시간 여행 디버거, 실시간 리로드 | 자동 대기, 네트워크 가로채기, 다중 컨텍스트 |
Playwright는 Playwright Test Runner라는 자체 테스트 러너를 제공한다. 이 러너는 Jest나 Mocha와 유사한 구문을 사용하며, 테스트 병렬 실행, HTML 리포트 생성, 트레이스 뷰어를 통한 디버깅 기능을 내장하고 있다. 또한 시각적 회귀 테스트를 위해 expect(page).toHaveScreenshot() 같은 내장 어설션을 지원하며, Percy나 Applitools Eyes 같은 전문 도구와의 통합도 가능하다.
셀레니움, 사이프레스, 플레이라이트는 모두 인기 있는 웹 자동화 및 E2E 테스트 도구이다. 각 도구는 고유한 아키텍처, 접근 방식 및 장단점을 가지고 있으며, 프로젝트 요구사항에 따라 선택이 달라진다.
비교 항목 | |||
|---|---|---|---|
아키텍처 | W3C WebDriver 프로토콜 기반. 외부 브라우저 드라이버 필요. | Node.js 프로세스 내에서 브라우저 구동. 자체 아키텍처. | |
설치 및 설정 | 브라우저별 드라이버 설치 및 관리가 필요하여 상대적으로 복잡하다. | 통합 패키지로 설치가 간편하다. |
|
실행 속도 | 네트워크를 통한 프로토콜 통신으로 인해 상대적으로 느리다. | 브라우저와 테스트 러너가 직접 통신하여 빠르다. | 자동 대기 및 최적화된 제어로 매우 빠른 실행 속도를 보인다. |
브라우저 지원 | 가장 광범위한 브라우저와 버전을 지원한다. | 크로미움 계열 브라우저에 최적화되어 있다. | |
다중 브라우저/탭 | 강력한 네이티브 지원을 제공한다. | 공식적으로는 단일 브라우저 컨텍스트에 최적화되어 있다. | 다중 브라우저 컨텍스트, 페이지, 도메인 간 테스트를 완벽하게 지원한다. |
네트워크 제어 | 제한적인 지원(프록시 설정 등). | 네트워크 요청 스터빙 및 모의 응답을 지원한다. | 네트워크 요청 가로채기, 모의 응답, 서비스 워커 모의 등을 강력하게 지원한다. |
언어 지원 |
셀레니움은 가장 오래되고 성숙한 도구로, 다양한 프로그래밍 언어와 브라우저를 지원하는 데 강점이 있다. 그러나 설정이 복잡하고 실행 속도가 상대적으로 느리다는 단점이 있다. 사이프레스는 개발자 경험(DevEx)에 중점을 두어 설치와 사용이 쉽고, 실시간 리로딩과 디버깅 도구가 우수하다. 하지만 크로미움 계열 브라우저에 제한적이며, 다중 브라우저나 도메인 간 테스트에는 약점을 보인다.
플레이라이트는 비교적 최신 도구로, 셀레니움의 광범위한 브라우저 지원과 사이프레스의 개발자 친화적 경로를 결합하려는 시도이다. 단일 API로 여러 브라우저 엔진을 제어하며, 네트워크 모의와 자동 대기 기능이 내장되어 있어 안정적이고 빠른 테스트 작성이 가능하다. 또한 마이크로소프트가 주도하여 개발하고 있어 지속적인 업데이트와 개선이 활발히 이루어지고 있다.
Playwright Test Runner는 Playwright의 핵심 구성 요소로, E2E 테스트 및 웹 자동화 스크립트를 실행하고 관리하기 위한 전용 도구이다. Node.js 환경에서 동작하며, Jest나 Mocha와 같은 범용 테스트 러너와 달리 웹 애플리케이션 테스트에 특화된 기능을 내장하고 있다.
주요 기능으로는 테스트 병렬 실행, 자동 재시도, 스냅샷 테스트, 테스트 리포트 생성 등이 있다. 테스트는 기본적으로 격리된 컨텍스트에서 실행되어 안정성을 보장하며, 실패한 테스트에 대한 풍부한 진단 정보(자동 생성된 트레이스 뷰어, 스크린샷, 실행 비디오)를 제공한다. 구성은 playwright.config.ts(또는 .js) 파일을 통해 관리되며, 브라우저 종류, 실행 옵션, 타임아웃, 기기 에뮬레이션 설정 등을 중앙에서 제어할 수 있다.
다음은 Playwright Test Runner의 주요 구성 옵션 예시이다.
옵션 | 설명 | 기본값 예시 |
|---|---|---|
| 테스트 파일이 위치한 디렉토리 |
|
| 모든 테스트를 병렬 실행할지 여부 |
|
| 실패한 테스트의 재시도 횟수 |
|
| 리포트 출력 형식 (예: |
|
| 테스트에 사용할 기본 URL |
|
| 브라우저 뷰포트 크기 |
|
이 러너는 @playwright/test 패키지에 포함되어 있으며, npx playwright test 명령어로 실행한다. CI/CD 환경과의 통합을 염두에 두고 설계되어, 다양한 리포트 포맷 출력과 쉬운 구성 관리로 지속적인 테스트 실행에 적합하다.
Playwright는 내장된 스크린샷 비교 기능을 통해 시각적 회귀 테스트를 수행하는 데 효과적인 도구이다. expect(page).toHaveScreenshot() 어설션을 사용하면 특정 DOM 상태나 사용자 흐름의 스크린샷을 캡처하고, 이를 사전에 정의된 기준 스크린샷(baseline)과 픽셀 단위로 비교할 수 있다. 이 과정에서 허용 오차 범위를 설정하거나 특정 요소를 비교에서 제외하는 것도 가능하다. 테스트 실행 시, 기준 스크린샷이 없으면 자동으로 생성되며, 이후 실행에서는 새 스크린샷과 지속적으로 비교하여 시각적 차이를 감지한다.
Playwright Test 러너는 시각적 테스트를 위한 몇 가지 유용한 구성을 제공한다. 예를 들어, playwright.config.ts 파일에서 screenshot 옵션을 'on' (실패 시만), 'off', 또는 'only-on-failure'로 설정할 수 있다. 또한 fullPage 옵션을 통해 전체 페이지를 캡처하거나, mask 옵션을 사용해 동적 콘텐츠(예: 광고 배너, 시간 표시)가 포함된 요소를 가려 테스트의 안정성을 높일 수 있다.
기능/옵션 | 설명 |
|---|---|
| 페이지 또는 특정 요소의 스크린샷을 기준과 비교하는 주요 어설션이다. |
| 스크린샷 비교 시 특정 요소를 가려 동적 콘텐츠로 인한 오류를 방지한다. |
| 허용할 수 있는 픽셀 차이의 최대 비율 또는 절대값을 설정한다. |
| 픽셀 차이를 감지하는 민감도(0에서 1 사이)를 조정한다. |
| CSS 애니메이션을 'disabled'로 설정하여 일관된 캡처를 보장한다. |
이러한 내장 기능 외에도 Playwright는 Percy나 Chromatic과 같은 전문 시각적 테스트 클라우드 서비스와의 통합도 지원한다. 이러한 서비스는 더 풍부한 비교 도구, 협업 기능, 그리고 히스토리 관리 대시보드를 제공하여 대규모 팀이나 복잡한 프로젝트에서 시각적 회귀를 체계적으로 관리하는 데 도움을 준다. 내장 스크린샷 비교는 로컬이나 CI 환경에서 빠르게 실행하기에 적합한 반면, 클라우드 서비스는 더 포괄적인 승인 워크플로우와 보고 체계가 필요한 경우 유용하다.
E2E 테스트와 Playwright는 개발 생산성과 소프트웨어 품질을 높이는 강력한 도구이지만, 그 구현과 유지보수 과정에는 때로 예상치 못한 재미와 도전이 따르곤 한다. 테스트 자동화를 진행하다 보면 마주치는 특이한 버그나 우스꽝스러운 실패 사례는 개발 팀 내에서 이야깃거리가 되기도 한다. 예를 들어, 애니메이션 타이밍에 민감한 요소를 검증할 때 테스트는 실패했지만 실제 사용자 눈에는 문제가 없는 경우[8], 혹은 테스트 환경에서만 나타나는 유령 같은 요소를 찾아 헤매는 경험은 많은 엔지니어가 공감할 만한 일이다.
이러한 도전은 때로 창의적인 해결책을 낳는다. 네트워크 상태를 의도적으로 불안정하게 만들어서 오류 처리 로직을 검증하거나, 시스템 시간을 조작하여 기한이 지난 콘텐츠의 표시를 테스트하는 등의 시나리오는 Playwright의 고급 기능을 활용해 구현할 수 있다. 또한, 테스트 스크립트의 이름을 재치 있게 짓거나[9], 실패한 테스트의 스크린샷을 모아 팀 내부에 공유하는 것은 업무에 작은 유머를 더하는 방법이 된다.
궁극적으로, 이러한 '여담'의 경험들은 단순한 코드 검증을 넘어서, 소프트웨어와 사용자 사이의 복잡한 상호작용을 더 깊이 이해하는 계기가 된다. 테스트를 작성하는 과정 자체가 애플리케이션의 동작과 사용자 경험에 대한 새로운 통찰을 제공하기 때문이다. 따라서 E2E 테스트는 버그를 찾는 기계적인 작업이 아니라, 제품을 다양한 각도에서 바라보고 개선점을 발견하는 지적인 탐험으로 여겨질 수 있다.