개념
2004년에 나온 도구를 지금 배우는 이유
Selenium은 2004년에 등장한 웹 자동화의 원조다. 모듈 13(레슨 2)의 Playwright가 2020년생인데도 오늘날 가장 많은 기업의 자동화 자산은 여전히 Selenium으로 쓰여 있다. 이 레슨의 목표는 문법 암기가 아니라 Playwright에서 익힌 개념이 Selenium에서 어떤 모양으로 나타나는지 알아보는 것 이다.
구조 차이 — 표준 프로토콜을 사이에 둔다
모듈 13(레슨 9)에서 Playwright는 브라우저 "밖", Cypress는 브라우저 "안"에서 실행된다고 배웠다. Selenium은 제3의 구조다.
Playwright: 테스트 코드 → (전용 프로토콜) → 브라우저 엔진 직접 제어
Cypress: 테스트 코드가 브라우저 안에서 함께 실행
Selenium: 테스트 코드 → WebDriver(W3C 표준 프로토콜)
→ 브라우저 드라이버(ChromeDriver 등) → 브라우저핵심은 가운데의 WebDriver 다. 특정 회사의 구현이 아니라 W3C 웹 표준 규격이다. "요소를 찾아라", "클릭해라" 같은 명령이 HTTP 요청 형태로 규격화돼 있고, 각 브라우저 벤더가 그 규격을 지키는 드라이버를 직접 만들어 배포한다. 이 표준 계층 한 겹이 Selenium의 특징 대부분을 설명한다.
| Selenium | Playwright | |
|---|---|---|
| 브라우저와의 연결 | W3C WebDriver 표준 프로토콜 | 자체 프로토콜로 엔진 직접 제어 |
| 지원 언어 | Java·Python·C#·JS·Ruby·Kotlin 등 | JS/TS·Python·Java·.NET |
| 브라우저 지원 | 드라이버를 만드는 모든 브라우저 | Chromium·Firefox·WebKit |
| 자동 대기 | 제한적 (직접 대기를 써야 할 때가 많음) | 기본 제공 |
언어 지원이 넓은 것은 프로토콜이 HTTP 규격이라 요청만 보낼 수 있으면 어떤 언어로든 클라이언트를 만들 수 있어서고, 브라우저 지원이 넓은 것은 브라우저를 만드는 회사가 자기 드라이버를 직접 책임지기 때문이다.
같은 시나리오, 다른 문법
모듈 13(레슨 2)의 로그인 예시를 Selenium(Python)으로 옮기면 이렇다.
def test_로그인에_성공하면_대시보드로_이동한다():
driver = webdriver.Chrome()
# Arrange — 페이지 접속
driver.get("https://example.com/login")
# Act — 로그인 정보 입력 후 제출
driver.find_element(By.ID, "email").send_keys("user@example.com")
driver.find_element(By.ID, "password").send_keys("password123")
driver.find_element(By.CSS_SELECTOR, "button[type=submit]").click()
# Assert — 대시보드로 이동했는지 확인
WebDriverWait(driver, 10).until(EC.url_contains("dashboard"))
assert "환영합니다" in driver.page_source
driver.quit()page.goto ↔ driver.get, getByLabel(...).fill ↔
find_element(...).send_keys. 모듈 10(레슨 1)의 AAA 패턴도 그대로다.
개념은 같고 문법만 다르다 는 모듈 13(레슨 9)의 결론이 반복된다.
다만 두 가지가 눈에 띄게 다르다. 브라우저를 직접 열고(webdriver.Chrome())
직접 닫아야(driver.quit()) 한다는 것, 그리고 검증 앞에 붙은
WebDriverWait 다.
명시적 대기 — Selenium 플래키의 최대 원인
Playwright는 요소가 나타나고 클릭 가능해질 때까지 알아서 기다린다(모듈 13 레슨 2, 레슨 5). Selenium의 암묵적 대기(implicit wait)는 "DOM에서 찾을 때까지"만 기다릴 뿐 화면에 보이는지·클릭 가능한지는 보장하지 않는다. 그래서 조건을 직접 명시한다.
time.sleep(3) # 안티패턴 (모듈 13 레슨 5)
WebDriverWait(driver, 10).until( # 조건을 명시해서 기다린다
EC.element_to_be_clickable((By.ID, "submit"))
).click()WebDriverWait(driver, 10)은 "최대 10초 동안 조건이 참이 될 때까지 짧은
간격으로 반복 확인한다"는 뜻이다. 1초 만에 충족되면 1초만 쓴다.
이 한 줄을 빼먹는 것이 Selenium 테스트가 플래키해지는 가장 흔한 원인 이다. 로컬에서는 화면이 빨리 그려져 통과하고, 부하가 걸린 CI에서는 렌더링이 0.5초 늦어져 실패한다. 모듈 13(레슨 6)의 "환경에 따라 결과가 달라지는 불안정한 테스트"의 교과서적 사례다.
왜 아직도 Selenium인가
"오래됐다"는 단점이 아니라 오히려 이유다.
- 관성 — 수천 개의 테스트가 이미 Selenium으로 쓰인 회사가 많다. 전부 옮기는 비용은 모듈 13(레슨 1)의 ROI 관점에서 대개 정당화되지 않는다
- 자산과 언어 — 20년치 커뮤니티 답변이 쌓여 있고, 팀 주력 언어가 Java나 C#이면 선택지가 사실상 Selenium이다
- Selenium Grid — 여러 머신에 브라우저를 띄워 분산 실행하는 공식 도구다. 500개 테스트를 10대에 나눠 돌리거나 Chrome·Firefox·Edge에 동시에 태울 수 있다 — 모듈 13(레슨 8) 크로스 브라우저 전략의 실행 수단이다
실무에서 왜 필요한가
이직해 들어간 팀의 자동화 자산이 Selenium인 경우는 매우 흔하다. 그때
필요한 능력은 이미 아는 Playwright 개념을 Selenium 코드 위에 올려 읽는
것 이다. find_element를 보면 "로케이터구나(모듈 13 레슨 3)",
WebDriverWait을 보면 "대기 전략을 직접 쓴 거구나(레슨 5)" 하고 알아볼 수
있으면 첫 주부터 코드 리뷰에 참여할 수 있다.
또 CI에서 간헐적으로 깨지는 Selenium 테스트를 만났을 때 sleep이 흩뿌려져
있는지, WebDriverWait이 빠졌는지 먼저 의심하는 것만으로 원인을 크게 좁힐
수 있다. QA가 자동화 팀에 넘기지 않고 스스로 1차 분석을 하는 지점이다.