본문으로 건너뛰기
중급약 28분

Zephyr 실전: Squad와 Scale, 같은 이름 다른 도구

테스트 케이스가 Jira 이슈인가 아닌가 — 이 한 가지가 두 제품의 모든 차이를 만든다. 사이클 운영과 ZQL, 커버리지 추적, 리포트·가젯·API까지 실무 기준으로 다룬다.

  • #Zephyr
  • #ZephyrScale
  • #ZephyrSquad
  • #Jira
  • #추적성
  • #ZQL

개념

검색하기 전에 알아야 할 것 — Zephyr는 하나가 아니다

Zephyr 사용법을 검색하면 화면이 서로 다른 자료들이 섞여 나온다. 메뉴 이름도 다르고, 어떤 글은 "이슈 유형을 Test로 선택하라"고 하는데 다른 글에는 그런 메뉴가 없다. 헤매기 딱 좋다.

이유는 단순하다. Zephyr라는 이름을 쓰는 제품이 셋이다.

제품형태핵심 성격
Zephyr Squad (구 Zephyr for Jira)Jira 애드온테스트 케이스가 Jira 이슈 다
Zephyr Scale (구 TM4J)Jira 애드온테스트 케이스가 별도 저장소 에 산다
Zephyr Enterprise독립 제품Jira 없이도 도는 엔터프라이즈 TMS

실무에서 가장 먼저 할 일은 "우리가 쓰는 게 셋 중 무엇인가"를 확인하는 것이다. 이걸 모르고 문서를 읽으면 없는 메뉴를 계속 찾게 된다. 확인 방법은 간단하다 — Jira 프로젝트 왼쪽 메뉴에 테스트들(Tests) 이 있고 이슈 유형 목록에 Test 가 있으면 Squad, 별도의 Zephyr Scale 메뉴와 PROJ-T123 형태의 키가 보이면 Scale이다.

이 레슨은 Jira 애드온인 Squad와 Scale 두 가지 를 다룬다. 모듈 22 레슨 1에서 "Jira 플러그인형"이라는 계열로 묶어 봤던 것을, 이제 화면 수준으로 내려간다.

결정적 차이 — 케이스가 Jira 이슈인가 아닌가

두 제품의 모든 차이가 여기서 파생된다.

[ Zephyr Squad ]                    [ Zephyr Scale ]
 
Jira 이슈 저장소                     Jira 이슈 저장소
 ├─ Story  SHOP-12                   ├─ Story  SHOP-12
 ├─ Bug    SHOP-45                   └─ Bug    SHOP-45
 └─ Test   SHOP-88  ← 케이스가                    ▲
              여기 산다                           │ 커버리지 링크
                                                 │
                                    Zephyr Scale 저장소(별도)
                                     └─ 폴더 / 하위 폴더
                                         └─ 케이스 SHOP-T123

여기서 실무적 결과가 갈린다.

SquadScale
케이스의 정체Jira 이슈(유형 Test)별도 엔티티(키 PROJ-T123)
검색JQL로 검색됨Scale 자체 검색(Jira 전체를 뒤지지 않아 빠름)
정리 구조폴더 없음 — 컴포넌트·레이블로 분류폴더 계층
재사용·파라미터화제한적지원
프로젝트 간 사용프로젝트 단위크로스 프로젝트 실행·리포트
Jira 워크플로·권한이슈이므로 그대로 적용별도 체계
케이스가 많아지면Jira 이슈 수가 함께 폭증Jira는 그대로
적합한 규모소규모 애자일 팀큰 케이스 라이브러리, 추적성 요구가 큰 조직

"케이스가 Jira 이슈다"의 양면성 을 이해하는 것이 중요하다.

  • 좋은 점 — 별도로 배울 것이 적다. 앞 레슨(m22-l07)에서 배운 JQL이 그대로 통하고, Jira의 권한·워크플로·대시보드가 그대로 적용된다.
  • 나쁜 점 — 케이스 2,000개를 만들면 Jira 이슈가 2,000개 늘어난다. 이슈 검색이 느려지고, 백로그·보드 필터에 테스트가 섞여 들어오고, 이슈 기반 지표(모듈 6 레슨 5)가 오염된다.

