TRENDSHIFT #11 딥다이브 · 2026-03-28 분석

Expect 딥다이브
— AI 에이전트가 실제 브라우저에서 코드를 적대적으로 테스트하는 도구

AI가 코드를 작성하는 시대, "AI가 만든 코드의 품질을 어떻게 보장하지?"라는 질문에 정면으로 답합니다. Expectgit diff만 있으면 AI가 테스트 계획을 자동 생성하고, Playwright로 실제 브라우저에서 공격적으로 테스트합니다. (저장소: millionco/expect · ⭐3.5k · TypeScript 99.2% · FSL-1.1-MIT)
목차
  1. 프로젝트 한줄 요약
  2. 왜 주목받는가
  3. 기술 스택 전체 지도
  4. 아키텍처 심화 분석
  5. 디렉토리 구조 해부
  6. 학습 포인트 (기술별)
  7. 하드웨어 / 시스템 요구사항
  8. 직접 해볼 수 있는 실습 과제
  9. 관련 기술 심화 학습 로드맵
  10. 핵심 키워드 사전
  11. 참고 링크

1프로젝트 한줄 요약

Expect가 정확히 무엇을 하는가

Expect는 AI 에이전트(Claude, Codex 등)가 코드 변경사항을 분석하여 "적대적(adversarial)" 테스트 계획을 자동 생성하고, 실제 브라우저(Playwright)에서 해당 테스트를 실행하여 통과/실패를 리포트하는 자동화 테스트 도구입니다.

한 컷 비유

"코드 변경했어? AI가 네 코드를 실제 브라우저에서 깨뜨려볼게"

일반 테스트는 "로그인이 잘 되는지" 확인합니다. Expect는 빈 값, SQL 인젝션 문자열, 1000자 입력, 연속 제출로 시스템을 공격합니다. 코드를 쓰는 AI와, 그 코드를 테스트하는 AI가 협업하는 새로운 개발 패러다임입니다.

Playwright 스크린샷과 스냅샷 비교로 테스트 과정을 추적하므로, 실패 시 "무슨 일이 일어났는지"를 단계별로 확인할 수 있습니다.

2왜 주목받는가

트렌딩 이유와 경쟁 대비 장점
기존 방식의 한계
바이브코딩 시대의 품질 보증 문제

AI가 코드를 빠르게 생성하는 바이브코딩이 확산되면서, "AI가 작성한 코드의 품질을 어떻게 보장하지?"라는 질문이 커졌습니다. Playwright나 Cypress로 테스트를 작성하면 코드가 바뀔 때마다 테스트도 수동으로 고쳐야 합니다.

Expect의 해법
변경사항 → 테스트 자동 생성

git diff만 있으면 AI가 무엇이 바뀌었는지 분석하여 그에 맞는 적대적 테스트 계획을 자동으로 만들어냅니다. 사람이 테스트 코드를 작성할 필요가 없습니다.

경쟁 도구 대비 위치

비교 대상Expect의 차별점
Playwright 직접 작성테스트 코드를 사람이 안 써도 됨. git diff만 있으면 AI가 자동 생성
CypressE2E 프레임워크이지만 테스트 작성은 수동. Expect는 "변경→테스트"가 자동
Copilot 테스트 생성코드 레벨 유닛 테스트 생성 vs 실제 브라우저 UI 레벨 테스트
browser-use브라우저 자동화 라이브러리 vs 테스트 특화 + 세션 녹화/리플레이 포함

핵심 혁신 4가지: 적대적 테스트 철학, 쿠키/인증 자동 주입, Playwright 스냅샷 비교, Claude Code 스킬 통합.

3기술 스택 전체 지도

핵심 프레임워크 · AI 연동 · 빌드 시스템

언어 & 런타임

기술버전역할
TypeScript5.7.0메인 언어 (코드베이스 99.2%)
Node.jsv18.x 이상런타임 (engines: '>=18'; @types/node v22.15.0은 타입 정의 버전)

핵심 프레임워크

