Day 62 - 웹 기반 문서 편집기 제작 프로젝트 (2)

이유승·2025년 3월 17일

* 프로그래머스, 타입스크립트로 함께하는 웹 풀 사이클 개발(React, Node.js) 5기 강의 수강 내용을 정리하는 포스팅.

* 원활한 내용 이해를 위해 수업에서 제시된 자료 이외에, 개인적으로 조사한 자료 등을 덧붙이고 있음.


4-01. BE 단위 테스트

주요 내용

목적:

  • 백엔드의 개별 함수 및 API 엔드포인트(예: GET /users/me)의 독립적 동작을 검증
  • 데이터베이스, 쿠키 등 상태를 가지는 객체를 모킹(mock)하여 테스트 대상을 분리하고, TDD 방식 적용 가능하도록 지원

테스트 대상 및 흐름:

  • JWT 생성/검증 (jsonwebtoken 모듈 모킹)
  • 사용자 모델(User) 모킹
  • 미들웨어(authentication)와 라우터(users.ts)를 통한 실제 요청 처리 흐름 테스트

테스트 구성 요소:

  • Mock 파일:
    • src/models/__mocks__/user.ts: 사용자 모델(User) 모킹
    • __mocks__/jsonwebtoken.ts: JWT의 sign, verify, decode 함수를 모킹
  • 테스트 설정:
    • jest.config.jstsconfig.json을 통해 테스트 환경 설정

예시 테스트 케이스:

  • "GET /users/me" 요청에 대해, 올바른 JWT 쿠키가 전달되면 200 응답 및 사용자 정보 반환
  • JWT 쿠키가 없거나 잘못된 경우 401 (Unauthorized) 응답 처리

예시 테스트 코드:

// src/routes/users.test.ts
import request from "supertest";
import { app } from "../app";
import { User, MOCK_USERS } from "../models/__mocks__/user";

jest.mock("../models/user", () => jest.requireActual("../models/__mocks__/user"));

afterEach(() => {
    MOCK_USERS.splice(0, MOCK_USERS.length);
});

describe("GET /users/me", () => {
    test("올바른 JWT 쿠키가 설정되어있으면 유저 정보와 함께 200 응답을 받는다.", async () => {
      MOCK_USERS.push(new User(1, "apple@example.com", "mock_encrypted_apple123"));

      const response = await request(app)
        .get("/users/me")
        .set("Cookie", "access-token=mock_jwt_apple@example.com");

      expect(response.status).toBe(200);
      expect(response.body).toEqual({ email: "apple@example.com" });
    });
});

추가 고려 사항:

  • 모킹(mock)을 통한 테스트 분리 전략, 다양한 시나리오(예: 잘못된 토큰, 미존재 사용자) 추가
  • CI/CD 파이프라인에 테스트 스크립트(Makefile 등)를 포함하여 재현성 확보

4-02. FE 단위 테스트

주요 내용

목적:

  • 프론트엔드 컴포넌트(예: JoinForm)의 UI 요소 렌더링, 사용자 이벤트 처리, 상태 변화, 그리고 콜백 호출 등을 검증
  • 버튼 클릭, 링크 이동, 입력값 검증 등 사용자의 인터랙션에 따른 동작 테스트

테스트 요구 사항:

렌더링 테스트:

  • 이메일, 비밀번호, 비밀번호 확인 input, "회원가입" 버튼, "로그인하기" 링크가 DOM에 올바르게 생성되어 있는지 확인

이벤트 처리 테스트:

  • 올바른 입력 후 "회원가입" 버튼 클릭 시 onSubmit 콜백 호출
  • "로그인하기" 링크 클릭 시 URL이 "/login"으로 변경
  • 비밀번호와 비밀번호 확인 값 불일치 시 alert 메시지 발생하고 onSubmit 호출이 발생하지 않음

필요 라이브러리 및 설정:

  • 테스트 라이브러리:
    • @testing-library/jest-dom
    • @testing-library/react
    • @testing-library/user-event
  • 모듈 이름 매핑:
    • package.json의 jest 설정에서 moduleNameMapper를 통해 별칭 설정
  • 렌더링 도우미:
    • src/utils/test/renderWithRouter.ts 내의 renderWithRouter() 함수
  • 브라우저 이벤트 모킹:
    • src/setupTests.ts에서 window.alert() 모킹

예시 코드:

렌더링 테스트 예시:

