pgms

[18주차] - [9기] 타입스크립트로 함께하는 웹 풀 사이클 개발(React, Node.js) 10회차 - 82

Ejah 2026. 5. 14. 23:15

Selenium을 활용한 E2E 테스트 자동화 완벽 가이드

들어가며

웹 서비스를 개발하다 보면 가장 많이 듣게 되는 말 중 하나가 바로 “테스트는 중요하다”라는 이야기다. 실제로 기능 하나를 수정했는데 전혀 예상하지 못한 곳에서 오류가 발생하거나, 배포 이후 특정 기능이 동작하지 않는 상황은 생각보다 자주 발생한다. 특히 프론트엔드와 백엔드가 함께 동작하는 서비스에서는 단순한 단위 테스트만으로는 실제 사용자의 행동 흐름을 완벽하게 검증하기 어렵다.

예를 들어 회원가입 → 로그인 → 게시글 작성 → 댓글 작성 → 로그아웃과 같은 흐름은 여러 API와 UI, 상태 관리 로직이 동시에 연결되어 있다. 이런 흐름은 각 기능이 따로 정상 동작하더라도 실제 사용 환경에서는 예상치 못한 문제가 발생할 수 있다.

이때 중요한 역할을 하는 것이 바로 E2E(End-to-End) 테스트이다.

E2E 테스트는 실제 사용자가 서비스를 사용하는 것처럼 브라우저를 직접 조작하면서 전체 흐름을 검증하는 테스트 방식이다. 그리고 이러한 E2E 테스트 자동화 도구 중 가장 대표적인 것이 Selenium이다.

이번 글에서는 Selenium이 무엇인지부터 시작해 Selenium IDE, Selenium WebDriver, E2E 테스트 전략, 테스트 자동화의 장점과 한계, 실제 프로젝트 적용 방법까지 자세하게 정리해보려고 한다.


Selenium이란?

Selenium은 웹 브라우저를 자동으로 제어할 수 있도록 도와주는 오픈소스 테스트 자동화 프레임워크이다.

쉽게 말하면 사람이 직접 브라우저를 클릭하고 입력하는 행동을 코드로 대신 수행할 수 있도록 만들어주는 도구라고 볼 수 있다.

예를 들어 아래와 같은 행동을 자동으로 수행할 수 있다.

  • 특정 웹사이트 접속
  • 로그인 버튼 클릭
  • 입력창에 텍스트 입력
  • 게시글 작성
  • 페이지 이동 검증
  • 특정 요소 존재 여부 확인
  • 버튼 활성화 상태 확인
  • 경고창 처리
  • 파일 업로드
  • 스크롤 이동
  • 페이지 렌더링 대기

즉, 사용자의 실제 행동을 자동화해서 테스트할 수 있는 것이다.

Selenium은 다양한 브라우저를 지원한다.

  • Chrome
  • Firefox
  • Edge
  • Safari

또한 여러 프로그래밍 언어에서도 사용할 수 있다.

  • JavaScript
  • TypeScript
  • Java
  • Python
  • C#
  • Ruby

특히 최근에는 React, Vue, Next.js 같은 프론트엔드 프레임워크 기반 프로젝트에서도 E2E 테스트의 중요성이 커지면서 Selenium이나 Playwright, Cypress 같은 자동화 도구 사용이 점점 증가하고 있다.


E2E 테스트란?

E2E는 End-to-End의 약자로, 서비스의 전체 흐름을 처음부터 끝까지 검증하는 테스트를 의미한다.

보통 테스트는 크게 세 가지로 나뉜다.

종류설명

단위 테스트(Unit Test) 함수나 컴포넌트 하나를 테스트
통합 테스트(Integration Test) 여러 모듈이 함께 동작하는지 테스트
E2E 테스트 실제 사용자 흐름 전체 테스트

예를 들어 로그인 기능을 테스트한다고 가정해보자.

단위 테스트

expect(validatePassword("1234")).toBe(false);

비밀번호 검증 함수 하나만 테스트한다.

통합 테스트

로그인 API 호출 후 토큰 저장 여부 확인

프론트와 API 연결 정도를 테스트한다.

E2E 테스트

1. 로그인 페이지 접속
2. 이메일 입력
3. 비밀번호 입력
4. 로그인 버튼 클릭
5. 메인 페이지 이동 확인

실제 사용자가 행동하는 전체 흐름을 테스트한다.

