개념
하나만 이해하면 되는 것 — 케이스와 실행은 다른 곳에 산다
TestRail을 처음 열면 메뉴가 많아 막막하다. 그런데 이 도구의 구조는 문장 하나로 요약된다.
케이스를 쓰는 곳(Test Cases)과 실행하는 곳(Test Runs)이 분리돼 있다.
모듈 7(레슨 1)에서 "반복 실행 이력이 만드는 가치"를 배웠다. 같은 케이스를 여러 번 실행하고 그 결과를 비교할 수 있어야 한다는 것. TestRail은 그 요구를 구조로 못 박아둔 도구 다.
프로젝트(Project)
└─ 테스트 스위트(Suite) ← 케이스가 사는 저장소
└─ 섹션(Section) / 하위 섹션
└─ 케이스(Case) ← 여기서는 실행하지 않는다. 정의만 있다
│
│ 실행할 때 케이스를 "선택해서" 런에 담는다
▼
프로젝트
└─ 마일스톤(Milestone) ← 릴리즈 단위 묶음
└─ 테스트 플랜(Plan) ← 여러 런의 묶음 + 구성 조합
└─ 테스트 런(Run) ← 한 번의 실행 회차
└─ 테스트(Test) ← 런에 담긴 케이스의 "그때 그 인스턴스"
└─ 결과(Result) ← Passed / Failed / Blocked …이 그림을 이해하면 초보자가 가장 자주 하는 질문들이 한 번에 풀린다.
- "케이스를 고쳤는데 지난 런의 내용이 안 바뀌어요" → 당연하다. 런에 담긴 테스트는 그때의 스냅샷 이다. 과거 실행 이력이 나중 수정으로 훼손되면 이력의 의미가 없다.
- "같은 케이스를 두 번 실행하고 싶어요" → 런을 두 개 만든다. 케이스는 하나, 실행은 여럿이다.
- "이번 릴리즈 결과만 모아 보고 싶어요" → 마일스톤으로 묶는다.
프로젝트 모드 — 처음에 정하고 되돌리기 어려운 선택
프로젝트를 만들 때 스위트 모드 를 고른다. 세 가지다.
| 모드 | 구조 | 적합한 상황 |
|---|---|---|
| 단일 저장소 | 케이스 전체가 하나의 저장소에, 섹션으로만 구분 | 대부분의 팀. 단순하고 관리가 쉽다 |
| 단일 저장소 + 베이스라인 | 저장소를 분기(branch)해 버전별 케이스를 병행 관리 | 여러 제품 버전을 동시에 유지보수 |
| 다중 테스트 스위트 | 스위트를 여러 개 만들어 완전히 분리 | 한 프로젝트 안에 성격이 크게 다른 영역이 공존 |
실무 조언은 명확하다 — 특별한 이유가 없으면 단일 저장소로 시작한다.
이유가 둘이다. 첫째, 다중 스위트는 관리 비용이 눈에 띄게 늘고 대부분의 팀에게 그만한 이득이 없다. 섹션으로 나누면 충분하다. 둘째, 모드 변경에는 제약이 있다. 특히 다중 스위트로 갔다가 단일 저장소로 되돌리는 것은 사실상 어렵다. 시작 시점의 선택이 오래 간다는 뜻이다.
베이스라인은 "v1.x는 유지보수하면서 v2.x를 개발한다"처럼 케이스 자체가 버전별로 갈라지는 상황에서만 값을 한다. 그런 상황이 아니라면 복잡도만 늘어난다.
케이스 작성 — 템플릿과 References
케이스를 만들 때 템플릿 을 고른다.
| 템플릿 | 구조 | 언제 |
|---|---|---|
| Test Case (Text) | 전제조건 + 절차 + 기대결과를 자유 서술 | 짧고 단순한 케이스 |
| Test Case (Steps) | 단계별로 행위와 기대결과를 행으로 분리 | 결과를 단계별로 기록해야 할 때 |
| Exploratory Session | 미션(Charter)과 목표 중심 | 모듈 5의 탐색적 테스팅 세션 |
Steps 템플릿의 장점은 실행 중에 어느 단계에서 실패했는지 를 기록할 수 있다는 점이다. 8단계짜리 케이스가 "Failed"라고만 남으면 나중에 아무도 어디서 깨졌는지 모른다.
References 필드가 QA에게 가장 중요한 칸이다. 여기에 요구사항이나
Jira 키(SHOP-241)를 적어두면, 케이스가 어떤 요구사항을 검증하는지가
데이터로 남는다. 모듈 2에서 배운 요구사항 추적성, 모듈 25에서 본 규제
도메인의 추적성 요구가 여기서 실체를 갖는다.
이 필드를 채워두면 나중에 Coverage for References 리포트 로 "이 요구사항을 검증하는 케이스가 있는가, 결과는 어땠는가"를 뽑을 수 있다. 안 채워두면 그 리포트는 영원히 비어 있다.
섹션 구조를 짜는 원칙 도 짚어두자. 흔한 실수는 화면 구조를 그대로 베끼는 것이다.
| 잘 안 되는 구조 | 더 나은 구조 |
|---|---|
| 화면 이름 그대로(로그인 화면 / 마이페이지 화면 …) | 기능·흐름 단위(인증 / 주문 / 결제 / 알림) |
| 개발 모듈 구조 그대로 | 사용자 여정 단위 |
화면 기준으로 짜면 화면이 개편될 때마다 케이스 트리를 다시 짜야 하고, 한 기능이 여러 화면에 걸치면 케이스가 흩어진다. 기능 단위가 화면보다 오래 산다.
런·플랜·구성 — TestRail이 강한 지점
여기가 다른 도구와 확실히 갈리는 부분이다.
| 무엇인가 | 언제 쓰나 | |
|---|---|---|
| 테스트 런(Run) | 케이스 묶음을 한 번 실행하는 회차 | 회귀 1차, 스모크 등 단일 실행 |
| 테스트 플랜(Plan) | 여러 런을 하나로 묶은 것 | 한 릴리즈에서 여러 스위트를 동시에 돌릴 때 |
| 구성(Configuration) | 환경 축(브라우저·OS·기기 등) | 같은 케이스를 환경별로 실행해야 할 때 |
구성이 핵심이다. 플랜에 구성을 붙이면 케이스 × 환경 조합만큼 런이 자동 생성 된다.
플랜: "v2.4.0 릴리즈 회귀"
├─ 런: 결제 스위트 × Chrome / Windows
├─ 런: 결제 스위트 × Safari / macOS
├─ 런: 결제 스위트 × Chrome / Android
└─ 런: 알림 스위트 × Chrome / Windows모듈 13(레슨 8)에서 배운 크로스 브라우저 전략이 도구에서 이렇게 구현된다. 조합을 손으로 만들면 관리가 무너지지만, 구성으로 만들면 "Safari에서만 실패하는 케이스" 를 리포트로 바로 뽑을 수 있다.
마일스톤 은 그 위의 묶음이다. 릴리즈 단위로 런·플랜을 모으고, 시작·종료일을 걸어 진행률을 본다. 하위 마일스톤으로 계층을 만들 수도 있다. 실무에서는 릴리즈 = 마일스톤 으로 놓는 것이 가장 단순하고 잘 돈다.
결과 상태 — Blocked를 제대로 쓰는 팀이 드물다
기본 상태는 다섯 개다.
| 상태 | 의미 | 실무에서 자주 틀리는 점 |
|---|---|---|
| Passed | 기대대로 동작 | |
| Failed | 기대와 다름 | 결함 등록 없이 Failed만 남기면 추적이 끊긴다 |
| Blocked | 실행할 수 없었음 | 이걸 Failed로 기록하는 팀이 많다 |
| Retest | 다시 확인 필요 | 수정 후 재검증 대기 표시로 유용 |
| Untested | 아직 실행 안 함 | 수동으로 지정할 수 없는 기본 상태다 |
Blocked와 Failed의 구분이 지표를 바꾼다. 로그인 서버가 죽어서 결제 케이스를 아예 못 돌렸다면 그건 Failed가 아니다. Failed로 기록하면 "결제 기능에 결함 20건"처럼 보이고, 실제로는 환경 문제 하나다. 모듈 6 (레슨 5)의 지표가 오염되는 전형적 경로다.
Failed를 기록할 때는 Defects 필드에 결함 키를 넣는다. Jira를 연동해 두면 이 칸에서 바로 이슈를 만들거나 링크할 수 있고, 그러면 케이스 → 실행 결과 → 결함 의 사슬이 완성된다. 이 사슬이 있어야 "이 결함은 어떤 테스트에서 나왔나", "이 요구사항의 검증 상태는 무엇인가"에 답할 수 있다.
필요하면 커스텀 상태를 추가할 수 있지만, 늘리기 전에 정말 필요한지 따져본다. 상태가 늘면 집계가 복잡해지고 사람마다 다르게 쓴다.
리포트 — 무엇을 언제 뽑는가
TestRail의 리포트는 종류가 많다. QA가 실제로 쓰는 것 위주로 정리한다.
| 리포트 | 답하는 질문 | 쓰는 시점 |
|---|---|---|
| Summary | 이번 실행의 전체 통과율은? | 차수 종료 시 |
| Comparison for Cases | 같은 케이스가 회차별로 어떻게 변했나 | 회귀 추세 확인 |
| Coverage for References | 이 요구사항은 검증됐나 | 릴리즈 판단, 감사 대응 |
| Defects | 이 실행에서 나온 결함은? | 결함 트리아지 |
| Activity | 누가 언제 무엇을 했나 | 진행 상황 점검 |
Comparison for Cases가 가장 저평가된 리포트다. 회차별로 같은 케이스의 결과를 나란히 보여주므로, 자꾸 깨지는 케이스 가 눈에 띈다. 모듈 13 (레슨 6)에서 배운 플래키 테스트를 수동 케이스 영역에서 찾아내는 방법이기도 하다. 매번 통과했다가 이번에만 실패한 것과, 세 번 중 두 번 실패하는 것은 전혀 다른 문제다.
자동화 결과 밀어넣기 — trcli
수동 케이스만 관리하는 TestRail은 절반만 쓰는 것이다. 자동화 결과를 같은 화면에 모으면 릴리즈 판단을 한 곳에서 할 수 있다.
공식 CLI 도구가 trcli 다. JUnit XML, Robot Framework, Cucumber 등 표준 리포트 형식을 읽어 TestRail에 런을 만들고 결과를 올린다.
pip install trcli가장 기본적인 사용 형태다.
trcli -y \
-h https://example.testrail.io \
--project "SHOP" \
-u "$TESTRAIL_USER" -k "$TESTRAIL_API_KEY" \
parse_junit \
-f "reports/junit-*.xml" \
--title "CI 회귀 - build 482"CI에 붙이면 모듈 14(레슨 2)에서 만든 워크플로의 마지막 단계가 된다.
# .github/workflows/test.yml 의 마지막 단계 예시
- name: TestRail에 결과 업로드
if: always() # 테스트가 실패해도 결과는 올린다
run: |
trcli -y -h "$TR_HOST" --project "SHOP" \
-u "$TR_USER" -k "$TR_KEY" \
parse_junit -f "reports/*.xml" \
--title "CI ${{ github.ref_name }} #${{ github.run_number }}" \
--milestone-id 42
env:
TR_HOST: ${{ secrets.TESTRAIL_HOST }}
TR_USER: ${{ secrets.TESTRAIL_USER }}
TR_KEY: ${{ secrets.TESTRAIL_API_KEY }}if: always() 를 빠뜨리면 테스트가 실패했을 때 결과가 안 올라간다.
정작 가장 보고 싶은 회차의 데이터가 비는 셈이라, 이 한 줄이 중요하다.
자동화 결과와 기존 케이스를 잇는 방식(case matcher)도 알아둬야 한다. 테스트 이름에 케이스 ID를 넣거나, 프로퍼티로 매핑하거나, 자동 생성하게 할 수 있다. 매핑 규칙을 정하지 않으면 실행할 때마다 케이스가 새로 만들어져 저장소가 부풀어 오른다 — 실제로 자주 벌어지는 사고다.
안티패턴 — TestRail이 무너지는 전형적 경로
1) 케이스 폭발. "모든 것을 케이스로"라는 생각으로 만들다 보면 3,000개가 된다. 그리고 아무도 전부 실행하지 못한다. 모듈 11(레슨 4)의 자동화 부채와 같은 문제다. 실행되지 않는 케이스는 자산이 아니라 부채다.
2) 화면 구조를 그대로 베낀 섹션. 앞에서 다룬 그대로. 화면이 바뀌면 트리를 다시 짜야 한다.
3) 하나의 런을 계속 재사용. "이번에도 그 런에 다시 기록하죠"를 반복하면 이력이 사라진다. TestRail을 쓰는 이유 자체가 없어지는 실수다. 회차마다 새 런을 만든다.
4) Blocked를 Failed로 기록. 지표가 오염된다. 환경 문제와 제품 결함은 분리해야 한다.
5) Untested를 방치한 채 종료. 실행하지 않은 케이스가 절반인데 "통과율 100%"라고 보고하는 상황. 분모를 밝히지 않은 통과율은 거짓말에 가깝다. 종료 시 Untested 건수를 반드시 함께 보고한다.
6) 자동화 결과를 올리지 않음. 수동 결과만 TestRail에, 자동화 결과는 CI 로그에 있으면 릴리즈 판단을 두 화면에서 해야 한다. trcli로 합친다.
실무에서 왜 필요한가
TestRail은 국내외 QA 채용공고에서 가장 자주 언급되는 테스트 관리 도구다. "TestRail 사용 경험"이 요건에 적힌 공고를 만나면, 실제로 요구되는 것은 버튼 조작이 아니라 케이스 저장소와 실행 이력을 분리해 운영해본 감각 이다. 스위트를 어떻게 나눴고, 회차를 어떻게 관리했고, 자동화 결과를 어떻게 합쳤는지를 말할 수 있으면 그 경험은 다른 도구로도 그대로 옮겨간다.
조직 안에서의 실익도 크다. 릴리즈 판단 회의에서 "이번 회귀는 통과율 94%, 미실행 12건, 실패 8건 중 5건이 결제 영역이고 그중 2건은 Blocked 상태입니다"라고 말할 수 있는 근거가 화면에 있는 것과, 스프레드시트를 급히 정리해 가는 것은 다르다. 그리고 그 화면은 다음 회차에도 그대로 쓰인다.
무엇보다 요구사항 → 케이스 → 실행 → 결함 의 사슬이 데이터로 남는 것이 크다. 모듈 25에서 본 인증·감사 대응에서 요구되는 것이 정확히 이 사슬이고, 규제 도메인이 아니어도 "이 기능은 검증됐나"라는 질문에 즉답할 수 있다는 것은 QA의 기본 역량이다.