// src/components/JoinForm.test.tsx - Case 1: 렌더링
test("잘 렌더링된다.", () => {
  renderWithRouter(<JoinForm />);
  expect(screen.getByLabelText("이메일", { selector: "input" })).toBeInTheDocument();
  expect(screen.getByLabelText("비밀번호", { selector: "input" })).toBeInTheDocument();
  expect(screen.getByLabelText("비밀번호 확인", { selector: "input" })).toBeInTheDocument();
  expect(screen.getByText("회원가입", { selector: "button" })).toBeInTheDocument();
  expect(screen.getByText("로그인하기", { selector: "a" })).toBeInTheDocument();
});

버튼 클릭 시 onSubmit 호출 예시:

// src/components/JoinForm.test.tsx - Case 2: 버튼 콜백
test("회원정보를 입력하고 회원가입 버튼을 누르면 onSubmit 콜백이 호출된다.", () => {
   const onSubmit = jest.fn();
   renderWithRouter(<JoinForm onSubmit={onSubmit} />);
   fireEvent.change(screen.getByLabelText("이메일"), { target: { value: "foo@example.com" } });
   fireEvent.change(screen.getByLabelText("비밀번호"), { target: { value: "1234" } });
   fireEvent.change(screen.getByLabelText("비밀번호 확인"), { target: { value: "1234" } });
   screen.getByText("회원가입", { selector: "button" }).click();
   expect(onSubmit).toBeCalledWith({ email: "foo@example.com", password: "1234" });
});

링크 이동 테스트 예시:

// src/components/JoinForm.test.tsx - Case 3: 링크 이동
test("로그인하기 버튼을 누르면 로그인 URL로 이동한다.", () => {
    renderWithRouter(<JoinForm />);
    fireEvent.click(screen.getByText("로그인하기"));
    expect(window.location.pathname).toBe("/login");
});

비밀번호 불일치 테스트 예시:

// src/components/JoinForm.test.tsx - Case 4: 입력 일치 검사
test("비밀번호 확인을 다르게 입력하면 alert 창이 뜨고 onSubmit 콜백이 호출되지 않는다.", () => {
    const alertSpy = jest.spyOn(window, "alert");
    const onSubmit = jest.fn();
    renderWithRouter(<JoinForm onSubmit={onSubmit} />);
    fireEvent.change(screen.getByLabelText("이메일"), { target: { value: "foo@example.com" } });
    fireEvent.change(screen.getByLabelText("비밀번호"), { target: { value: "1234" } });
    fireEvent.change(screen.getByLabelText("비밀번호 확인"), { target: { value: "123456" } });
    screen.getByText("회원가입", { selector: "button" }).click();
    expect(alertSpy).toBeCalledWith("비밀번호가  일치하지 않습니다.");
    expect(onSubmit).not.toBeCalled();
});

추가 고려 사항:

  • 테스트 케이스를 통해 UI 컴포넌트의 사용자 인터랙션과 에러 처리를 꼼꼼하게 검증
  • 향후 다른 컴포넌트, API, 훅 등에 대한 단위 테스트 확장을 고려

4-03. BE 의 컨테이너화

주요 내용

목적:

  • 백엔드 애플리케이션을 컨테이너화하여, 프로덕션 배포 환경 및 로컬 클러스터에서의 실행을 보장

방법:

  • Dockerfile, Docker Compose, Makefile 등을 이용하여 컨테이너 이미지 생성 및 테스트 절차 수립

컨테이너 실행 환경:

  • 프로덕션 배포:
    FE, BE, DB가 각각 컨테이너로 실행되며, AWS EC2, Nginx Reverse Proxy, DNS, 포트 매핑(예: 3031, 3306 등)을 통해 서비스됨
  • 로컬 클러스터:
    Docker Desktop을 이용한 로컬 테스트 환경 구성

BE 컨테이너 실행 구조:

  • Node.js (v18 기반)와 프로덕션 빌드된 백엔드 코드
  • 환경 변수(예: PORT, DB 설정, CORS_ALLOWED_ORIGIN 등)를 통해 컨테이너 내부 실행 환경 구성
  • 데이터베이스는 컨테이너 외부에 존재할 수 있음

Dockerfile 예시:

# ${PROJECT_ROOT}/backend/Dockerfile
FROM node:18

WORKDIR /var/app

COPY package.json package-lock.json ./
RUN npm ci --omit=dev

COPY ./build/ ./build/

ENV PORT=3031
# CORS_ALLOWED_ORIGIN=(...)

EXPOSE 3031

HEALTHCHECK CMD curl --fail http://localhost:3031/healthcheck || exit 1

