윤가영 프로필

QA Engineer

윤가영

AI 에이전트를 직접 만들어 QA 파이프라인을 자동화한 엔지니어

0

AI QA 에이전트 개발

0+

버그 식별

2h

30m

회귀테스트 단축

0%

토큰 비용 절감

Skills

Core

Playwright TypeScript Claude Code Python JavaScript

Tools & Infra

AWS Lambda DynamoDB Docker Jira Slack API GitHub SQL Selenium YAML Figma Excel

Profile

Phone

010-6529-6563

Email

qwe06277@naver.com

Education

단국대학교 응용컴퓨터공학과

2018.03 ~ 2022.08

Certifications

ISTQB CTFL 2023.02

컴퓨터활용능력 1급 2022.01

Career

총 4년+ 경력 (2022.05 ~ 현재)

모두싸인 전자계약 SaaS

QA Engineer

2025.11 ~ 재직중

  • Playwright + TypeScript 기반 E2E 자동화 테스트 작성 및 유지보수
  • Claude Code 기반 AI QA 자동화 스킬/에이전트 7종 개발
  • POM 아키텍처 규칙 480줄 가이드 문서 수립 및 리팩토링 주도
  • 모바일 바텀시트 서명 플로우 E2E 신규 구축
  • PDF 스냅샷 비교 기반 시각적 회귀 테스트 도입
  • 링크서명/내부결재/GNB 계약 등 핵심 도메인 E2E 커버리지 확대

월급쟁이부자들 부동산/재테크 교육

QA Engineer

2025.01 ~ 2025.10

  • Playwright + TypeScript 기반 E2E 테스트 자동화 구축
  • Slack-Jira 실시간 연동 시스템 설계 및 개발 (AWS Lambda)
  • QA 일정-마일스톤 자동 연동 체계 구축
  • 이커머스/커뮤니티 스쿼드 QA 리딩
  • VOC 기반 시나리오 설계 및 핫픽스 대응

토스증권 모바일 증권

QA Specialist

2024.01 ~ 2025.01

  • WTS(웹 트레이딩 시스템) TC 수행 및 이슈 관리
  • 국내 원장 시스템 TC 작성 및 검증
  • TC 작성 가이드 제작 및 팀 내 표준화
  • Playwright 기반 UI 테스트 자동화 구축

티맥스와플 → 티맥스오에스 화상회의 / OS 솔루션

QA Manager

2022.05 ~ 2023.11

  • 하이퍼미팅 QA 리딩 (화상회의 솔루션)
  • SI 프로젝트 QA 수행
  • 부하테스트 및 서버 리소스 최적화
  • Docker/K8s 기반 테스트 환경 관리

Projects

모두싸인

2025.11 ~ 재직중

Problem

  • TC 작성이 수동, 기획 문서 기반 도출 시간 소요
  • TC → E2E 코드 변환 반복적
  • 실행/검증/리포트 과정이 분절적

How

  • Claude Code 스킬 3종 + 에이전트 4종 설계/개발
  • TC 생성 → E2E 실행 전체 파이프라인 자동화
  • Canary 패턴 + 토큰 최적화

Value

  • TC 작성 → AI 자동 도출
  • E2E 원스텝 생성/실행/리포트
  • 토큰 비용 75% 절감 (876K→200K)

개발한 스킬 & 에이전트

스킬 3종

qa-create-tc

tech-spec AC(GWT) + DesignSpec → tc.md 자동 생성

tc-auto-test

TC → E2ESpec YAML → spec 생성 → Playwright 실행 → 리포트

e2e-gen

자연어 시나리오 → E2ESpec YAML → BDD spec 생성

에이전트 4종

test-writer

E2ESpec → BDD spec 작성, POM 메서드 직접 추가

pom-writer

POM 작성/수정 (리팩토링 + 신규)

e2e-reviewer

spec/POM 의미적 검증 + 코드 리뷰 + 수정