기술버전역할
Effect4.0.0-beta.35함수형 프로그래밍 프레임워크 (에러 핸들링, 의존성 주입, 동시성)
Playwright1.52.0실제 브라우저 자동화 (Chromium/Firefox/WebKit)
rrweb(@posthog/rrweb ^0.0.50)데모 웹사이트(apps/website)에서만 사용 — 코어 패키지 의존성 아님
Zod4.3.6런타임 스키마 검증

AI/에이전트 연동

기술역할
@ai-sdk/provider (3.0.8)AI 모델 프로바이더 추상화 (Vercel AI SDK)
Agent Client Protocol / ACP (0.16.1)에이전트 간 통신 프로토콜
MCP SDK (1.27.1)Model Context Protocol — Claude Code와 통합

빌드 & 패키지 관리

기술역할
pnpm모노레포 패키지 매니저 (workspace 기반)
Turborepo모노레포 빌드 오케스트레이션 (동시성 20)
Vite번들링 & 개발 서버

4아키텍처 심화 분석

Supervisor 패턴과 4가지 핵심 설계 패턴

시스템 구조도

┌─────────────────────────────────────────────────────┐ │ CLI (expect-cli) │ │ npx expect-cli -m "이 폼을 공격적으로 테스트해" -y │ └──────────────────────┬──────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────┐ │ Supervisor 패키지 │ │ ┌──────────┐ ┌──────────┐ ┌───────────────────┐ │ │ │ Git 모듈 │ │ Executor │ │ Reporter │ │ │ │ diff 분석│ │ 실행 관리 │ │ pass/fail 리포트 │ │ │ └──────┬───┘ └──────┬───┘ └───────────────────┘ │ │ └──────────────┴──────────────┐ │ │ ▼ │ │ Updates (변경사항 추적) │ │ categorizeChangedFiles │ └──────────┬──────────────────────────────────────────┘ │ ┌──────┴──────┐ ▼ ▼ ┌──────────────────┐ ┌────────────────────────────────────┐ │ Agent 패키지 │ │ Browser 패키지 │ │ Claude · Codex │ │ Playwright 브라우저 엔진 │ │ Copilot · Gemini │ │ - runBrowser() / autoDiscoverCdp() │ │ Cursor · OpenCode│ │ - 스크린샷, 스냅샷 비교 │ │ Droid · Pi │ ├────────────────────────────────────┤ │ (8 agents) │ │ MCP 서버 (Claude Code 통합) │ │ detectAvailable │ │ - createBrowserMcpServer() │ │ Agents() │ ├────────────────────────────────────┤ │ AI가 테스트 │ │ Session 녹화 (rrweb — 웹사이트 전용) │ │ 계획 생성 │ │ - collectEvents() / loadSession() │ └──────────────────┘ │ - buildReplayViewerHtml() │ └────────────────────────────────────┘ │ ┌──────────────────────┼──────────────────┐ ▼ ▼ ▼ ┌──────────────┐ ┌──────────────────┐ ┌─────────────────┐ │ Cookies 패키지│ │ typescript-sdk │ │ Shared 패키지 │ │ 쿠키 추출 │ │ 외부 공개 SDK │ │ 모델/프롬프트 │ │ 인증 주입 │ │ (expect-sdk) │ │ Observability │ └──────────────┘ └──────────────────┘ └─────────────────┘

패턴 1 — Effect 기반 함수형 아키텍처

Expect의 가장 독특한 기술적 선택은 Effect 라이브러리를 핵심 프레임워크로 사용한다는 점입니다. Effect는 TypeScript의 "ZIO" 같은 것으로, 에러 타입이 타입 시스템에 명시됩니다.

// Effect 패턴 — 에러 타입이 타입 시그니처에 명시됨
type BrowserResult = Effect.Effect<SnapshotResult, BrowserLaunchError | ActionTimeoutError>