두 번째 항목이 실무에서 실제로 문제가 된다. Squad를 쓰는 팀은 모든 JQL에 issuetype != Test 를 습관적으로 붙여야 하는 상황을 자주 만난다. 앞 레슨에서 만든 결함 지표 쿼리들도 마찬가지다.

설치와 활성화

두 제품 모두 Atlassian Marketplace에서 설치하는 애드온이고, Jira 관리자 권한이 필요하다.

설정(톱니바퀴) → 앱 → 앱 찾기(Find new apps)
   → "Zephyr Squad" 또는 "Zephyr Scale" 검색 → 설치
   → 프로젝트별로 활성화

모듈 22 레슨 10의 draw.io와 같은 패턴이다. 일반 사용자는 설치할 수 없다. 요청할 때는 어느 제품인지 정확히 적어야 한다 — 이름이 비슷해 다른 것이 설치되는 일이 실제로 있다.

Squad 실전 — 버전에서 시작해 사이클로 끝난다

Squad의 작업 흐름은 버전(릴리즈)을 축으로 돈다. 순서대로 보자.

1) 버전 생성 (Jira)

먼저 테스트 대상 버전을 만든다. 개발팀이 이미 버전을 관리하고 있다면 그것을 쓰면 된다. 없다면 QA가 만드는데, 이때 추적 가능한 명명 규칙 을 쓰는 것이 중요하다.

버전명 체계가 없는 조직이라면 서비스명.날짜 형태를 권한다. 나중에 "이 결함이 언제 발견됐나", "이 검증은 어느 시점 것인가"를 추적할 때 단서가 된다.

2) 관리 이슈·스토리 생성 (Jira)

테스트 케이스가 매달릴 상위 이슈를 만든다. 기능이 복잡하고 요구사항 분류가 많으면 스토리로 쪼갠다. 하나의 관리 이슈 아래 여러 스토리가 붙는 구조다. 모듈 22 레슨 6에서 본 업무 항목 계층이 여기서 쓰인다.

3) 테스트 케이스 작성 (Zephyr)

이슈 유형을 Test 로 고르면 화면 하단에 테스트 스텝 입력 영역이 생긴다.

칸무엇을 쓰나
요약(Summary)테스트 케이스 제목
설명(Description)이 케이스의 목적
Step수행할 행위
Test Data그 스텝에서 쓰는 데이터·사전 조건
Expected Result그 행위의 기대 결과

여기서 반드시 지켜야 할 원칙이 하나 있다.

케이스는 독립적으로 작성한다. 하나만 실행한 결과와, 열 개를 연달아 실행했을 때의 결과가 같아야 한다.

모듈 10에서 배운 테스트 독립성이 수동 케이스에도 그대로 적용된다. 앞 케이스가 만든 데이터에 의존하는 케이스는 실행 순서가 바뀌는 순간 깨지고, 원인 파악에 실제 테스트보다 긴 시간이 든다.

작성 중인 케이스의 상태를 관리하는 요령 도 유용하다. 케이스도 Jira 이슈이므로 워크플로 상태가 있다 — 작성 중에는 To Do·In Progress, 작성이 끝나면 Closed. 이렇게 두면 동료가 "지금 어디까지 작성됐나"를 물어보지 않아도 안다.

4) 테스트 사이클 구성 (Zephyr)

작성된 케이스를 실행하려면 사이클(Test Cycle) 로 묶어야 한다. 사이클은 버전 아래에 만든다 — 그래서 1번의 버전 생성이 먼저였다.

사이클에 케이스를 담는 방법이 여러 가지다.

방법언제 쓰나
케이스에서 버전을 지정케이스를 만들면서 바로 배정
사이클에서 케이스를 추가실행 계획을 세우며 고를 때
저장된 필터로 일괄 추가"결제 컴포넌트 전체"처럼 조건으로 담을 때
과거 사이클 복제회귀처럼 매번 같은 묶음을 돌릴 때

아래 두 방법을 알아두면 시간이 크게 절약된다. 특히 복제는 회귀 사이클 운영의 기본이다 — 매 릴리즈마다 케이스를 다시 고르는 팀이 의외로 많다.

5) 실행