e2e-rule-checker

grep 기반 규칙 위반 탐지 → 리포트

전체 파이프라인

Phase 1 — TC 생성 (agentic-sd)

/qa-create-tc

tech-spec + DesignSpec 읽기

AC(GWT) → TC 변환

tc.md 생성

Phase 2 — E2E 자동 실행 (web-app)

/tc-auto-test
01 TC 파싱 (automation=O 필터)
02 POM 사전 분석 pom-writer
03 spec 병렬 생성 test-writer
04 Canary 실행 + 검증 reviewer
05 나머지 spec 전체 실행
06 결과 종합 + 리포트 출력

E2ESpec YAML 예시

name: 링크서명 2인 서명 요청
domain: linkSignature
preconditions:
  - 로그인 상태
  - 문서 1건 업로드 완료
scenarios:
  - name: 서명자 2명에게 이메일 서명 요청
    steps:
      - action: addSigners
        params: { count: 2, method: email }
      - action: addSignatureFields
        params: { signerIndex: [0, 1] }
      - action: sendRequest
    expected:
      - 서명 요청 완료 토스트 노출
      - 문서 상태가 "서명 진행중"으로 변경

핵심 설계 포인트

Canary 패턴

첫 번째 spec 1개를 먼저 실행하여 조기 실패 감지, 최대 2회 재시도 후 나머지 전체 실행

POM 충돌 방지

Phase 1에서 pom-writer로 필요한 POM 메서드를 한번에 추가, Phase 2에서 test-writer는 spec만 생성 (POM 읽기 전용)

토큰 최적화

reviewer에게 파일 내용을 프롬프트에 직접 삽입하여 Read tool call 최소화 (876K → 200K 토큰, 75% 절감)

크로스 레포 연동

agentic-sd에서 TC 생성 → web-app에서 E2E 실행, 절대경로로 tc.md 참조

Problem

  • E2E 코드에 일관된 구조 없음
  • CSS/ID 선택자로 테스트 쉽게 깨짐
  • Page/Component/Flow 역할 혼재
  • AI 에이전트 코드 생성 일관성 부재

How

  • 480줄 POM 코딩 규칙 가이드 작성
  • Locator 우선순위 7단계 정의
  • Page/Component/Flow 3계층 분리
  • 메서드 prefix 10종 표준화

Value

  • 팀/AI 동일 규칙 코드 작성
  • 제품 변경 시 테스트 깨짐 방지
  • 신규 온보딩 시간 단축

문서 구성 (9개 섹션)

#섹션내용
1AI 친화적 구조 원칙Self-describing, Predictable, Composable
2Locator 사용 규칙시맨틱 locator 우선순위 7단계, CSS/ID 금지
3메서드 작성 규칙prefix 10종, 파라미터 규칙, 코드 배치 순서
4공통 모듈 정의Page/Component/Flow 3계층 역할 분리
5리팩토링 가이드체크리스트 + 수정/삭제 백로그
6TC → Spec 자동 생성/e2e-gen, /tc-auto-test 스킬 연동
7AI 에이전트4종 에이전트 역할 정의 + 자동 검증 규칙
8도메인 레지스트리JSDoc 태그 분석 → 자동 갱신 스크립트
9도메인 패턴 가이드도메인별 기본 상태, gotcha, 사전 조건

Locator 우선순위

1. getByRole()      ← 최우선 (시맨틱)
2. getByText()
3. getByLabel()
4. getByPlaceholder()
5. getByAltText()
6. getByTitle()
7. getByTestId()    ← 최후 수단
━━━━━━━━━━━━━━━━━━━━
✗ CSS selector      ← 금지
✗ ID selector       ← 금지
✗ XPath             ← 금지

3계층 아키텍처

Page

URL 컨텍스트 대표, Component 생성/반환, spec의 진입점

Component

단일 UI 요소 래핑, spec에서 직접 생성 금지

Flow