// 의존성 주입이 타입 레벨에서 관리됨 — 테스트 시 쉽게 모킹 가능
왜 Effect인가?
try-catch의 한계를 넘어서
전통적인 try-catch에서는 어떤 에러가 발생하는지 함수 시그니처에 보이지 않습니다. Effect는 Effect<성공값, 에러타입, 의존성>으로 모든 것을 타입으로 추적합니다. Scala의 ZIO에서 영감을 받았습니다.

패턴 2 — Agent Client Protocol (ACP)

┌─────────────┐ ACP Interface ┌──────────┐ │ Supervisor │ ──────────────────── │ Claude │ │ │ ├──────────┤ │ "테스트 │ ──────────────────── │ Codex │ │ 계획 생성" │ ├──────────┤ │ │ ──────────────────── │ (확장) │ └─────────────┘ └──────────┘

detectAvailableAgents() 함수가 사용 가능한 에이전트를 자동 감지하고, AgentBackend 타입으로 추상화합니다.

패턴 3 — MCP (Model Context Protocol) 통합

Browser 패키지가 MCP 서버를 내장하여, Claude Code가 Expect를 도구(tool)로 직접 호출할 수 있습니다:

// MCP 서버 생성 — Claude Code가 이 도구를 호출 가능
const runtime = ManagedRuntime.make(
  Layer.mergeAll(McpSession.layer, OverlayController.layer)
);
const server = createBrowserMcpServer(runtime);
// 호출 흐름: Claude Code → MCP 프로토콜 → Playwright 실행

패턴 4 — Supervisor 오케스트레이션 패턴

Supervisor 패키지가 전체 워크플로우를 조율합니다: Git 모듈 → Agent 테스트 계획 → Browser 실행 → Reporter 결과 수집.

5디렉토리 구조 해부

7-패키지 모노레포 구조
expect/ ├── packages/ │ ├── agent/ # AI 에이전트 통합 계층 │ │ └── src/ │ │ ├── index.ts # Agent, AgentBackend, detectAvailableAgents │ │ └── acp-client.ts # Agent Client Protocol 클라이언트 │ │ │ ├── browser/ # 브라우저 자동화 엔진 (가장 큰 패키지) │ │ └── src/ │ │ ├── index.ts # Browser, runBrowser, diffSnapshots │ │ ├── mcp/ # MCP 서버 (Claude Code 통합) │ │ │ ├── server.ts # McpServer 생성 │ │ │ ├── mcp-session.ts │ │ │ ├── runtime.ts # McpRuntime │ │ │ ├── overlay-controller.ts │ │ │ └── constants.ts, errors.ts 등 (총 12파일) │ │ └── runtime/ # 브라우저 실행 런타임 │ │ │ ├── cookies/ # 쿠키/인증 세션 관리 │ ├── expect-skill/ # Claude Code 스킬 정의 (SKILL.md) │ ├── shared/ # 공통 유틸 (모델, 프롬프트, 텔레메트리) │ ├── supervisor/ # 워크플로우 오케스트레이터 │ │ └── src/ │ │ ├── git/ # Git 연산 (diff, branch, commit) │ │ ├── executor.ts # 테스트 실행 관리자 │ │ └── reporter.ts # 결과 리포트 생성 │ └── typescript-sdk/ # 외부 공개 SDK (expect-sdk) │ ├── turbo.json # Turborepo 빌드 설정 (동시성 20) ├── pnpm-workspace.yaml └── package.json
패키지 의존 관계
shared ← 모든 패키지가 의존
expect-skill(독립) → shared → agent → browser → supervisor 순으로 의존성이 흐릅니다. cookies와 video는 browser가 의존합니다. Supervisor가 agent + browser를 오케스트레이션합니다.

6학습 포인트 (기술별)

이 레포에서 무엇을 배울 수 있는가

Effect (함수형 TypeScript)

배울 것: TypeScript에서 "에러를 타입으로 추적"하는 혁신적 방식. try-catch의 한계를 넘어서는 함수형 에러 핸들링.

// 전통적 방식: 어떤 에러가 발생하는지 타입에서 안 보임
async function runTest(): Promise<Result> {
  try { /* ... */ } catch (e) { /* e는 unknown */ }
}