사이클에서 실행 버튼(E)을 누르면 케이스가 열리고, 결과를 기록한 뒤 다음 케이스로 바로 넘어가는 내비게이션 이 제공된다. 이 흐름이 있어야 수동 회귀를 연속으로 돌 수 있다. 진행률은 막대 그래프로 표시되고, 마우스를 올리면 상태별 비율이 나온다.

앞 레슨(TestRail)에서 다룬 상태 기록 원칙이 여기서도 그대로다 — 실행 불가와 실패를 구분 하고, 실패에는 결함을 연결한다.

ZQL — Zephyr의 쿼리 언어

Squad는 테스트 실행을 검색하는 자체 쿼리 언어 ZQL(Zephyr Query Language) 을 제공한다. 테스트들 → 테스트 실행 검색 메뉴에서 쓴다.

project = "SHOP" AND fixVersion = "v2.4.0" AND executionStatus = FAIL

문법은 JQL과 닮았다. 앞 레슨에서 JQL을 익혔다면 곧바로 쓸 수 있다. 차이는 검색 대상이 이슈가 아니라 테스트 실행 이라는 점이다.

QA가 자주 쓰는 형태들이다.

-- 이번 버전에서 실패한 실행
project = "SHOP" AND fixVersion = "v2.4.0" AND executionStatus = FAIL
 
-- 아직 실행되지 않은 것 (분모를 밝히기 위해)
project = "SHOP" AND fixVersion = "v2.4.0" AND executionStatus = UNEXECUTED
 
-- 내가 실행해야 할 것
project = "SHOP" AND executionAssignee = currentUser()
  AND executionStatus IN (UNEXECUTED, WIP)

두 번째 쿼리를 강조하고 싶다. 앞 레슨에서 다룬 그대로 — 미실행 건수를 밝히지 않은 통과율은 신뢰를 잃는다.

Scale 실전 — 폴더와 커버리지

Scale은 구조가 다르다. 케이스가 Jira 이슈가 아니므로 폴더로 정리 하고, Jira 이슈와는 커버리지 링크 로 연결한다.

테스트 케이스 (폴더 계층)
   └─ 결제 / 카드결제 / 3DS인증
        └─ SHOP-T142  "3DS 인증 실패 시 재시도"
                │
                │  커버리지 링크
                ▼
        Jira 스토리 SHOP-12 "3DS 인증 도입"

이 링크가 있으면 Jira 쪽에서 JQL 함수로 커버리지를 질문할 수 있다. Scale이 제공하는 JQL 함수들이 그것이다.

-- 테스트로 커버되지 않은 스토리 찾기 (커버리지 구멍)
project = SHOP AND issuetype = Story AND NOT issue in hasTestCoverage()
 
-- 특정 케이스가 커버하는 이슈
issue in coveredBy("SHOP-T142")

첫 번째 쿼리가 실무에서 값을 한다. "이번 릴리즈 스토리 중 테스트 케이스가 하나도 없는 것" 을 기계적으로 찾아낸다. 모듈 2에서 배운 요구사항 추적성이 여기서 쿼리 한 줄이 되는 셈이다.

Scale의 실행 단위는 테스트 사이클 이고, 그 위에 테스트 플랜 을 둘 수 있다. 앞 레슨의 TestRail 구조(런·플랜·마일스톤)와 개념이 대응한다. 도구가 달라도 케이스 저장소와 실행 회차를 분리한다 는 골격은 같다.

리포트와 대시보드 가젯

Scale의 보고서(Reports) 탭에는 내장 리포트가 여럿 있는데, 가장 많이 쓰는 것이 테스트 실행 결과(요약) 다. 이 리포트가 담는 항목들이다.

항목답하는 질문
전체 진행 상황몇 개가 끝났고 몇 개가 남았나
테스트 실행 결과통과·실패·미실행 비율
테스트 실행 노력추정 시간 대비 실제 소요
보고된 이슈이 기간에 몇 건의 결함이 나왔나
시간 경과에 따른 결과(누적)추세 — 진행이 정체되고 있지 않은가
범위별 결과어느 영역이 문제인가
환경별 결과특정 환경에서만 깨지는가

리포트는 프로젝트·에픽·스토리·버전·테스트 사이클로 필터할 수 있고, PDF로 출력하거나 Excel로 내보낼 수 있다. Jira 계정이 없는 이해관계자와 공유해야 할 때 이 기능이 실질적으로 쓰인다.

