개념
기능 테스트 너머 — 왜 같은 방식으로 넓히면 안 되는가
지금까지 이 모듈은 주로 기능 테스트에 AI를 붙였다. 요구사항에서 조건을 뽑고, 케이스를 만들고, 실패를 분석했다. 같은 방식을 보안·부하·성능· 데이터 품질로 넓히고 싶어지는 것은 자연스럽다. 그런데 이 네 영역은 오라클(정답을 판정하는 기준)의 성질 이 기능 테스트와 다르다.
| 영역 | 기능 테스트와 다른 점 | AI 보조가 특히 위험한 이유 |
|---|---|---|
| 보안 | "아무 일도 안 일어남"이 통과다. 결함은 공격자가 찾는다 | AI가 "취약점 없음"이라고 하면 그 말을 반증하기 어렵다 |
| 부하 | 정답이 숫자 범위이고, 워크로드 모델이 틀리면 결과 전체가 무의미하다 | 그럴듯한 시나리오가 실제 트래픽과 전혀 다를 수 있다 |
| 성능 해석 | 같은 수치도 맥락(워밍업·캐시·분포)에 따라 해석이 갈린다 | AI는 평균과 상관을 인과처럼 말하기 쉽다 |
| 데이터 품질 | 규칙의 근거가 업무 정책이다 | 현재 데이터를 프로파일링해 만든 규칙은 현재의 결함까지 정답으로 굳힌다 |
이 레슨의 원칙은 하나다. AI는 후보를 넓히는 데 쓰고, 판정 기준과 범위는 사람이 쥔다. 위협 후보·퍼징 입력·시나리오 초안·규칙 초안은 AI가 빠르게 늘려 준다. 무엇이 실제 위협인지, 어떤 부하가 현실적인지, 어떤 데이터가 옳은지는 업무와 시스템을 아는 사람이 정한다.
보안 ① — AI 보조 위협 모델링
모듈 50 레슨 1에서 STRIDE와 공격 트리로 위협 모델을 만드는 법을 배웠다. AI 보조 위협 모델링은 아키텍처 설명과 데이터 흐름을 주면 STRIDE 범주별 위협 후보와 완화책을 뽑아 준다. 오픈소스 도구 STRIDE GPT 가 대표적이다. 애플리케이션 설명과 아키텍처 다이어그램을 입력하면 위협 목록·공격 트리·완화책·DREAD 점수까지 생성한다.
빈 종이보다 50개 후보에서 시작하는 편이 빠르고, 사람이 습관적으로 빠뜨리는 범주를 기계적으로 훑는다. 하지만 약점도 일정하다.
| 약점 | 모습 | 보완 |
|---|---|---|
| 일반론 | "SQL 인젝션 가능성", "약한 비밀번호" 같은 어느 시스템에나 맞는 위협이 대부분 | 우리 데이터 흐름의 특정 지점(어느 API·어느 필드)을 가리키지 않는 항목은 버린다 |
| 신뢰 경계 누락 | 입력에 없는 외부 연동·배치·관리자 경로를 모른다 | 입력 다이어그램을 사람이 먼저 완성한다. 빠진 경계는 AI가 찾지 못한다 |
| 업무 로직 위협 부재 | 쿠폰 중복 적용·환불 후 재사용 같은 업무 악용을 못 본다 | 도메인 담당자와 "이 기능으로 돈을 벌거나 아끼는 부정한 방법" 질문 세션 |
특히 세 번째가 중요하다. 실제 사고의 상당수는 기술 취약점이 아니라 업무 규칙의 허점 에서 나온다. 이 부분은 업(業)을 아는 QA가 가장 잘 찾는 영역이고, AI가 가장 못 찾는 영역이다.
보안 ② — AI 보조 퍼징과 스캐너 결과 검증
퍼징은 비정상 입력을 대량으로 넣어 크래시·예외·이상 동작을 찾는 기법이다. 사람이 하기 어려운 부분은 퍼즈 타깃(퍼저가 입력을 넣을 진입점 코드)을 쓰는 일이다. Google OSS-Fuzz 팀은 LLM으로 퍼즈 타깃을 생성하는 실험을 2023년부터 공개해 왔다. 2024년 11월 발표에 따르면 AI가 생성·보강한 타깃으로 272개 C/C++ 프로젝트에서 커버리지를 늘렸고, OpenSSL의 CVE-2024-9143을 포함해 26건의 새 취약점을 보고했다. 사람이 쓴 기존 타깃으로는 닿지 않던 코드였다는 점이 핵심이다.
이 사례에서 QA가 가져올 교훈은 "AI가 취약점을 찾는다"가 아니라 구조다. AI가 만든 것은 입력 생성기이고, 판정은 크래시·새니타이저라는 결정적 오라클이 했다. AI가 결과를 판정한 것이 아니다. 웹·API 영역으로 옮기면 다음과 같다.
AI에게 맡기는 것: OpenAPI 명세를 읽고 필드별 경계·변형 입력 생성 (긴 문자열, 유니코드, 음수, 타입 혼동, 중첩 JSON)
결정적으로 판정: 5xx 응답, 스택 트레이스 노출, 응답 시간 급증, 다른 사용자 데이터 노출(권한 검사)
사람이 판정: 4xx인데 메시지가 내부 정보를 흘리는가, 업무상 허용되면 안 되는 값이 받아들여졌는가AI 보안 스캐너가 내놓는 리포트도 같은 원칙으로 본다. 모듈 23 레슨 3에서 다뤘듯 100건짜리 리포트의 상당수는 오탐이거나 중복이다. AI가 "치명적"이라고 표시한 항목도 재현 가능한 증거(요청·응답 쌍)가 없으면 확정하지 않는다. 반대로 "문제없음"은 아무것도 증명하지 않는다.
LLM이 들어간 제품이라면 OWASP Top 10 for LLM Applications 2025(프롬프트 인젝션, 과도한 권한 위임 등)를 위협 범주로 추가한다(모듈 18b).
부하 — 실사용 로그에서 시나리오 뽑기
모듈 51 레슨 1의 워크로드 모델링을 AI가 크게 덜어 준다. 액세스 로그를 넣으면 호출 비율·세션 흐름·피크를 요약하고 스크립트 초안까지 만든다. Grafana는 2025년 Grafana Assistant에 k6 스크립트 작성 모드를 넣어, 서비스 이름만 주면 메트릭·로그·트레이스를 조회해 실제 엔드포인트와 트래픽 패턴으로 스크립트를 생성하게 했다. 브라우저 흐름을 녹화한 HAR 파일에서 스크립트를 만드는 k6 Studio 같은 도구도 있다.
문제는 초안이 그럴듯할수록 검토 없이 쓰게 된다 는 점이다. AI가 만든 부하 시나리오에서 자주 틀리는 지점은 다음과 같다.
| 틀리는 지점 | 결과 | 확인 방법 |
|---|---|---|
| 평균 비율만 반영 | 피크 시간대의 쓰기 비중 급증(정산·이벤트 오픈)을 놓친다 | 시간대별 비율을 따로 뽑아 피크 구간 모델을 별도로 만든다 |
| 같은 데이터 반복 | 모든 가상 사용자가 같은 상품·계정을 조회해 캐시 적중률이 비현실적으로 높다 | 데이터 분포(인기 상품 쏠림, 롱테일)를 실데이터와 비교 |
| 상관 값 누락 | 세션 토큰·CSRF 값을 하드코딩해 대부분 요청이 401로 끝나는데 "빠르다"고 나온다 | 응답 코드 분포를 체크·임계값에 넣는다 |
| 생각 시간 무시 | 사용자 수 대비 요청률이 수 배로 과장된다 | 로그의 요청 간격 분포를 반영 |
| 외부 연동 호출 | PG·본인인증 실서비스를 부하로 두드린다 | 레슨 6의 서비스 가상화로 대체, 실호출 차단 확인 |
마지막 행은 품질 문제가 아니라 사고다. AI가 만든 스크립트에 운영 URL이나 실서비스 엔드포인트가 섞여 있지 않은지 실행 전에 사람이 확인 하는 절차를 둔다.
// AI 초안에 사람이 반드시 추가하는 안전장치 예 (k6)
export const options = {
thresholds: {
'checks': ['rate>0.99'], // 401·5xx로 끝나는 '빠른 실패' 차단
'http_req_duration{group:::checkout}': ['p(95)<800'],
},
};
const ALLOWED_HOSTS = ['perf-stg.example.internal']; // 허용 호스트 외 호출 시 중단성능 결과 해석 — AI 요약을 그대로 믿지 않기
AI에게 "결과를 요약하고 병목을 찾아 달라"고 하면 깔끔한 문단이 돌아온다. 그 요약에서 자주 나오는 오류는 다음과 같다.
- 평균으로 말한다. "평균 응답 320ms로 양호" — 모듈 31 레슨 4에서 배웠듯 성능은 분포(p95·p99)와 오류율로 말해야 한다.
- 워밍업 구간을 섞는다. 시작 직후 JIT·캐시 적재 구간이 평균을 끌어올리거나 내린다.
- 상관을 인과로 말한다. "CPU가 80%일 때 지연이 늘었으므로 CPU가 병목" — 같은 시점에 GC·DB 락·외부 API 지연이 함께 있었을 수 있다.
- 비교 기준이 없다. 지난 릴리스 기준선 없이 "양호"라고 판정한다.
- 실패 요청을 빼고 계산한다. 타임아웃으로 끊긴 요청이 지연 통계에서 빠지면 결과가 좋아 보인다.
그래서 AI 해석 요청에는 판정 규칙을 함께 준다. "p95와 오류율로만 판정, 기준선 대비 증감을 표로, 병목 주장마다 같은 시간대의 근거 지표 두 개 이상 인용, 근거가 하나면 '가설'로 표시." 레슨 7의 실패 분석과 같은 구조다. AI의 몫은 수많은 지표에서 볼 만한 구간을 좁혀 주는 것 이고, 병목 확정은 프로파일링·재현으로 사람이 한다.
데이터 품질 — 규칙 자동 생성과 그 함정
데이터 품질은 ISO/IEC 25012가 정의한 데이터 품질 모델로 체계를 잡을 수 있다. 이 표준은 15개 특성을 데이터 자체로 판단하는 고유(inherent) 관점과 시스템 환경에 좌우되는 시스템 의존 관점으로 나눈다. 실무 규칙은 대개 다음 몇 가지 특성으로 모인다.
| 특성 | 규칙 예 | 자동 생성 가능성 |
|---|---|---|
| 완전성 | 주문.결제수단 은 null 불가 | 높음 — 프로파일링으로 null 비율 확인 |
| 정합성(일관성) | 주문 합계 = 상품 금액 합 - 할인 + 배송비 | 낮음 — 업무 공식을 알아야 한다 |
| 정확성 | 우편번호가 실제 주소와 일치 | 낮음 — 외부 참조 데이터 필요 |
| 유효성(형식) | 휴대폰 번호 형식, 상태값이 허용 목록 안 | 높음 |
| 유일성 | 주문번호 중복 없음 | 높음 |
| 현재성 | 재고 스냅샷이 15분 이내 | 중간 — 기준 시간은 업무가 정한다 |
Great Expectations·dbt 테스트 같은 도구는 데이터를 프로파일링해 규칙 초안(기대값)을 만들 수 있고, LLM은 테이블 스키마와 샘플을 보고 규칙을 문장과 코드로 제안한다. 여기서 가장 큰 함정이 나온다. 프로파일링은 "지금 데이터가 어떻게 생겼는가"를 알려 줄 뿐 "어떻게 생겨야 하는가"를 알려 주지 않는다. 지금 데이터에 할인 금액이 음수인 행이 0.3% 있으면, 프로파일링 기반 규칙은 "할인 금액 범위: -5,000~50,000"을 정답으로 굳힌다. 그 0.3%가 결함이었다면 규칙이 결함을 영구히 합법화한 것이다.
# 규칙 초안에 출처 칸을 붙여 사람이 승인하는 형태
- rule: discount_amount >= 0
source: 할인 정책서 v4 §2.1 "할인 금액은 0 이상"
generated_by: LLM 초안, 프로파일링 결과(min=-5000)와 충돌 — 담당자 확인 필요
status: 승인 대기규칙마다 근거가 프로파일링인지, 업무 정책인지 를 표시하고, 둘이 충돌하면 결함 후보로 올린다. 이 충돌 목록이 데이터 품질 점검에서 가장 값진 산출물이다. 모듈 61 레슨 6의 수집 데이터 품질 점검과 함께 보면 좋다.
네 영역 공통 — 범위·허가·데이터 보호
| 영역 | 반드시 사람이 확인할 것 |
|---|---|
| 보안 | 테스트 대상·기간·방법에 대한 서면 허가 범위, AI 에이전트가 범위 밖 호스트를 건드리지 않는지 |
| 부하 | 대상 환경(운영 금지 여부), 외부 연동 차단, 중단 기준 |
| 성능 해석 | 비교 기준선, 판정 지표(p95·오류율), 병목 확정 절차 |
| 데이터 품질 | 샘플 데이터의 개인정보 마스킹, 외부 LLM에 보내도 되는 범위, 규칙의 업무 근거 |
운영 데이터 원본을 외부 LLM에 넣는 일은 점검 자체보다 큰 위험이다. 스키마와 통계만 보내거나 사내 승인 모델만 쓰는 규칙을 먼저 정한다.
실무에서 왜 필요한가
AI로 기능 테스트를 자동화한 조직은 곧 "보안·성능은 왜 아직 수작업인가"라는 질문을 받는다. 이 영역은 전문 인력이 적고 일정 끝에 몰리기 때문에 AI 보조의 효과가 크다. 위협 후보 50개, 퍼징 입력 수천 개, 시나리오 초안, 규칙 초안이 몇 분 만에 나온다.
그러나 이 영역의 결함은 대개 조용하다. 보안 구멍과 잘못된 데이터 규칙은 테스트 결과에 빨간불로 나타나지 않는다. AI가 그럴듯하게 "문제없음"을 내놓으면 아무도 다시 보지 않는다. 그래서 QA가 할 일은 AI 결과를 결정적 오라클(크래시·응답 코드·임계값·업무 공식)과 업무 근거에 묶는 것이다. 이 연결을 설계할 수 있는 사람이 비기능 영역까지 AI를 넓힐 수 있다.