여러 Page/Component 조합, 비즈니스 워크플로우 수행

Problem

  • 모바일 바텀시트 서명 E2E 전무
  • 애니메이션으로 인한 테스트 flaky
  • PC/모바일 UI 분기 대응 불가

How

  • aria-busy 기반 바텀시트 안정화
  • CSS 애니메이션 완료 대기 로직
  • device 분기 구조 ('web'|'mobile')

Value

  • 모바일 서명 E2E 커버리지 0%→100%
  • 안정화 패턴 팀 표준으로 확립
  • PC/모바일 통합 테스트 구조 마련

애니메이션 안정화 패턴

바텀시트 열림
  → aria-busy="true" 감지
  → height 안정화 대기 (CSS transition 완료)
  → aria-busy="false" 확인
  → 버튼 클릭 가능

구현 시나리오

사인/도장 바텀시트 열기/닫기

이미지 첨부 바텀시트

체크박스 바텀시트

약관 동의 바텀시트

SignaturePage 대규모 리팩토링

776줄 핵심 POM을 CLAUDE.md 규칙 기반으로 4단계 전면 리팩토링. 리팩토링 결과 CLAUDE.md 모범 예시로 지정됨.

항목BeforeAfter
SignaturePage 역할Page + Flow 혼재Page만 (단일 액션)
Flow 메서드SignaturePage에 포함SignatureFlowPage 분리
미사용 locator다수 방치제거 완료
모바일 지원없음device 분기 구조

시각적 회귀 테스트 도입

PDF 렌더링 검증 수단이 없어 수동 비교에 의존하던 문제를 해결. PDF 스냅샷 캡처 → 기준 스냅샷 비교, 필드 위치 스크린샷 비교를 CI/CD 품질 게이트에 통합.

PDF 스냅샷 비교

임계값 초과 시 자동 실패

필드 위치 스크린샷

리사이징 변경 자동 감지

CI/CD 통합

품질 게이트로 자동 차단

링크서명/내부결재 E2E 커버리지 확대

링크서명 플로우 전면 개선, 내부결재 비동기 대기 로직으로 flaky 해소, 외부 서버 의존을 로컬 파일 업로드로 전환하여 CI 안정성 확보.

링크서명

UX 변경 시 회귀 자동 감지

내부결재

flaky 테스트 완전 해소

CI 안정성

외부 의존 제거

월급쟁이부자들

2025.01 ~ 2025.10

Problem

  • SMS 인증 수동 처리
  • 결제 로직 검증 어려움
  • 상품 옵션별 가격 계산 한계

How

  • POM(Page Object Model) 아키텍처
  • SMS 인증 자동화 (테스트 API 연동)
  • CI/CD 파이프라인 통합

Value

  • 수동 테스트 2h → 30m
  • 핵심 플로우 3개 자동화
  • PR 머지 시 자동 E2E 실행

테스트 시나리오

1. 회원가입 → 로그인

SMS 인증 자동화 포함

2. 상품 구매 플로우

옵션 선택, 가격 계산, 결제

3. 마이페이지 검증

구매 내역, 수강 상태 확인

* 보안 정책상 실제 코드 대신 동일 패턴의 구현 예시입니다

PaymentPage POM

export class PaymentPage {
  constructor(private page: Page) {}

  async selectOption(optionName: string) {
    await this.page.click(`[data-option="${optionName}"]`);
  }

  async verifyPrice(expected: number) {
    const price = await this.page
      .locator('.total-price')
      .textContent();
    expect(Number(price?.replace(/[^0-9]/g, '')))
      .toBe(expected);
  }

  async proceedPayment() {
    await this.page.click('[data-testid="pay-button"]');
    await this.page.waitForURL('**/payment/complete');
  }
}

SMS 인증 자동화

async function getVerificationCode(phone: string) {
  const response = await request.get(
    `${TEST_API}/sms/latest?phone=${phone}`
  );
  const { code } = await response.json();
  return code;
}