Scale은 Jira 대시보드 가젯 도 제공한다. 범위별 실행 결과, 테스트 사이클별 실행 결과 같은 것들이다. 모듈 22 레슨 8에서 만든 QA 대시보드에 이 가젯을 얹으면 결함 현황과 테스트 진행이 한 화면 에 모인다.

그 레슨의 원칙이 여기서도 그대로 적용된다 — 독자별로 나누고, 3~5개로 제한하고, 행동으로 이어지지 않는 지표는 뺀다. 그리고 리포트를 만들어 놓고 회의 동선에 넣지 않으면 아무도 열지 않는다.

자동화 결과 연동 — API

두 제품 모두 REST API로 테스트 실행 결과를 등록할 수 있다. 앞 레슨의 TestRail trcli 에 해당하는 자리다.

CI 파이프라인
   └─ 자동화 테스트 실행 → 리포트 생성(JUnit XML 등)
        └─ API 호출로 실행 결과 등록
             → 사이클에 자동화 결과가 함께 쌓인다

여기서도 같은 주의점이 반복된다.

  • 테스트가 실패해도 결과는 올린다. CI 스텝에 if: always() 상당의 조건을 걸지 않으면 가장 보고 싶은 회차의 데이터가 빈다.
  • 자동화 테스트와 케이스의 매핑 규칙을 먼저 정한다. 규칙 없이 돌리면 실행할 때마다 케이스가 새로 생기거나, 결과가 어디에도 붙지 않는다.
  • API 토큰을 CI 시크릿으로 관리한다. 모듈 14에서 배운 그대로다.

결국 남는 것은 추적성

Zephyr를 Jira 애드온으로 쓰는 이유를 한 줄로 정리하면 이것이다.

요구사항(스토리)  →  테스트 케이스  →  사이클 실행 결과  →  결함
      SHOP-12          SHOP-T142         v2.4.0 회귀        SHOP-45
        └───────────── 한 화면에서 따라갈 수 있다 ─────────────┘

이 사슬이 데이터로 남으면 답할 수 있는 질문이 늘어난다.

  • 이 요구사항은 검증됐는가, 결과는?
  • 이 결함은 어떤 테스트에서 나왔는가?
  • 이번 릴리즈에서 검증되지 않은 스토리는?
  • 이 케이스는 지난 다섯 번의 릴리즈에서 몇 번 실패했는가?

모듈 25에서 본 인증·감사 대응이 요구하는 것이 정확히 이 사슬이고, 규제 도메인이 아니어도 릴리즈 판단의 근거가 된다. 별도 도구를 쓰면 이 연결을 사람이 유지해야 하지만, Jira 애드온은 구조적으로 붙어 있다 — 그게 이 계열의 존재 이유다. 대신 모듈 22 레슨 1에서 본 대가, Jira에 종속된다 는 점을 함께 감수하는 것이다.

실무에서 왜 필요한가

국내 조직에서 Jira를 쓰는 팀이라면 Zephyr는 가장 만날 확률이 높은 테스트 관리 도구다. 그리고 채용공고에 "Zephyr 사용 경험"이라고만 적혀 있어도, 면접에서 Squad와 Scale을 구분해서 말할 수 있으면 실제로 써본 사람이라는 신호가 된다. 두 제품을 섞어 말하는 순간 반대 신호가 되기도 한다.

실무 효용은 추적성에서 온다. 릴리즈 판단 회의에서 "이번 버전 스토리 18개 중 테스트 케이스가 없는 것이 3개이고, 실행 결과는 통과 87%, 미실행 9건 입니다"라고 말할 수 있는 근거가 쿼리 한 줄에서 나온다. 스프레드시트로 관리하는 팀은 이 문장을 만드는 데 반나절을 쓴다.

그리고 이 레슨에서 배운 것은 도구가 바뀌어도 남는다. 케이스 저장소와 실행 회차의 분리, 버전을 축으로 한 사이클 운영, 커버리지 링크, 미실행 건수를 밝히는 습관. 앞 레슨의 TestRail과 구조가 대응한다는 것을 확인했다면, 다음에 처음 보는 TMS를 만나도 하루면 적응한다.

실습 과제

과제 1 — 우리 조직의 Zephyr 판별하기 (10분)