ENTRYPOINT ["node", "."]

컨테이너 이미지 빌드 및 테스트:

  • Makefile:
    이미지 빌드, 테스트, 배포 등의 작업 자동화
  • Docker Compose:
    데이터베이스와 BE를 동일 네트워크 상에서 실행 후 Postman 등을 통한 독립 테스트 진행

추가 고려 사항:

  • 베이스 이미지(node:18) 선택 및 프로덕션 의존성 설치
  • 환경 변수와 건강 상태(healthcheck) 설정을 통한 안정성 확보

4-04. FE 의 컨테이너화

주요 내용

목적:

  • 프론트엔드 애플리케이션을 컨테이너화하여, 프로덕션 및 로컬 클러스터 환경에서 동작하도록 구성

실행 환경 설정:

  • 환경 변수 전달, 빌드 산출물(static 파일) 배포, Docker entrypoint 스크립트 등을 통해 실행 환경을 설정

컨테이너 실행 환경:

  • 프로덕션:
    FE, BE, DB가 컨테이너로 실행되며, AWS EC2, Nginx, Reverse Proxy 등과 연동
  • 로컬 클러스터:
    Docker Desktop 등을 이용한 로컬 테스트 환경 구성

FE 컨테이너 실행 구조 및 설정:

환경 변수 전달:

  • REACT_APP_ 으로 시작하는 환경 변수를 빌드 시 window._ENV 객체에 주입하기 위해, entrypoint 스크립트(docker-entrypoint.sh)를 작성

Docker entrypoint 스크립트 예시:

# ${PROJECT_ROOT}/frontend/docker-entrypoint.sh
#!/bin/bash
set -e
echo -n "" > ./build/env.js
echo "window._ENV={" >> ./build/env.js
for key in $(compgen -v | grep ^REACT_APP_); do
  echo "$key:'${!key}'," >> ./build/env.js
done
echo "}" >> ./build/env.js
exec serve -s build

Dockerfile 예시:

# ${PROJECT_ROOT}/frontend/Dockerfile
FROM node:18

WORKDIR /var/app

RUN npm install -g serve

COPY build ./build

EXPOSE 3000

COPY docker-entrypoint.sh /usr/local/bin/
RUN chmod u+x /usr/local/bin/docker-entrypoint.sh

ENTRYPOINT ["docker-entrypoint.sh"]

Makefile 및 Docker Compose:

  • Makefile:
    이미지 빌드, 테스트, 배포 타겟을 추가하여 CI/CD 환경에서 활용
  • docker-compose.yaml:
    FE 컨테이너의 포트(예: 3000) 및 환경 변수 설정

추가 고려 사항:

  • FE의 환경 변수 전달 방식(window._ENV)을 통한 런타임 설정 중요
  • Docker entrypoint 스크립트를 활용하여 빌드 산출물 내 env.js 파일 생성 및 동적 환경 변수 적용

4-05. 로컬 클러스터에 시험 배포

주요 내용

목적:

  • 로컬 클러스터 환경(예: Kubernetes)을 이용하여 FE, BE, DB를 통합 배포한 후, 실제 동작 여부를 검증
  • 프로덕션 배포를 염두에 둔 환경 구성을 로컬 테스트 환경에서 시험

배포 환경 구성:

