테스트 분류 체계로 CI 품질 게이트 운영하기

테스트 목적·레벨·위험도·환경을 표준 태그로 관리해 CI 파이프라인, 품질 게이트, 변경 영향 분석을 일관되게 운영하는 방법

2026-08-14 · 최초 발행 2025-12-16

테스트를 실행 목록이 아니라 운영 대상로 다루는 방법

릴리스 주기가 짧아지고 서비스 복잡도가 높아질수록 모든 테스트를 같은 방식으로 실행하기는 어렵다. 테스트 분류 체계(Test Classification Taxonomy)는 테스트의 목적, 레벨, 위험도, 환경, 자동화 수준을 표준화하고, 그 정보를 실행·게이팅·리포팅까지 일관되게 사용하는 운영 메커니즘이다.

분류 대상에는 유닛·통합·시스템·인수 테스트와 기능·비기능 테스트가 포함된다. 비기능 범위에는 성능, 보안, 내고장성, 접근성이 있으며 블랙·화이트·그레이박스, 스모크·회귀, 계약·혼합 테스트도 함께 다룬다. 이를 운영하려면 메타데이터 스키마, 정책과 게이트, 오케스트레이션, 측정 및 피드백 루프가 필요하다.

공통 분류 축과 태그 규칙을 먼저 맞춘다

목적, 레벨, 기법, 위험, 환경, 주기, 자동화 수준처럼 여러 팀이 함께 쓸 최소 공통 분모를 정한다. 팀별 확장을 허용할 범위도 함께 명시해야 태그가 무분별하게 늘어나는 일을 막을 수 있다.

예를 들어 분류 값은 다음과 같이 관리할 수 있다.

  • level(unit|integration|e2e)
  • purpose(functional|performance|security)
  • risk(P0~P3)
  • env(dev|staging|prod)
  • cadence(on-commit|nightly|pre-release)

테스트 파일이나 케이스에 표준 태그를 적용하고 스키마를 관리한다. 이름 규칙, pytest markers, JUnit properties를 병행할 수 있다. 요구사항 ID, API 계약 버전, 위험 항목을 연결하면 소스와 요구사항의 트레이서빌리티도 유지된다.

정책은 클래스별로 필수와 선택 기준을 나눈다. P0 변경에는 스모크, 계약, 보안 스캐닝을 필수로 두고 커버리지 임계치를 적용하는 식이다. 머지와 릴리스를 막는 조건, 재시도 정책, 플레이키 격리와 치유 워크플로도 이 기준에 포함한다.

실행 전략은 분류 정보를 사용해 달라진다

변경 영향 분석(CIA)으로 테스트 후보를 좁히고, 우선순위 큐를 구성한 뒤 샤딩·병렬·캐시 전략을 클래스마다 다르게 적용한다. 테스트 클래스에 따라 ephemeral 환경, 데이터 시드, 트랜잭션 롤백, 락 정책을 구분하는 환경 격리 원칙도 필요하다.

운영 중에는 클래스별 커버리지, 소요 시간, 실패율, 플레이키율, MTTR을 수집한다. SLO와 OKR을 관리하면서 회귀 탐지 알람을 두고, 태그 누락률이나 잘못 분류된 테스트까지 점검해야 분류 체계 자체의 품질을 확인할 수 있다.

기존 테스트를 분류 체계로 옮기는 과정

먼저 현행 테스트를 목록화하고 실행 시간, 불안정도, 의존성을 매핑한다. 이 과정에서 유사하거나 중복된 테스트와 제거 후보를 찾는다.

다음으로 level, purpose, risk, cadence, env, owner 같은 최소 필수 필드를 정하고, 표준 명명 규칙·마커·라벨·요구사항 및 계약 ID 연결 방식을 확정한다. 메타데이터 전환은 핵심 20%부터 태깅하는 린(Lean) 접근을 취하고, 자동 추론 스크립트를 병행할 수 있다. 누락과 충돌을 검증하는 룰, PR 체커도 함께 둔다.

파이프라인은 클래스별 잡으로 나누고 샤딩과 캐시, 변경 영향 기반 부분 실행을 적용한다. 환경 풀과 리소스 할당 정책에서는 동시성, 락, 격리 기준을 정한다. 이후 클래스별 머지 차단 조건과 재시도·격리 기준을 합의하고, 초기에는 관대한 임계치에서 시작해 점진적으로 높인다.

분류 지도(heatmap)로 병목을 찾고 플레이키 치료 백로그를 운영한다. 규칙을 갱신하기 위한 분류 체계 거버넌스 회의는 월 1회로 운영한다.

서비스 환경별로 달라지는 적용 방식

모노레포에서는 변경 영향 기반의 스모크와 유닛 테스트를 먼저 실행하고, 야간에 회귀 풀세트를 돌릴 수 있다. 이 방식의 결과로 평균 PR 시간은 35% 단축되고 비용은 30% 절감된다.

금융·의료처럼 규제 요구가 있는 환경에서는 밸리데이션 클래스를 두고 요구사항 추적과 증빙 자동 수집을 연결한다. 릴리스 승인 리드타임을 예측하기 쉬워지고 감사 대응도 수월해진다.

마이크로서비스는 제공자와 소비자의 계약 테스트를 분리해 브레이킹 체인지를 사전에 막는다. 카나리 배포와 연결하면 프로덕션 세이프가드로 사용할 수 있다. 프론트엔드와 모바일은 브라우저·디바이스 클래스별로 샤딩하고 비주얼 회귀를 따로 실행해 렌더링 오류를 일찍 발견하며 회귀 비용을 낮춘다.