Jira에 접근할 수 있다면 다음을 확인한다(접근할 수 없다면 각 제품의 공식 문서 스크린샷으로 대신한다).

확인 항목결과
이슈 유형 목록에 Test 가 있는가
왼쪽 메뉴에 테스트들 또는 Zephyr Scale 이 있는가
케이스 키가 SHOP-88 형태인가 SHOP-T88 형태인가
결론: Squad인가 Scale인가

Squad라면 추가로 확인한다 — 전체 이슈 중 Test 유형이 몇 %인가?

해설 보기

마지막 질문이 이 과제의 핵심이다. project = X AND issuetype = Test 와 project = X 의 건수를 비교해보면, 팀에 따라 테스트 케이스가 전체 이슈의 절반을 넘는 경우도 있다.

그 상태에서 앞 레슨(m22-l07)에서 만든 결함 지표 쿼리들을 다시 보면 문제가 보인다. project = X AND created >= -30d 같은 쿼리에 테스트 케이스가 섞여 들어가 "이번 달 유입 이슈"가 부풀려진다.

대응은 간단하다 — 지표용 쿼리에 issuetype != Test 를 기본으로 붙인다. 저장된 필터를 점검해 이 조건이 빠진 것을 찾아보라. Squad를 쓰는 조직에서 자주 발견되는 오염이다.

과제 2 — 사이클 운영 계획 세우기 (20분)

다음 릴리즈의 테스트 사이클을 설계한다.

  1. 버전 명명 규칙을 정한다(추적 가능하게)
  2. 만들 사이클 목록과 각각의 목적을 적는다(예: 스모크 / 기능 회귀 / 결함 재검증)
  3. 각 사이클에 케이스를 담을 방법 을 정한다(네 가지 중 어느 것)
  4. 회귀 사이클을 복제로 운영 한다면, 매 릴리즈마다 무엇을 손봐야 하는지 적는다
해설 보기

4번에서 자주 놓치는 것 두 가지. (1) 지난 회차의 실행 결과가 함께 복제되지 않도록 확인해야 한다. 도구·설정에 따라 다르므로 첫 복제 때 반드시 검증한다. (2) 지난 릴리즈에서 추가된 신규 케이스가 회귀 사이클에 자동으로 들어오지 않는다 — 회귀 스위트에 편입하는 절차 를 정해두지 않으면 새 기능이 영원히 회귀 대상에서 빠진다.

두 번째가 실무에서 조용히 사고를 만든다. 모듈 11 레슨 2에서 배운 "무엇을 자동화할 것인가"와 같은 문제 — 회귀 대상 편입 기준 을 명시적으로 정해두는 팀이 드물다.

과제 3 — 커버리지 구멍 찾기 (15분)

Scale을 쓴다면 JQL 함수로, Squad를 쓴다면 링크·컴포넌트 기준으로 테스트 케이스가 없는 요구사항 을 찾는 쿼리를 작성한다.

-- Scale 예시
project = SHOP AND issuetype = Story AND fixVersion = "v2.4.0"
  AND NOT issue in hasTestCoverage()

결과가 나오면 각 항목에 대해 판정한다.

  • 정말 테스트가 필요한데 빠진 것
  • 테스트는 있는데 링크를 안 걸어둔 것
  • 테스트가 필요 없는 것(그렇다면 왜)

두 번째가 가장 많이 나온다. 그게 무엇을 의미하는지 한 줄로 적는다.

과제 4 — 리포트를 회의 동선에 넣기 (12분)

테스트 실행 결과(요약) 리포트 또는 대시보드 가젯을 설정하고, 다음을 정한다.

  • 어느 회의에서 이 화면을 열 것인가
  • 그 자리에서 어떤 판단을 내리는가(행동으로 이어지는가)
  • Jira 계정이 없는 이해관계자에게는 어떻게 전달하는가
  • 이 화면이 깨졌을 때 어떻게 알아차릴 것인가

마지막 항목은 모듈 22 레슨 8에서 다룬 그대로다 — 0건이 "좋아졌다"인지 "고장났다"인지 구분할 장치가 필요하다.