// 테스트에서 사용
const code = await getVerificationCode('01012345678');
await page.fill('[data-testid="sms-code"]', code);
await page.click('[data-testid="verify-btn"]');

CI/CD 파이프라인

name: E2E Tests
on:
  pull_request:
    branches: [main]

jobs:
  e2e:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
      - run: npm ci
      - run: npx playwright install --with-deps
      - run: npx playwright test
      - uses: actions/upload-artifact@v4
        if: failure()
        with:
          name: test-results
          path: test-results/

실제 동작 화면

E2E 테스트 결과 Slack 알림

E2E 테스트 결과 Slack 자동 알림

GitHub PR 커밋 히스토리

GitHub PR / 커밋 히스토리

기술적 도전

1. SMS 인증 자동화

테스트 전용 API 엔드포인트를 활용하여 인증 코드를 프로그래밍 방식으로 조회, 수동 개입 없이 전체 인증 플로우 자동화

2. 결제 로직 검증

테스트 결제 게이트웨이를 통한 실제 결제 플로우 시뮬레이션, 옵션별 가격 계산 로직 검증

3. 테스트 데이터 관리

테스트 실행마다 독립적인 데이터 셋업/클린업으로 테스트 간 의존성 제거

Problem

  • Jira 수동 등록 병목
  • Slack-Jira 댓글 불일치
  • 상태 업데이트 수작업

How

  • Lambda 3개 (이벤트 라우터 / 이슈 생성 / 댓글 동기화)
  • DynamoDB 중복 방지
  • Jira REST API + Slack Web API

Value

  • 이슈 등록 시간 80% 단축
  • 정보 동기화 완전 자동화
  • 커뮤니케이션 단일 채널

시스템 아키텍처

Slack Message

Lambda A — 이벤트 라우터

이벤트 타입 분류 · 중복 요청 필터링

Lambda B

이슈 생성

Jira REST API

Lambda C

댓글 동기화

DynamoDB

실제 동작 화면

Jira-Slack 티켓 자동 생성

Slack 메시지 → Jira 티켓 자동 생성 화면

* 보안 정책상 실제 코드 대신 동일 패턴의 구현 예시입니다

Lambda A: 이벤트 라우터

exports.handler = async (event) => {
  const body = JSON.parse(event.body);

  // Slack URL 검증
  if (body.type === 'url_verification') {
    return { statusCode: 200, body: body.challenge };
  }

  // 중복 이벤트 필터링
  const eventId = body.event_id;
  const isDuplicate = await checkDuplicate(eventId);
  if (isDuplicate) return { statusCode: 200 };

  const eventType = body.event?.type;

  if (eventType === 'message' && !body.event.thread_ts) {
    // 새 메시지 → 이슈 생성
    await invokeLambda('issue-creator', body.event);
  } else if (eventType === 'message' && body.event.thread_ts) {
    // 스레드 댓글 → 댓글 동기화
    await invokeLambda('comment-sync', body.event);
  }

  return { statusCode: 200 };
};

기술적 해결책

중복 처리

DynamoDB TTL을 활용한 이벤트 ID 기반 멱등성 보장으로 동일 이벤트 중복 처리 방지

사용자 매핑

Slack User ID ↔ Jira Account ID 매핑 테이블로 자동 리포터 할당

Jira 키 추출

Slack 메시지 내 Jira 이슈 키 정규식 추출로 기존 이슈 댓글 자동 연결

Problem

  • 매일 수동 배포 알림 작성
  • 팀별 현황 파악 어려움
  • 커뮤니케이션 분산

How

  • EventBridge 스케줄링
  • fixVersion 기반 JQL 쿼리
  • 팀별 자동 분류 + 새로고침 버튼

Value

  • 매일 30분 작업 완전 자동화
  • 정보 누락 0건
  • 실시간 현황 공유

시스템 아키텍처