운영 환경에서는 카나리와 합성 모니터링을 시프트라이트 클래스에 포함한다. 장애 재현과 검증에 걸리는 시간을 줄이는 데 쓰인다.

테스트 분류 체계를 적용하면 평균 파이프라인 시간은 2050% 단축되고, 인프라 사용량은 2540% 절감되며, 플레이키 노이즈는 30% 이상 감소한다. 공통 언어를 정립해 온보딩을 쉽게 만들고, 감사·컴플라이언스 대응을 단순화하며, 품질 게이트의 일관성과 신뢰도를 높이는 효과도 기대할 수 있다.

클래스별 실행 조건을 비교할 때

클래스 성능(평균 실행시간) 확장성(병렬/샤딩) 일관성(플레이키) 안정성(환경 의존) 운영 편의
유닛(Unit) 매우 짧음(초) 매우 높음 매우 낮음 매우 낮음 매우 높음
통합(Integration) 중간(분) 높음 낮음 중간 높음
E2E(System) 길음(분~십분) 중간 중간 높음 중간
성능(Performance) 매우 길음(십분~시간) 낮음 낮음 매우 높음 낮음

분류부터 리포트까지 이어지는 운영 흐름

처리: '입력 정합성 검증'처리: '테스트 후보 집합 생성'조건: '규칙 일치 여부 판단'예: '누락/충돌 발생'아니오: '정상 분류'처리: '리소스 요구량 산정'예: '가용/락 획득'아니오: '대기 또는 축소 실행계획'처리: '환경 준비 완료'결과: '성공/실패/플레이키감지'입력: '변경 코드, 테스트메타데이터, 커버리지 맵'처리: '변경 영향 분석(CIA)실행'처리: '분류 규칙 정책 적용'조건: '태그 누락 또는 충돌?'에러 처리: '분류 실패 리뷰요청 기본 스모크 실행'처리: '우선순위 큐잉 샤딩계획 수립'조건: '환경 자원 가용성획득?'처리: '환경 할당/격리,데이터 시드, 트랜잭션 설정'출력: '테스트 실행 재시도정책 적용'출력: '리포트 집계, 품질게이트, 커버리지 업데이트'

pytest 마커로 실행 클래스를 나누는 예시

전제조건은 Python 3.10+, pytest 7.x, Linux/Windows/Mac 공통 환경이다. 표준 마커를 이용해 테스트 클래스를 구분하고 CI 잡을 분리한다.

pytest.ini

[pytest]
markers =
  unit: Unit tests
  integration: Integration tests
  e2e: End-to-end tests
  perf: Performance tests
  security: Security tests
  priority_p0: Highest priority
  priority_p1: High priority
  risk_high: High risk change
  contract: Contract tests
addopts = -ra

tests/test_sample.py

import pytest

@pytest.mark.unit
@pytest.mark.priority_p1
def test_sum():
    assert 1 + 1 == 2

@pytest.mark.integration
@pytest.mark.contract
def test_user_api_contract(api_client):
    # 계약 스키마 검증
    resp = api_client.get("/v1/users/1")
    assert resp.status_code == 200
    assert set(resp.json().keys()) >= {"id", "name", "email"}

@pytest.mark.e2e
@pytest.mark.risk_high
def test_checkout_flow(browser):
    browser.goto("/products/1")
    browser.click("add_to_cart")
    browser.goto("/checkout")
    assert browser.text("order_status") == "READY"

GitHub Actions 예시(.github/workflows/tests.yml)

name: tests
on:
  pull_request:
  push:
jobs:
  unit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with: { python-version: "3.11" }
      - run: pip install -U pip pytest
      - run: pytest -m "unit and not perf and not e2e" -q
  integration_contract:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with: { python-version: "3.11" }
      - run: pip install -U pip pytest
      - run: pytest -m "integration or contract" -q
  e2e_smoke:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with: { python-version: "3.11" }
      - run: pip install -U pip pytest
      - run: pytest -m "e2e and not perf" --maxfail=1 -q

변경 영향 분석에는 최근 커버리지 파일을 이용해 영향 모듈과 관련된 테스트를 우선 실행한다. 플레이키 테스트는 재시도 횟수 상한과 격리 라벨을 적용하고 별도 대시보드에서 집계한다. DB는 테스트별 스키마와 트랜잭션 롤백, 고정 시드 데이터를 사용해 환경 일관성을 유지한다.

속도와 신뢰도를 함께 관리할 기준

표준화는 코어 분류 축에 적용하되 팀별 보조 태그는 허용할 수 있다. 다만 클래스가 지나치게 세분화되면 유지비가 커진다.

부분 실행은 파이프라인을 빠르게 만들지만 회귀 누락 위험이 있다. 야간 풀회귀와 카나리로 이를 보완한다. 프로덕션과 유사한 환경은 신뢰도를 높이는 대신 비용과 속도를 악화시키므로 고위험 클래스에만 적용한다.

자동화는 상위 20% 경로와 P0 위험군부터 우선 적용하고 ROI를 기준으로 단계적으로 넓힌다. 분류 체계는 테스트를 목적과 위험 기준으로 구조화해 파이프라인 효율, 품질 일관성, 감사 대응력을 함께 다루는 운영 프레임이다.

테스트 분류 체계품질 게이트CI/CD변경 영향 분석플레이키 테스트