즉, E2E 테스트는 가장 현실적인 테스트 방식이라고 볼 수 있다.


Selenium의 주요 구성 요소

Selenium은 단순히 하나의 도구가 아니라 여러 구성 요소로 이루어져 있다.

1. Selenium IDE

Selenium IDE는 브라우저 확장 프로그램 형태로 제공되는 도구이다.

사용자가 직접 브라우저를 조작하면 그 행동을 자동으로 기록해준다.

예를 들어 아래와 같은 행동을 기록할 수 있다.

  • 클릭
  • 입력
  • 페이지 이동
  • 요소 선택
  • 검증

초보자도 쉽게 테스트 케이스를 만들 수 있다는 장점이 있다.

특히 테스트 자동화를 처음 접하는 사람에게 매우 좋은 입문 도구라고 생각한다.

Selenium IDE 장점

  • 코드 없이 테스트 가능
  • 브라우저 조작만으로 테스트 생성 가능
  • 빠른 테스트 프로토타입 작성 가능
  • 간단한 기능 검증에 적합

Selenium IDE 단점

  • 복잡한 로직 구현 어려움
  • 유지보수 어려움
  • 동적 UI 대응 한계
  • 대규모 프로젝트에는 부적합

즉, 간단한 테스트에는 매우 유용하지만 실제 서비스 수준의 자동화에는 한계가 있다.


2. Selenium WebDriver

실제 프로젝트에서 가장 많이 사용하는 핵심 기능이다.

WebDriver는 코드로 브라우저를 직접 제어할 수 있게 해준다.

예를 들어 JavaScript에서는 아래와 같이 사용할 수 있다.

const { Builder, By } = require("selenium-webdriver");

(async function example() {
  let driver = await new Builder().forBrowser("chrome").build();

  await driver.get("https://example.com/login");

  await driver.findElement(By.name("email")).sendKeys("test@test.com");

  await driver.findElement(By.name("password")).sendKeys("1234");

  await driver.findElement(By.css("button")).click();
})();

실제 브라우저를 실행하고 사용자 행동을 그대로 자동화한다.


3. Selenium Grid

Selenium Grid는 여러 환경에서 테스트를 동시에 실행할 수 있도록 도와주는 기능이다.

예를 들어 아래와 같은 테스트가 가능하다.

  • Chrome + Windows
  • Safari + macOS
  • Firefox + Linux

대규모 서비스에서는 다양한 브라우저 호환성이 매우 중요하기 때문에 Grid 기능이 자주 활용된다.


Selenium을 사용하는 이유

1. 실제 사용자 환경 테스트 가능

가장 큰 장점이다.

단순 함수 테스트가 아니라 실제 브라우저를 기반으로 테스트하기 때문에 현실적인 오류를 발견할 수 있다.

예를 들어 아래와 같은 문제를 발견할 수 있다.

  • 버튼 클릭이 안 되는 문제
  • CSS 때문에 요소가 가려지는 문제
  • 모바일 반응형 깨짐
  • 브라우저 호환성 문제
  • API 응답 지연 문제
  • 렌더링 타이밍 문제

이런 문제는 단위 테스트만으로는 발견하기 어렵다.


2. 반복 작업 자동화

매번 수동으로 테스트하는 것은 매우 비효율적이다.

특히 배포 전마다 아래와 같은 작업을 반복한다고 생각해보자.

  • 로그인 테스트
  • 회원가입 테스트
  • 결제 테스트
  • 게시글 작성 테스트
  • 관리자 권한 테스트

기능이 많아질수록 테스트 시간은 기하급수적으로 증가한다.

하지만 Selenium을 활용하면 버튼 클릭부터 결과 검증까지 모두 자동으로 수행할 수 있다.

즉, 개발자는 더 중요한 문제 해결에 집중할 수 있게 된다.


3. 회귀 테스트에 강함

회귀 테스트는 기존 기능이 정상 동작하는지 다시 확인하는 테스트이다.

예를 들어 로그인 기능을 수정했는데 게시글 작성 기능이 갑자기 깨지는 상황이 발생할 수 있다.

Selenium 기반 자동화 테스트가 있다면 이런 문제를 빠르게 발견할 수 있다.

실제 현업에서는 새로운 기능 개발보다 기존 기능 유지보수 비중이 훨씬 커지는 경우가 많다.