EventBridge (매일 09:00 KST)

AWS Lambda

1. Jira JQL 2. 팀별 분류 3. 메시지 생성
Slack Web API
DynamoDB

실제 동작 화면

Jira 배포 현황 Slack 알림

매일 자동 발송되는 배포 현황 Slack 메시지

* 보안 정책상 실제 코드 대신 동일 패턴의 구현 예시입니다

핵심 코드

def get_deploy_issues(fix_version: str) -> list:
    jql = (
        f'fixVersion = "{fix_version}" '
        f'AND status in (Done, "In Review") '
        f'ORDER BY team ASC'
    )
    issues = jira.search_issues(jql, maxResults=100)
    return categorize_by_team(issues)

기술적 해결책

에러 처리

Jira API 타임아웃 시 재시도(exponential backoff), 실패 시 Slack 에러 알림 자동 발송

빈 배포일 처리

배포 이슈가 없는 날에도 "오늘 배포 없음" 메시지를 전송하여 정보 공백 방지

메시지 상태 관리

DynamoDB에 메시지 ID 저장, 새로고침 버튼 클릭 시 기존 메시지 업데이트 (중복 메시지 방지)

Problem

  • 1인 QA 체계 부재
  • 상태 기반 테스트 복잡성
  • 기획 변경 빈번

How

  • 상태 기반 TC 체계 수립
  • 기획 변경 대응 프로세스
  • VOC 대응 루프 구축

Value

  • QA 누락 0건
  • 핫픽스 월 3건 → 0~1건
  • 릴리즈 지연 0건

실제 QA 활동 화면

Slack 버그 리포트

커뮤니티 스쿼드 Slack 채널 버그 리포트 현황

주요 활동

활동내용
상태 기반 TC 설계게시글/댓글/유저 상태 조합별 TC 매트릭스 작성
기획 변경 대응변경 사항 영향도 분석 → TC 즉시 업데이트 → 회귀 범위 재산정
VOC 대응 루프VOC 수집 → 시나리오 추가 → 회귀 테스트 반영
릴리즈 QA스프린트 별 릴리즈 QA 일정 관리 및 실행

성과 지표

지표BeforeAfter
QA 누락빈번0건
월간 핫픽스3건0~1건
릴리즈 지연간헐적0건

토스증권

2024.01 ~ 2025.01

Problem

  • 신규 트레이딩 플랫폼
  • 고위험 금융 시스템
  • 문서화된 QA 기준 없음

How

  • TC 0부터 체계적 정의
  • 4차례 이터레이션
  • 개발자 직접 커뮤니케이션

Value

  • TC 1,000+건 작성
  • 4,000+ 이슈 탐지
  • 오류 없는 정식 런칭

테스트 전략

신규 웹 트레이딩 시스템(WTS)의 QA를 0부터 담당. 기존 문서화된 기준이 없는 상태에서 기획서, 디자인, API 명세를 분석하여 TC를 체계적으로 작성. 4차례에 걸친 이터레이션을 통해 TC를 지속적으로 보완하고, 개발자와 직접 소통하며 엣지 케이스를 발견.

반복 이터레이션

1차

기본 기능 TC 작성

2차

엣지 케이스 추가

3차

회귀 TC 보완

4차

런칭 전 최종 검증

성과

항목수치
작성 TC1,000+건
탐지 이슈4,000+건
이터레이션4회
런칭 결과오류 없는 정식 런칭

Problem

  • 금융 거래 로직 검증 부담
  • 실시간 주식 거래 수동 테스트
  • 커뮤니티 연동 테스트 부재

How

  • POM + JavaScript
  • Docker 기반 CI/CD
  • FastAPI 테스트 서버

Value

  • 금융 테스트 4h → 1h
  • 핵심 플로우 12개 자동화
  • 비디오 증적 수집

* 보안 정책상 실제 코드 대신 동일 패턴의 구현 예시입니다