// Effect 방식: 에러 타입이 시그니처에 명시
function runTest(): Effect.Effect<Result, BrowserLaunchError | ActionTimeoutError> {
  // 컴파일러가 모든 에러 케이스 처리를 강제
}

Playwright 브라우저 자동화

배울 것: CDP(Chrome DevTools Protocol) 자동 발견, 스크린샷 비교(diffSnapshots), 스냅샷 기반 테스트.

// CDP 자동 발견 — 이미 실행 중인 Chrome에 연결
autoDiscoverCdp()  // 개발 중인 앱의 브라우저에 바로 연결

MCP 서버 구현

배울 것: Claude Code의 도구를 확장하는 MCP 서버를 TypeScript로 구현하는 방법. Expect의 packages/browser/src/mcp/ 코드를 분석하면 완전한 MCP 서버 구현 패턴을 익힐 수 있습니다.

rrweb 세션 녹화

배울 것: DOM 변경사항을 이벤트로 캡처하여 "영상처럼" 리플레이하는 기술. 비디오가 아닌 DOM 이벤트 기반이라 파일 크기가 작습니다.

// 세션 이벤트 수집 → HTML 리플레이어 생성
const events = collectAllEvents(session);
const html = buildReplayViewerHtml(events);
// 브라우저에서 열면 테스트 과정을 그대로 재생

Turborepo 모노레포 관리

배울 것: 7개 패키지를 효율적으로 관리하는 모노레포 구성, 의존성 그래프 기반 빌드.

// turbo.json — 빌드 태스크 간 의존 관계 정의
{
  "tasks": {
    "build": { "dependsOn": ["^build"] },  // 의존 패키지 먼저 빌드
    "test": { "dependsOn": ["^test"] }
  }
}

7하드웨어 / 시스템 요구사항

이 레포를 사용하기 위해 필요한 것
항목요구사항
Node.jsv18.x 이상 (engines: '>=18')
패키지 매니저pnpm (모노레포 workspace)
브라우저Chromium (Playwright가 자동 설치)
OSmacOS, Linux, Windows (Playwright 지원 OS)
메모리최소 4GB (Playwright + AI 호출 동시 실행)
AI API 키Claude API 키 또는 Codex 접근 권한
네트워크AI API 호출을 위한 인터넷 연결 필요

8직접 해볼 수 있는 실습 과제

난이도별 5개 과제
TASK 01

Expect 설치 & 기본 테스트 실행 ⭐ 초급

CLI 워크플로우 이해 — 변경 스캔 → 계획 생성 → 실행 → 리포트.

npx -y expect-cli@latest init
expect-cli -m "이 변경사항이 UI를 깨뜨리는지 확인해" -y
TASK 02

적대적 테스트 직접 설계 ⭐⭐ 중급

"행복한 경로(happy path)" vs "적대적 테스트" 차이를 체감합니다.

expect-cli -m "로그인 폼에 빈 값, SQL 인젝션 문자열, 1000자 입력, 연속 10번 제출, 특수문자만 입력해서 깨뜨려봐" -y
TASK 03

Claude Code 스킬로 통합 ⭐⭐⭐ 고급

expect-skill의 SKILL.md를 Claude Code에 등록하고, MCP 기반 도구 통합을 이해합니다. Claude Code에서 자연어로 "이 PR의 변경사항을 적대적으로 테스트해줘" 요청.

TASK 04

Effect 기반 미니 테스트 러너 구현 ⭐⭐⭐⭐ 도전

Expect의 Supervisor 패턴을 참고하여 미니 테스트 러너를 만들어봅니다. Effect 함수형 패턴 + Playwright + AI API 조합 실습.

import { Effect } from "effect";
import { chromium } from "playwright";
// 1. Git diff 파싱 → 변경 파일 목록
// 2. AI에게 테스트 계획 요청
// 3. Playwright로 브라우저에서 테스트 실행
// 4. 결과 리포트 출력
TASK 05

MCP 서버 직접 구현 ⭐⭐⭐⭐⭐ 심화

