Playwright vs. Selenium: 2026년 아키텍처 리뷰
I’m happy to translate the article for you, but I need the full text of the post (the sections you’d like translated). Could you please paste the article’s content here? I’ll keep the source line, formatting, code blocks, and URLs exactly as they are and translate the rest into Korean.
소개: API 표면을 넘어
2026년이 되면서 Playwright와 Selenium 사이의 논쟁은 이제 “문법 선호도”나 “언어 지원” 수준을 넘어섰다. 시니어 자동화 아키텍트에게 선택은 driver.find_element를 선호하느냐 page.locator를 선호하느냐가 아니라 인프라 토폴로지와 프로토콜 효율성에 관한 근본적인 결정이다.
과거에 브라우저 자동화는 “스크립팅”으로 여겨졌다: 버튼을 클릭하라는 명령을 보내고 결과를 기다리는 것이 전부였다. 오늘날에는 이것이 분산 인프라의 핵심 레이어가 되었다. 우리는 일시적인 컨테이너에서 테스트를 실행하고, 공격적인 WAF 뒤에서 데이터를 스크랩하며, 하드웨어에 결합된 자격 증명으로 보호된 복잡한 인증을 자동화한다. 이런 고위험 환경에서는 자동화 도구의 기본 아키텍처가 신뢰성, 속도, 유지보수성을 좌우한다.
본 리뷰에서는 Selenium(특히 W3C WebDriver BiDi 진화 포함)과 Playwright의 내부 메커니즘을 해부한다. 2004년에 내려진 설계 결정이 오늘날까지 Selenium을 제한하는 이유와, Playwright의 “headless‑first” 이벤트 루프가 현대 웹 현실에 어떻게 부합하는지를 분석한다.
두 프레임워크를 가장 크게 구분 짓는 요소는 브라우저를 구동하는 통신 프로토콜이다. 이는 구현 세부 사항이 아니라 두 프레임워크 간 거의 모든 성능 및 안정성 차이의 근본 원인이다.
Source: …
Selenium의 아키텍처
Selenium은 WebDriver W3C 표준 위에 구축되어 있으며, 본질적으로 RESTful HTTP 프로토콜입니다. Selenium 스크립트의 모든 동작은 개별 HTTP 요청을 트리거합니다:
Client → POST /session/{id}/element (Find element)
Driver → receives request, translates to browser internal command,
waits for browser, returns JSON response
Client ← parses JSON
Client → POST /session/{id}/element/{id}/click (Click element)
Driver → receives request, executes click, returns JSON
Client ← parses JSON
결과
- 대화형 통신 → 제어 루프 지연을 발생시킵니다.
- 각 명령은 네트워크 오버헤드, 직렬화 및 역직렬화를 수반합니다.
- 로컬 환경에서는 이 지연이 미미합니다(밀리초 수준).
- 분산 그리드(예: Sauce Labs, BrowserStack, CI 러너)에서는 왕복 시간이 누적되어 “정지‑후‑실행” 방식의 실행 리듬이 형성되고, 이는 본질적으로 느리며 레이스 컨디션에 취약합니다.
Playwright의 아키텍처
Playwright는 표준 HTTP를 포기하고 단일, 지속적인 WebSocket 연결(Chrome DevTools Protocol – CDP 또는 Firefox/WebKit 등가물을 활용)을 사용합니다. 연결이 설정되면 채널은 열려 있습니다.
주요 특성
| 특징 | 설명 |
|---|---|
| 양방향 | 브라우저가 스크립트에 이벤트를 푸시할 수 있습니다(예: “네트워크 요청 실패”, “DOM 노드 추가”) 스크립트가 요청하지 않아도. |
| 명령 배치 | Playwright는 HTTP 핸드쉐이크를 기다리지 않고 파이프를 통해 여러 명령을 보낼 수 있습니다. |
| 낮은 오버헤드 | 바이너리 데이터(예: 스크린샷)는 JSON 페이로드에 흔히 있는 대용량 Base64 오버헤드 없이 효율적으로 스트리밍됩니다. |
자동 대기 vs. 명시적 대기
시니어 엔지니어들은 Playwright의 Auto‑Wait을 핵심 기능으로 자주 언급합니다. 이 기능이 아키텍처적으로 어떻게 동작하는지를 이해하면 Selenium이 “Explicit Wait”를 사용하더라도 이를 재현하기 어려운 이유를 알 수 있습니다.
Selenium (Explicit Wait)
- 대기 로직이 클라이언트 스크립트(Python/Java/C#)에 존재합니다.
- 스크립트는 브라우저 드라이버에 HTTP 요청을 반복적으로 보내며 폴링합니다:
"Is it visible? No. (Wait 500 ms). Is it visible? No. (Wait 500 ms). Is it visible? Yes."
- 이 과정에서 네트워크 트래픽이 발생하고 경쟁 조건 창이 생깁니다—요소가 폴링 간격 사이에 잠깐 보였다가 사라질 수 있어 테스트가 불안정해집니다.
Playwright (Auto‑Wait)
- Playwright는 로케이터 로직을 컴파일하여 CDP 세션을 통해 브라우저 컨텍스트에 직접 주입합니다.
- “대기”는 브라우저 자체 이벤트 루프 안에서 이루어집니다(
requestAnimationFrame및 페인팅 사이클과 정렬됨). - 요소의 안정성(바운딩 박스 움직임)과 작동 가능성(z‑index 오버레이) 등을 애플리케이션과 동일한 렌더 루프에서 검사합니다.
- “클릭” 명령은 브라우저가 요소가 준비되었음을 확인했을 때만 실행됩니다—외부 폴링에서 발생하는 경쟁 조건을 없애는 원자적 Check‑and‑Act 방식입니다.
네트워크 제어
2026년 현재 자동화는 버튼 클릭에만 그치지 않는다. API 응답을 모킹하고, 헤더를 주입하며, 분석 트래커를 차단하는 작업이 흔히 요구된다.
Selenium
- 과거에는 Man‑in‑the‑Middle (MITM) 프록시(예: BrowserMob)를 사용해 네트워크 트래픽을 가로채야 했다.
- 단점: 인증서 신뢰 문제, 처리량 감소, 복잡한 인프라 구축.
- Selenium 4+에서는
NetworkInterceptor를 도입했지만, 이는 WebDriver 프로토콜 위에 얹은 임시방편에 불과해 세밀한 제어가 어렵고 브라우저 간 호환성 문제가 발생하기 쉽다.
Playwright
- CDP 기반 아키텍처 덕분에 무료로 네트워크 제어가 가능하다.
- 브라우저의 네트워크 스택과 렌더링 엔진 사이에 위치해 요청을 네이티브하게 일시 중지, 수정, 중단할 수 있다(프록시 서버가 필요 없음).
장점
- Zero‑latency 모킹 – 요청이 브라우저 프로세스를 떠나지 않는다.
- 신뢰성 – 호스트 머신에 SSL 인증서를 설치할 필요가 없다.
- 세밀함 – 라우팅 로직(글롭 패턴, 정규식)이 즉시 평가된다.
WebDriver BiDi의 현실
Selenium 5는 WebDriver BiDi를 완전히 수용했으며, 이는 WebDriver 표준에 양방향 통신(WebSockets)을 도입하기 위한 표준화된 노력입니다. 이것이 Selenium이 Playwright에 대응하는 방식입니다.
Playwright의 장점
- Single Page Application (SPA) 혁명 이후, Playwright의 Browser Context 모델은 단일 브라우저 프로세스 내에서 수백 개의 격리된, 인코그니토와 유사한 프로필을 허용함으로써 Selenium의 “One Driver = One Browser” 모델에 비해 아키텍처적 도약을 의미합니다.
- 이는 Playwright를 컨테이너화된 환경(Kubernetes/Docker)에서 대규모로 실행할 때 지수적으로 비용이 절감된다는 것을 의미합니다.
Selenium을 고수해야 할 때와 Playwright를 도입해야 할 때
| 시나리오 | 추천 도구 |
|---|---|
| 맞춤형 WebDriver 확장에 많은 투자를 한 기존 대규모 Selenium 테스트 스위트 | Selenium (계속 사용, 필요 시 Selenium 5와 BiDi로 업그레이드) |
| 특히 대규모 환경에서 CI/CD 파이프라인의 초고속, 불안정성 없는 실행이 필요할 때 | Playwright |
| 네트워크 수준의 대규모 모킹, 요청 가로채기, 혹은 지연 없는 API 스터빙이 필요할 때 | Playwright |
| Playwright 바인딩이 아직 성숙하지 않은 Ruby, PHP 등 다양한 언어 지원이 필요한 프로젝트 | Selenium |
| 단일 지속적인 WebSocket 연결과 내장 자동 대기 메커니즘을 중시하는 팀 | Playwright |
| 프록시 기반 네트워크 가로채기가 이미 구축돼 있어 변경할 수 없는 환경 | Selenium ( NetworkInterceptor 혹은 외부 프록시 사용) |
Selenium (w/ BiDi) vs. Playwright
| Feature | Selenium (BiDi) | Playwright |
|---|---|---|
| Primary Protocol | HTTP (RESTful) | WebSocket (event‑driven) |
| Wait Mechanism | External polling | Internal event loop (RAF) |
| Language Support | Java, C#, Python, Ruby, JavaScript | TypeScript/JavaScript, Python, Java, .NET |
| Legacy Browser Support | Excellent (IE Mode) | Non‑existent (modern engines only) |
| Mobile Support | Appium (native apps) | Experimental / web‑only |
| Scale / Cost | High – 1 process per test | Low – multiple contexts per process |
Selenium을 고수해야 할 때
- 레거시 브라우저(예: IE 11) 또는 특정 구버전 Chrome/Firefox를 테스트해야 할 때.
- 네이티브 모바일 테스트를 위해 Appium과 깊게 통합된 자동화일 때.
- 팀이 주로 **Java 또는 C#**으로 작업하고 동기식, 블로킹 API 스타일을 선호할 때.
Playwright로 전환해야 할 때
- 현대적인 SPA(React, Vue, Angular)를 테스트하면서 컴포넌트 재렌더링으로 Selenium이 불안정할 때.
- 고성능 스크래핑 또는 데이터 추출이 필요하고 (네트워크 가로채기가 핵심)일 때.
- 별도 프로세스 대신 브라우저 컨텍스트를 활용해 CI/CD 인프라 비용을 30‑50 % 절감하고 싶을 때.
TL;DR (2026)
Playwright는 이제 더 이상 “더 나은 Selenium”이 아니다.
WebSocket을 통해 브라우저와 긴밀히 연결함으로써, 수십 년간 flaky 테스트를 야기했던 추상화 레이어를 없앤다.
- Selenium은 상호 운용성의 거인이자 표준 준수의 타이탄으로 남아 있다; 그 W3C WebDriver 기반은 언제 어디서나 영원히 실행될 것을 보장한다.
- Playwright는 다른 종류의 도구를 제공한다—그 아키텍처는 프로토콜 수준에서 동기화와 지연을 해결하여, sleep 문구 대신 테스트 로직에 집중할 수 있게 한다.
현대 웹 애플리케이션을 위한 신뢰성 높고 고속의 자동화 파이프라인을 구축하는 팀에게 Playwright는 최소 저항의 경로를 제공한다.