따라서 회귀 테스트 자동화는 프로젝트 안정성에 매우 중요한 역할을 한다.


Selenium 테스트 전략

테스트 자동화를 무조건 많이 만든다고 좋은 것은 아니다.

잘못 설계된 테스트는 오히려 유지보수 비용만 증가시킨다.

따라서 테스트 전략이 매우 중요하다.

1. 핵심 사용자 흐름 우선 테스트

가장 중요한 흐름부터 자동화하는 것이 좋다.

예를 들어 쇼핑몰 서비스라면 다음 흐름이 핵심이다.

회원가입 → 로그인 → 상품 조회 → 장바구니 → 결제

이 흐름이 깨지면 서비스 자체가 동작하지 않는 수준의 문제가 발생한다.

따라서 가장 먼저 자동화해야 한다.


2. 지나치게 세부적인 UI 테스트 지양

예를 들어 아래와 같은 테스트는 유지보수 비용이 매우 크다.

버튼 너비가 정확히 120px인지 확인

UI는 자주 변경되기 때문에 너무 세부적인 테스트는 오히려 독이 될 수 있다.

대신 실제 사용자 기능 중심으로 테스트하는 것이 중요하다.

예를 들어:

로그인 버튼 클릭 시 메인 페이지 이동 여부 확인

이런 테스트가 훨씬 가치가 높다.


3. 테스트 독립성 유지

테스트끼리 서로 영향을 주지 않도록 구성해야 한다.

예를 들어 회원가입 테스트가 실패했다고 로그인 테스트까지 실패하면 원인 파악이 어려워진다.

따라서 테스트는 가능한 독립적으로 설계하는 것이 중요하다.


Selenium IDE를 활용한 테스트 케이스 개발

Selenium IDE는 테스트 자동화 입문 단계에서 매우 유용하다.

특히 QA나 비개발 직군도 쉽게 테스트를 만들 수 있다는 장점이 있다.

테스트 케이스 예시

로그인 테스트

1. 로그인 페이지 접속
2. 이메일 입력
3. 비밀번호 입력
4. 로그인 버튼 클릭
5. 메인 페이지 이동 확인

Selenium IDE는 이 과정을 자동으로 기록한다.

그리고 저장된 테스트는 반복 실행할 수 있다.


Selenium WebDriver 실전 예제

프로젝트 설치

npm install selenium-webdriver

ChromeDriver도 필요하다.

npm install chromedriver

기본 테스트 코드

const { Builder, By, until } = require("selenium-webdriver");

(async function test() {
  let driver = await new Builder().forBrowser("chrome").build();

  try {
    await driver.get("https://example.com/login");

    await driver.findElement(By.name("email")).sendKeys("test@test.com");

    await driver.findElement(By.name("password")).sendKeys("1234");

    await driver.findElement(By.css("button")).click();

    await driver.wait(until.urlContains("dashboard"), 5000);

    console.log("로그인 성공");
  } finally {
    await driver.quit();
  }
})();

이 코드는 실제 브라우저를 실행한 뒤 로그인 과정을 자동으로 수행한다.


동적 페이지 테스트 시 주의할 점

최근 웹 서비스는 대부분 React, Vue 같은 SPA 구조를 사용한다.

이 경우 비동기 렌더링 때문에 테스트가 실패하는 경우가 많다.

예를 들어 버튼이 아직 렌더링되지 않았는데 클릭하려고 하면 오류가 발생한다.

따라서 적절한 대기 처리가 매우 중요하다.

잘못된 방식

await driver.sleep(3000);

단순 sleep은 비효율적이다.


좋은 방식

await driver.wait(until.elementLocated(By.id("submit")), 5000);

요소가 실제로 나타날 때까지 기다리는 방식이 훨씬 안정적이다.


E2E 테스트 자동화의 장점

안정적인 배포 가능

자동화 테스트가 있으면 배포 전 검증이 쉬워진다.

CI/CD 파이프라인과 연결하면 아래 흐름이 가능하다.

코드 Push → 자동 테스트 → 성공 시 배포

즉, 사람이 직접 테스트하지 않아도 된다.


개발 속도 향상

처음에는 테스트 작성 시간이 오래 걸린다.

하지만 프로젝트 규모가 커질수록 자동화의 효과가 엄청나게 커진다.

특히 반복 테스트 시간이 크게 줄어든다.


협업 효율 증가