Expect의 createBrowserMcpServer() 패턴을 참고하여 자신만의 MCP 서버를 구현합니다. MCP 프로토콜의 서버/클라이언트 구조를 완전히 이해하는 것이 목표.

9관련 기술 심화 학습 로드맵

6주 커리큘럼

1주차 — 기초 다지기

Playwright 공식 튜토리얼 완주(2~3일), TypeScript 고급 타입(제네릭, 조건부 타입, 매핑된 타입) 복습, Git diff 파싱 기초(simple-git 라이브러리).

2주차 — Effect 입문

Effect 공식 문서 "Getting Started" 완독. Effect<Success, Error, Requirements> 3가지 타입 파라미터 이해. pipe, map, flatMap, catchAll 패턴 실습. Expect의 에러 타입 계층 분석.

3주차 — MCP 프로토콜 심화

MCP 공식 스펙 문서 읽기, 간단한 MCP 서버 직접 구현(Node.js + TypeScript), Claude Code에서 커스텀 MCP 도구 연동 테스트. Expect의 packages/browser/src/mcp/ 코드 분석.

4주차 — 모노레포 & 빌드 시스템

pnpm workspace 설정 방법 학습, Turborepo로 빌드 파이프라인 구성, Expect의 7-패키지 모노레포 구조를 참고한 미니 프로젝트 구성.

5주차 — AI 에이전트 통합

Vercel AI SDK(@ai-sdk/provider) 학습, ACP(Agent Client Protocol) 스펙 이해, 멀티 프로바이더 에이전트 시스템 직접 구현.

6주차 — 통합 프로젝트

자신만의 "AI 기반 자동화 테스트 도구" 미니 버전 구현, Supervisor 패턴으로 워크플로우 오케스트레이션, rrweb 세션 녹화 + 리플레이 기능 추가, CI/CD 파이프라인 통합.

10핵심 키워드 사전

이 레포를 이해하는 데 꼭 필요한 개념들
키워드설명
적대적 테스트정상 입력이 아닌 경계값, 악의적 입력, 비정상 조작으로 소프트웨어를 "공격"하는 테스트 방식. 해피 패스만 검증하는 기존 테스트의 한계를 보완
EffectTypeScript용 함수형 프로그래밍 프레임워크. 에러 타입을 시그니처에 명시하고, 의존성 주입/동시성을 타입 안전하게 관리. Scala의 ZIO에서 영감
PlaywrightMicrosoft가 만든 브라우저 자동화 라이브러리. Chromium, Firefox, WebKit을 코드로 제어. E2E 테스트의 사실상 표준
CDPChrome DevTools Protocol. Chrome 브라우저를 프로그래밍으로 제어하는 프로토콜. autoDiscoverCdp()는 이미 실행 중인 Chrome에 이 프로토콜로 연결
MCPModel Context Protocol. Anthropic이 만든 표준 프로토콜. AI 모델이 외부 도구를 호출할 수 있게 하는 인터페이스
ACPAgent Client Protocol. AI 에이전트 간 통신을 위한 프로토콜. 여러 AI 프로바이더를 통일된 인터페이스로 접근
rrweb"Record and Replay the Web" — 웹 페이지의 DOM 변경사항을 이벤트로 캡처하여 나중에 그대로 재생하는 라이브러리
TurborepoVercel이 만든 모노레포 빌드 도구. 패키지 간 의존 관계를 파악하여 빌드 순서를 자동 결정하고, 캐싱으로 재빌드를 최소화
Supervisor 패턴여러 하위 작업(Git 분석, AI 호출, 브라우저 실행, 리포트)을 조율하는 상위 관리자. Erlang/OTP의 Supervisor에서 영감
스냅샷 비교브라우저 상태의 이전/이후를 비교하여 변경 사항을 감지. diffSnapshots() 함수가 담당
FSL-1.1-MITFunctional Source License. 처음 일정 기간은 비상업적 사용만 가능하고, 이후 MIT로 자동 전환되는 라이선스

11참고 링크

더 깊이 공부하려면