자가 체크리스트

  • Zephyr Squad·Scale·Enterprise 세 제품을 구분하고, 우리 조직이 무엇을 쓰는지 판별할 수 있다
  • 케이스가 Jira 이슈인지 아닌지가 만드는 차이를 검색·정리 구조·규모 관점에서 설명할 수 있다
  • Squad에서 테스트 케이스가 늘 때 Jira 지표가 오염되는 문제와 대응을 말할 수 있다
  • Squad의 작업 흐름(버전 → 상위 이슈 → 케이스 → 사이클 → 실행)을 순서대로 설명할 수 있다
  • 테스트 케이스를 독립적으로 작성해야 하는 이유를 실행 순서 관점에서 설명할 수 있다
  • 사이클에 케이스를 담는 네 가지 방법을 알고, 회귀에는 복제가 왜 유용한지 말할 수 있다
  • ZQL로 실패·미실행·내 담당 실행을 검색할 수 있다
  • 미실행 건수를 함께 밝혀야 하는 이유를 설명할 수 있다
  • Scale의 폴더 구조와 커버리지 링크가 무엇을 가능하게 하는지 말할 수 있다
  • hasTestCoverage() 로 커버리지 구멍을 찾는 쿼리를 쓸 수 있다
  • 테스트 실행 결과(요약) 리포트의 주요 항목과, 대시보드 가젯 활용법을 설명할 수 있다
  • API로 자동화 결과를 연동할 때 주의할 세 가지를 말할 수 있다
  • 요구사항 → 케이스 → 실행 → 결함 사슬이 왜 이 계열의 존재 이유인지 설명할 수 있다

흔한 실수

  • Squad와 Scale을 구분하지 않고 문서를 찾는다. 없는 메뉴를 계속 찾게 된다. 먼저 우리가 무엇을 쓰는지 확인한다.
  • Squad에서 지표 쿼리에 issuetype != Test 를 안 붙인다. 테스트 케이스가 결함 지표에 섞여 들어가 유입 건수가 부풀려진다.
  • 케이스 간에 의존성을 만든다. 앞 케이스가 만든 데이터에 기대면 실행 순서가 바뀔 때 깨지고, 원인 파악에 더 긴 시간이 든다.
  • 버전 없이 사이클을 만들려 한다. Squad의 사이클은 버전 아래 붙는다. 버전 체계부터 정리해야 한다.
  • 매 릴리즈마다 회귀 케이스를 손으로 다시 고른다. 복제나 저장된 필터로 담는다.
  • 회귀 스위트 편입 기준을 정하지 않는다. 새로 만든 케이스가 회귀 대상에 영원히 들어가지 못한다.
  • 통과율만 보고하고 미실행을 감춘다. 분모를 숨긴 숫자는 신뢰를 잃는다.
  • 커버리지 링크를 안 걸고 추적성을 기대한다. 링크가 없으면 커버리지 리포트는 영원히 비어 있다.
  • 자동화 결과를 API로 올리지 않는다. 수동은 Zephyr, 자동은 CI 로그에 남아 릴리즈 판단을 두 화면에서 하게 된다.
  • 리포트를 만들고 회의 동선에 넣지 않는다. 아무도 열지 않는 화면이 된다.

참고 자료

낯선 말 풀이

이 레슨에 나온 약어입니다. 본문에서도 처음 나올 때 점선으로 표시해 두었습니다 (제목과 링크 글자는 그대로 둡니다).

JQL — 지라 질의 언어
결함 관리 도구에서 "이런 조건인 건만 보여 달라"고 적는 말.
QA — 품질보증
만든 것이 쓸 만한지 확인하고, 애초에 덜 망가지게 만드는 방법을 정하는 일. "테스트"는 그 일의 일부다.
PDF — 피디에프
어디서 열어도 모양이 같게 나오도록 만든 문서 형식.
API — 응용 프로그램 인터페이스
프로그램끼리 주고받는 창구. 사람이 화면 버튼을 누르는 대신, 프로그램이 정해진 주소로 요청을 보내 답을 받는다.
REST — 레스트
창구를 만드는 가장 흔한 방식. 주소 하나가 자원 하나를 가리키고, 동작은 정해진 몇 가지 말로 구분한다.
CI — 지속적 통합
코드를 올릴 때마다 자동으로 합쳐서 빌드하고 시험까지 돌리는 방식.

용어집 전체 보기