프론트엔드와 백엔드가 동시에 개발할 때 자동화 테스트는 매우 큰 도움이 된다.

API 변경이나 UI 변경이 발생했을 때 즉시 문제를 발견할 수 있기 때문이다.


Selenium의 한계

물론 Selenium이 완벽한 도구는 아니다.

테스트 속도가 느림

실제 브라우저를 실행하기 때문에 단위 테스트보다 훨씬 느리다.


유지보수 비용 존재

UI가 자주 바뀌면 테스트 코드도 계속 수정해야 한다.

특히 CSS selector 기반 테스트는 쉽게 깨질 수 있다.


비동기 처리 어려움

렌더링 타이밍 문제 때문에 flaky test가 발생하기 쉽다.

flaky test란 가끔 성공하고 가끔 실패하는 불안정한 테스트를 의미한다.


좋은 테스트 코드 작성 방법

1. data-testid 사용

<button data-testid="login-button">로그인</button>
By.css('[data-testid="login-button"]')

이렇게 작성하면 UI 변경에도 테스트가 덜 깨진다.


2. Page Object Pattern 활용

페이지별 로직을 분리하면 유지보수가 쉬워진다.

LoginPage.js

class LoginPage {
  async login(email, password) {
    // 로그인 로직
  }
}

이런 방식으로 구조화하면 테스트 코드 재사용성이 높아진다.


3. 테스트 데이터 분리

하드코딩 대신 별도 데이터 파일을 사용하는 것이 좋다.

const testUser = {
  email: "test@test.com",
  password: "1234",
};

CI/CD와 Selenium 연동

실무에서는 GitHub Actions와 함께 사용하는 경우가 많다.

GitHub Actions 예시

name: E2E Test

on: [push]

jobs:
  test:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3

      - name: Install Dependencies
        run: npm install

      - name: Run Selenium Tests
        run: npm run test:e2e

이렇게 설정하면 코드가 Push될 때마다 자동으로 E2E 테스트가 실행된다.


실제 프로젝트에서 느낀 점

테스트 자동화는 처음에는 굉장히 귀찮게 느껴질 수 있다.

특히 기능 개발 일정이 촉박한 상황에서는 테스트 코드 작성이 우선순위에서 밀리는 경우가 많다.

하지만 프로젝트 규모가 커질수록 테스트 자동화의 중요성은 압도적으로 커진다.

특히 여러 명이 협업하는 프로젝트에서는 예상치 못한 사이드 이펙트가 자주 발생한다.

이때 자동화 테스트는 단순한 품질 관리 수준을 넘어 개발 안정성을 지켜주는 안전망 역할을 하게 된다.

또한 Selenium 기반 E2E 테스트를 경험하면서 느낀 가장 큰 점은 “사용자 관점으로 기능을 바라보게 된다”는 점이었다.

단순히 API가 성공했다고 끝나는 것이 아니라:

  • 실제 버튼이 눌리는지
  • 페이지 이동이 자연스러운지
  • 로딩 중 문제가 없는지
  • 렌더링 타이밍 오류는 없는지
  • 브라우저별 차이가 없는지

이런 부분까지 확인하게 된다.

즉, 테스트 자동화는 단순 검증 도구가 아니라 더 좋은 사용자 경험을 만들기 위한 과정이라고 생각한다.


마무리

Selenium은 오랫동안 사용되어 온 대표적인 웹 테스트 자동화 도구이다.

특히 E2E 테스트를 통해 실제 사용자 흐름을 검증할 수 있다는 점에서 매우 강력한 장점을 가지고 있다.

물론 테스트 속도나 유지보수 같은 한계도 존재하지만, 프로젝트 규모가 커질수록 자동화 테스트의 가치는 더욱 커진다.

특히 최근에는 CI/CD 환경과 결합되면서 테스트 자동화가 거의 필수 요소처럼 자리 잡고 있다.

처음에는 Selenium IDE로 간단한 테스트를 경험해보고, 이후 WebDriver 기반 코드 자동화로 확장해나가는 방식이 가장 좋은 학습 흐름이라고 생각한다.

결국 안정적인 서비스를 만드는 가장 좋은 방법은 “문제가 발생하기 전에 미리 검증하는 것”이다.

그리고 Selenium 기반 E2E 테스트 자동화는 그 검증을 가능하게 만들어주는 매우 강력한 도구라고 할 수 있다.