프로덕션 배포 환경:

  • Frontend: 실제 BE URL (예: https://notes.prgms-fullcycle.com/api) 사용
  • Backend: DB 호스트/포트, FE URL 등 실제 운영 환경과 유사하게 구성

로컬 테스트 배포 환경:

  • FE: http://localhost:30030
  • BE: http://localhost:30031
  • DB: k8s 서비스 이름 (예: notes-db.db:3306) 이용

환경 변수 및 k8s 구성:

BE ConfigMap:

  • DB_HOST, DB_USER, DB_PASSWD, DB_NAME, CORS_ALLOWED_ORIGIN 등을 포함하여 설정

k8s Manifest 예시 (BE):

apiVersion: apps/v1
kind: Deployment
metadata:
  name: notes-be
  namespace: prgms-notes
spec:
  replicas: 1
  selector:
    matchLabels:
      run: notes-be
  template:
    metadata:
      labels:
        run: notes-be
    spec:
      containers:
      - name: notes-backend
        image: <Image to pull>
        imagePullPolicy: Always
        envFrom:
        - configMapRef:
            name: notes-be-config
---
apiVersion: v1
kind: Service
metadata:
  name: notes-be
  labels:
    run: notes-be
  namespace: prgms-notes
spec:
  type: NodePort
  selector:
    run: notes-be
  ports:
  - port: 3031
    targetPort: 3031
    nodePort: 30031

k8s Manifest 예시 (FE):

apiVersion: apps/v1
kind: Deployment
metadata:
  name: notes-fe
  namespace: prgms-notes
spec:
  selector:
    matchLabels:
      run: notes-fe
  replicas: 1
  template:
    metadata:
      labels:
        run: notes-fe
    spec:
      containers:
      - name: notes-frontend
        image: <Image to pull>
        imagePullPolicy: Always
        ports:
        - containerPort: 3000
        env:
        - name: REACT_APP_API_BASE_URL
          value: http://localhost:30031
---
apiVersion: v1
kind: Service
metadata:
  name: notes-fe
  labels:
    run: notes-fe
  namespace: prgms-notes
spec:
  type: NodePort
  selector:
    run: notes-fe
  ports:
  - port: 3000
    nodePort: 30030

Makefile 타겟:

  • make push, make deploy, make undeploy 등을 통해 이미지 빌드 및 k8s 적용

추가 고려 사항:

  • 프로덕션 배포와 유사한 환경에서의 인수 테스트(E2E 테스트) 필요
  • CI/CD 파이프라인에서 배포 스크립트, 환경 변수, k8s manifest의 변경 관리

5-01. Selenium 활용 기초

주요 내용 및 학습 요소

Selenium 개요:

  • Selenium은 브라우저 자동화 드라이버(WebDriver)를 제공하여 다양한 브라우저에서 자동화 테스트를 수행할 수 있도록 합니다.
  • Selenium IDE: 웹 사용자 상호작용을 기록(녹화)하고 재생하여 테스트 자동화에 활용됩니다.
  • Selenium Grid: 분산 환경에서 여러 테스트 머신에 테스트를 병렬로 실행할 수 있도록 지원합니다.

핵심 구성요소:

  • Selenium WebDriver: 브라우저 자동화 라이브러리
  • Selenium IDE: Chrome 또는 Firefox 확장 프로그램을 통해 테스트 시나리오 기록 및 재생
  • Selenium Grid: Hub/Node 구조로 테스트를 분산 실행

실습 예제 및 Docker 활용:

  • Docker를 이용해 Selenium standalone 컨테이너(예: selenium/standalone-chrome)를 실행합니다.

    docker run -d --rm -p 4444:4444 -v /dev/shm:/dev/shm selenium/standalone-chrome
  • Python 라이브러리 설치 후, 간단한 테스트 코드를 작성하여 원격 WebDriver에 접속하고 브라우저 자동화를 수행합니다.

테스트 코드 예시:

from selenium import webdriver
import time

print("Test Execution Started")

options = webdriver.ChromeOptions()
options.add_argument('--ignore-ssl-errors=yes')
options.add_argument('--ignore-certificate-errors')

driver = webdriver.Remote(
    command_executor='http://localhost:4444/wd/hub',
    options=options
)

# 최대화 및 테스트 페이지 접속
driver.maximize_window()
time.sleep(10)
driver.get("https://notes.prgms-fullcycle.com")
time.sleep(10)
driver.find_element("link text", "무료로 시작하기").click()
time.sleep(10)

# 브라우저 종료
s = input("Done: ")
driver.close()
driver.quit()
print("Test Execution Successfully Completed!")

추가 고려사항:

  • Selenium WebDriver의 옵션 설정, 암호화된 브라우저 실행(Headless 모드) 및 테스트 환경 구성이 중요합니다.
  • Selenium 관련 공식 문서(https://selenium.dev)를 참고하여 최신 기능과 베스트 프랙티스를 습득할 필요가 있습니다.

5-02. Selenium 을 이용한 테스트 전략

주요 내용 및 학습 요소

테스트 전략 개요:

  • 기존에 작성한 Selenium 테스트 코드를 실행하면서 테스트 결과를 관찰하고, 자동화 테스트의 효율성을 높이기 위한 전략을 모색합니다.
  • 테스트 실행 시 브라우저의 로딩 시간, 이벤트 처리 지연(Implicit/Explicit Wait) 등을 고려해야 합니다.

핵심 전략:

  • Headless Browser 사용:
    GUI 없이 브라우저를 실행하여 테스트 오버헤드를 줄이고 CI/CD 파이프라인에 적용할 수 있는 전략.
  • Wait 기능 활용:
    Selenium의 Implicit Wait와 Explicit Wait을 사용하여 요소가 로드될 때까지 대기하는 로직을 추가합니다.
  • 병렬화:
    Selenium Grid와 유사한 환경 구축을 통해 테스트를 병렬로 실행할 수 있으나, 여기서는 standalone 방식으로 진행합니다.

실습 내용:

  • 작성한 테스트 코드를 실행하며 “Click!” 등의 출력 및 브라우저 모니터링을 통해 테스트 흐름을 확인합니다.
  • 테스트 코드 실행 후 발생하는 이벤트(클릭, 입력 등)에 대해 적절한 Wait 타이밍을 적용해 테스트 신뢰도를 높이는 전략을 제시합니다.

추가 고려사항:

  • 테스트 코드 내에 지연 시간을 적절히 삽입하여 비동기적 요소 로딩 문제를 해결해야 합니다.
  • CI/CD 환경에 통합 시 테스트 병렬화 및 리소스 최적화 방안을 추가 검토합니다.

5-03. Selenium IDE 이용 테스트 케이스 개발

주요 내용 및 학습 요소

Selenium IDE의 활용:

  • Selenium IDE를 사용하여 테스트 시나리오를 녹화하고, 기록된 시나리오를 기반으로 테스트 케이스를 자동으로 생성할 수 있습니다.
  • 주로 로그인/로그아웃 시나리오와 같은 반복 작업을 대상으로 하며, HTML 요소 선택 및 이벤트 기록을 자동화합니다.

실습 절차:

  1. 녹화 및 재생:
    • Chrome 웹 스토어에서 Selenium IDE 확장을 설치합니다.
    • 테스트 시나리오(예: “무료로 시작하기” 클릭, 이메일/비밀번호 입력, 로그아웃)를 녹화합니다.
  2. 파일 저장 및 활용:
    • 녹화된 시나리오는 .side 파일로 저장되며, command-line runner(예: selenium-side-runner)를 통해 재생할 수 있습니다.
  3. Python 코드 추출 및 수정:
    • Selenium IDE는 녹화된 테스트 케이스를 Python 코드로 추출할 수 있으며, 이를 pytest 등과 함께 사용해 자동화 테스트로 통합할 수 있습니다.

예시 흐름 및 코드:

  • 녹화된 시나리오에는 로그인/로그아웃, 버튼 클릭, 입력 필드 채우기 등의 절차가 포함됩니다.
  • 추출된 Python 코드 예시 (간략화):
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

class TestUntitled:
    def setup_method(self, method):
        self.driver = webdriver.Chrome()
        self.vars = {}

    def teardown_method(self, method):
        self.driver.quit()

    def test_untitled(self):
        self.driver.get("http://localhost:30030/")
        self.driver.set_window_size(931, 685)
        self.driver.find_element(By.LINK_TEXT, "무료로 시작하기").click()
        self.driver.find_element(By.NAME, "email").send_keys("test@example.com")
        self.driver.find_element(By.NAME, "password").send_keys("1234")
        self.driver.find_element(By.ID, "login-button").click()
        self.driver.find_element(By.CSS_SELECTOR, "#logout-button > span").click()
        self.driver.close()

추가 고려사항:

  • Selenium IDE로 기록된 시나리오가 실제 테스트 자동화에 적합하도록, 코드 추출 후 적절한 Wait, Assertion, 오류 처리를 추가할 필요가 있습니다.
  • Command-line runner의 설치 및 활용 방법을 숙지하고, CI/CD 파이프라인에 통합할 수 있는지 검토합니다.

5-04. 종단간 테스트 케이스 개발

주요 내용 및 학습 요소

종단간(E2E) 테스트의 목적:

  • 전체 시스템(프론트엔드, 백엔드, 데이터베이스)을 아우르는 사용자의 실제 상호작용을 검증하여, 통합된 시스템의 동작을 보장합니다.
  • 로그인, 로그아웃, 노트 목록 조회 및 노트 상세보기 등 사용자 시나리오를 기반으로 테스트 케이스를 개발합니다.

테스트 케이스 개발 예시:

공통 기능 메서드 작성:

  • 테스트 클래스 내에 login()logout() 메서드를 정의하여 모든 테스트에서 공통으로 사용하는 동작을 라이브러리화합니다.
def test_loginlogout(self):
    self.driver.get("http://localhost:30030/")
    self.login()
    self.driver.implicitly_wait(10)
    self.logout()

def login(self):
    self.driver.find_element(By.LINK_TEXT, "무료로 시작하기").click()
    self.driver.find_element(By.NAME, "email").send_keys("test@example.com")
    self.driver.find_element(By.NAME, "password").send_keys("1234")
    self.driver.find_element(By.ID, "login-button").click()

def logout(self):
    self.driver.find_element(By.CSS_SELECTOR, "#logout-button > span").click()

노트 목록 및 상세보기 테스트:

  • 로그인 후 노트 목록 페이지로 이동하여 특정 노트를 선택하고 그 내용(제목, 본문)을 Assertion을 통해 검증합니다.
def test_noteview(self):
    import time
    time.sleep(1)
    self.driver.get(BASE_URL + "/notes")
    self.driver.implicitly_wait(10)
    assert self.driver.find_element(By.ID, "current-user").text == "test@example.com"
    notes_list = self.driver.find_element(By.ID, "notes-list")
    assert notes_list.find_element(By.CSS_SELECTOR, "li:nth-child(1) span").text == "Test (2)"
    assert notes_list.find_element(By.CSS_SELECTOR, "li:nth-child(2) span").text == "Test (1)"
    notes_list.find_element(By.XPATH, "li[last()]/a/span").click()
    self.driver.implicitly_wait(2)
    assert self.driver.find_element(By.CSS_SELECTOR, "article header textarea").text == "Test (1)"
    expected_content = "<p>This note is for testing.</p><p>Note number: 1</p>"
    assert self.driver.find_element(By.CSS_SELECTOR, "article main div div").get_attribute("innerHTML") == expected_content

Alert 처리 테스트:

  • 로그인 실패 시 발생하는 Alert의 텍스트를 검증하는 테스트 케이스도 포함합니다.
def test_loginfail(self):
    self.driver.get("http://localhost:30030/")
    self.driver.find_element(By.LINK_TEXT, "무료로 시작하기").click()
    self.driver.find_element(By.NAME, "email").send_keys("test@example.com")
    self.driver.find_element(By.NAME, "password").send_keys("1235")
    self.driver.find_element(By.ID, "login-button").click()
    assert self.driver.switch_to.alert.text == "이메일 또는 비밀번호가 일치하지 않습니다."

추가 고려사항:

  • 공통 기능을 베이스 클래스에 포함하여 재사용하고, HTML 요소 선택 기준을 일관되게 유지합니다.
  • Selenium의 Wait 기능을 적절히 사용하여 로딩 타이밍 문제를 해결해야 합니다.

5-05. E2E 테스트 자동화

주요 내용 및 학습 요소

E2E 테스트 자동화 개요:

  • 사용자 인터페이스 전체 흐름을 테스트하기 위해, Headless Browser를 이용한 자동화 및 Selenium Grid(또는 standalone)를 활용한 테스트 환경 구축을 목표로 합니다.
  • 자동화된 E2E 테스트는 CI/CD 파이프라인에 통합되어, 변경 시마다 전체 시스템의 동작을 검증할 수 있도록 지원합니다.

핵심 전략 및 환경 구성:

  • Headless Browser:
    GUI 없이 브라우저를 실행하여 빠른 테스트 수행 및 리소스 절약.
    Python 코드 예시에서 ChromeOptions를 이용해 headless 모드로 실행할 수 있습니다.
  • Selenium Grid 및 Docker Compose:
    Docker Compose로 FE, BE, DB, Selenium 컨테이너를 동일 네트워크에 구성하여 단일 원본(single origin) 환경을 구축합니다.
  • Nginx Reverse Proxy:
    FE와 BE를 통합하고, 쿠키의 SameSite, Secure 설정을 조정합니다.

환경 설정 예시:

Nginx Reverse Proxy 설정 (간략화):

server {
    location / {
        proxy_set_header Host $host;
        proxy_pass http://frontend:3000/;
    }
    location /api/ {
        proxy_set_header Host $host;
        proxy_pass http://backend:3031/;
    }
}

Docker Compose 예시:

  • FE, BE, DB, Selenium 컨테이너를 동일 네트워크에 배치하고 각 컨테이너에 필요한 환경 변수를 전달합니다.

추가 고려사항:

  • E2E 테스트는 시스템 자원 소모가 크므로, 테스트 병렬화 및 적절한 시간 지연(Implicit/Explicit Wait) 설정이 필요합니다.
  • CI/CD 파이프라인에 테스트 환경을 통합하고, 테스트 실패 시 빠른 피드백을 받을 수 있도록 설정합니다.
profile
프론트엔드 개발자를 준비하고 있습니다.

0개의 댓글