StockDetail POM

class StockDetailPage {
  constructor(page) {
    this.page = page;
  }

  async navigateTo(stockCode) {
    await this.page.goto(
      `/stock/${stockCode}`
    );
    await this.page.waitForSelector(
      '[data-testid="stock-price"]'
    );
  }

  async getCurrentPrice() {
    return await this.page
      .locator('[data-testid="stock-price"]')
      .textContent();
  }

  async clickBuyButton() {
    await this.page.click(
      '[data-testid="buy-button"]'
    );
    await this.page.waitForSelector(
      '.order-modal'
    );
  }

  async placeOrder(quantity) {
    await this.page.fill(
      '[data-testid="quantity"]',
      String(quantity)
    );
    await this.page.click(
      '[data-testid="confirm-order"]'
    );
  }
}

Dockerfile

FROM mcr.microsoft.com/playwright:v1.40.0

WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .

# 비디오 증적 저장 디렉토리
RUN mkdir -p /app/test-results/videos

CMD ["npx", "playwright", "test", \
     "--reporter=html,json"]

FastAPI 테스트 서버

from fastapi import FastAPI
from datetime import datetime

app = FastAPI()

@app.get("/api/test/stock/{code}")
async def get_test_stock(code: str):
    """테스트용 주식 데이터 반환"""
    return {
        "code": code,
        "price": 50000,
        "change": 2.5,
        "timestamp": datetime.now().isoformat()
    }

@app.post("/api/test/order")
async def create_test_order(order: dict):
    """테스트 주문 생성 (실제 체결 없음)"""
    return {
        "orderId": f"TEST-{datetime.now().timestamp()}",
        "status": "FILLED",
        **order
    }

테스트 시나리오 (12개 핵심 플로우)

1. 로그인 / 로그아웃

2. 종목 검색

3. 종목 상세 조회

4. 매수 주문

5. 매도 주문

6. 주문 취소

7. 잔고 조회

8. 주문 내역 조회

9. 차트 렌더링

10. 호가창 실시간 업데이트

11. 커뮤니티 댓글

12. 알림 설정

QA 철학

4년간 현장에서 얻은 관점

"1인 QA는 자동화에 집착해야 합니다"

혼자서 전체 제품을 커버하려면 수동 반복을 제거하는 수밖에 없습니다. 처음엔 E2E 자동화로 회귀테스트를 2시간에서 30분으로 줄였고, 이후엔 TC 작성과 코드 생성까지 AI로 자동화했습니다. 결과적으로 "QA가 한 명이라 못 한다"는 말이 나오지 않는 환경을 만들었습니다.

핫픽스 월 3건 → 0건 | QA 누락 0건 | 스킬 3종 + 에이전트 4종

"AI는 QA를 대체하는 게 아니라, QA의 판단력을 확장합니다"

AI 에이전트가 TC를 자동 도출하고 E2E 코드를 생성해도, 어떤 시나리오가 중요한지, 어떤 엣지 케이스가 위험한지는 사람이 판단합니다. 저는 AI가 반복 작업을 맡게 하고, 그 시간에 리스크 분석과 테스트 전략에 집중합니다. 토큰 75% 절감도 "더 많이 쓰자"가 아니라 "더 똑똑하게 쓰자"의 결과입니다.

토큰 876K → 200K (75% 절감) | Canary 패턴으로 조기 실패 감지

"규칙을 문서로 남기면, 사람이 바뀌어도 품질은 유지됩니다"

480줄 POM 가이드를 쓴 이유는 단순합니다. 제가 없어도 같은 품질의 E2E 코드가 나와야 하니까요. AI 에이전트도 이 문서를 참조해서 코드를 생성합니다. 사람과 AI 모두 같은 기준으로 움직이는 것 — 그게 진짜 표준화입니다.

480줄 POM 가이드 | TC 작성 표준화 | 4종 에이전트가 동일 규칙 참조