모바일 개발에서의 Code Coverage: 개념, 메트릭 및 측정 방법

저자: IT Sectr 게시일: 2026-04-09 읽는 시간: 9 분

Code Coverage(코드 커버리지)는 테스트 중에 애플리케이션의 소스 코드 중 몇 퍼센트가 실행되는지 보여주는 메트릭입니다. 테스트 품질을 판단하고, 확인되지 않은 영역을 식별하며, 새 테스트 작성의 우선순위를 정하는 데 도움이 됩니다. Atlassian, 2025에 따르면, 최적의 커버리지 수준은 70~80%입니다. 이 임계값을 넘으면 테스트 비용이 이점을 초과하기 시작합니다.

핵심 요점

  • Code Coverage — 테스트에 의해 실행된 코드의 비율을 측정하는 메트릭
  • 커버리지 메트릭에는 라인(line), 브랜치(branch), 함수, 조건 및 경로가 포함됩니다
  • 도구: Android용 JaCoCo, iOS용 XCCov, 코드 분석용 SonarQube
  • 목표 커버리지 70~80% — 품질과 테스트 비용 간의 균형
  • CI/CD 통합을 통해 커버리지가 임계값 아래로 떨어지면 빌드를 차단할 수 있습니다

Code Coverage란

Code Coverage(코드 커버리지)는 테스트 중에 애플리케이션의 소스 코드 중 어느 부분이 실행되었는지 결정하는 정량적 메트릭입니다. 백분율로 표시되며 실행된 라인/브랜치의 총 대비 비율로 계산됩니다. 높은 커버리지가 버그가 없음을 보장하지는 않지만, 놓친 오류의 위험을 줄여줍니다.

커버리지를 측정하는 이유

코드 커버리지는 팀이 다음과 같은 일을 하는 데 도움이 됩니다: 코드의 테스트되지 않은 영역 찾기, 테스트 작성 우선순위 결정, CI/CD에서 테스트 품질 동향 추적. 모바일 개발에서 커버리지는 비즈니스 로직, 데이터 모델 및 리포지토리 — 오류 가능성이 가장 높은 계층 — 에 특히 중요합니다.

Code Coverage에 대한 오해

일반적인 오해: “100% 커버리지 = 완벽한 품질”. 실제로 100% 커버리지는 극히 드물며 종종 피상적인 테스트를 희생하여 달성됩니다. 효과적인 커버리지는 백분율 경쟁이 아니라 중요한 경로와 경계 조건에 대한 전략적 커버리지입니다. 커버리지는 테스트 자체의 품질에 대해 아무 것도 말해주지 않습니다: 테스트는 통과할 수 있지만 결과의 정확성을 검증하지 않을 수 있습니다.

코드 커버리지 메트릭

Code Coverage에는 각각 테스트의 다른 측면을 측정하는 여러 메트릭이 있습니다. Line coverage(라인 커버리지)는 가장 간단한 메트릭으로, 실행된 코드 라인의 백분율을 보여줍니다. Branch coverage(브랜치 커버리지)는 어떤 if-else 및 switch 분기가 테스트되었는지 측정합니다.

라인 커버리지 (Line Coverage)

Line coverage는 각 소스 코드 라인을 실행 여부로 계산합니다. 라인에 조건 연산자나 루프가 포함된 경우, 제어가 해당 라인에 도달했다면 모든 분기가 처리되지 않았더라도 실행된 것으로 간주됩니다. 이것은 가장 덜 엄격한 메트릭이지만 시각적 평가에 가장 이해하기 쉽습니다.

브랜치 커버리지 (Branch Coverage)

Branch coverage는 코드의 모든 가능한 분기가 테스트되었는지 평가합니다. 각 if-else에 대해 true와 false 두 분기 모두 고려됩니다. switch에 대해 각 case가 고려됩니다. Branch coverage는 line coverage보다 더 엄격한 메트릭으로 간주되며 테스트되지 않은 시나리오를 더 자주 발견합니다.

메트릭측정 내용달성 난이도
Line실행된 코드 라인의 백분율낮음
Branch실행된 분기의 백분율 (if/else, switch)중간
Function호출된 함수 및 메서드의 백분율낮음
Condition논리적 하위 표현식의 백분율 (&&, ||)높음

경로 커버리지 (Path Coverage)

Path coverage는 가장 엄격한 메트릭으로, 함수 내 모든 가능한 분기의 조합을 검증해야 합니다. 실제로 path coverage는 조합 수가 기하급수적으로 증가하기 때문에 거의 사용되지 않습니다. 분기가 10개인 함수는 1024개의 가능한 경로를 가집니다.

커버리지 측정 도구

모바일 개발에서는 플랫폼에 따라 Code Coverage를 측정하기 위해 다양한 도구가 사용됩니다. Android의 표준은 JaCoCo(Java Code Coverage)로, Gradle과 통합되며 단위 테스트와 계측 테스트를 모두 지원합니다. iOS의 경우 Xcode에 내장된 XCCov가 사용됩니다.

Android용 JaCoCo

JaCoCo는 HTML, XML 및 CSV 형식으로 보고서를 생성합니다. HTML 보고서는 라인을 시각적으로 강조 표시합니다: 녹색 — 실행됨, 빨간색 — 건너뜀, 노란색 — 부분적으로 실행됨. XML 보고서는 SonarQube 및 기타 코드 분석 시스템과 호환됩니다. JaCoCo는 클래스 필터링을 지원합니다: 생성된 코드, 데이터바인딩 및 BuildConfig를 제외할 수 있습니다.

groovy
// build.gradle — JaCoCo 설정
android {
    buildTypes {
        debug {
            testCoverageEnabled = true
        }
    }
}

// JaCoCo 보고서 생성
task jacocoTestReport(type: JacocoReport) {
    dependsOn 'testDebugUnitTest'
    reports {
        xml.enabled = true
        html.enabled = true
    }
}

iOS용 XCCov

XCCov는 코드 커버리지를 측정하기 위한 Xcode에 내장된 도구입니다. 테스트 스킴에서 Gather coverage data를 통해 활성화됩니다. XCCov는 Swift와 Objective-C에 대한 커버리지를 지원하며, .xccovreport 형식으로 보고서를 생성하고 xcodebuild -enableCodeCoverage YES를 통해 CI와 통합됩니다. 데이터는 콘솔에 출력되고 JSON으로 내보낼 수 있습니다.

SonarQube 및 Codecov

중앙 집중식 커버리지 모니터링을 위해 SonarQube(코드 품질 분석 + 커버리지), Codecov 및 Coveralls와 같은 플랫폼이 사용됩니다. 이러한 서비스는 JaCoCo와 XCCov의 데이터를 집계하고, 추세, 품질 게이트 및 PR 댓글을 통한 GitHub/GitLab 통합을 보여줍니다.

코드 커버리지 개선 방법

Code Coverage를 개선하려면 체계적인 접근 방식이 필요합니다: “백분율 올리기”가 아니라 위험을 커버하는 것입니다. 첫 번째 단계는 JaCoCo 또는 XCCov 보고서를 분석하여 빨간색(커버되지 않은) 클래스를 식별하는 것입니다. 우선순위: 비즈니스 로직 → 리포지토리 → ViewModel → UI 구성 요소.

TDD 전략

테스트 주도 개발(TDD)은 구현 전에 테스트를 작성하기 때문에 자동으로 높은 커버리지를 보장합니다. 프로세스: 빨강(실패하는 테스트 작성) → 초록(최소 코드 작성) → 리팩토링. TDD는 개발자를 훈련시켜 종종 테스트되지 않은 상태로 남는 경계 케이스와 예외 상황을 커버하도록 강제합니다.

매개변수화된 테스트

하나의 매개변수화된 테스트는 수십 개의 일반 테스트를 대체합니다. JUnit 및 XCTest는 매개변수화를 지원합니다: JUnit 5의 @ParameterizedTest, XCTest의 testPerformanceExample을 사용한 XCTestCase. 매개변수화를 사용하면 코드 중복 없이 여러 입력 데이터를 검증할 수 있어 브랜치 및 조건 커버리지가 크게 확장됩니다.

kotlin
// Kotlin에서 JUnit 5를 사용한 매개변수화된 테스트
@ParameterizedTest
@ValueSource(strings = ["user@test.com", "admin@test.com", "test@example.com"])
fun `validate email returns true for valid addresses`(email: String) {
    val result = EmailValidator.isValid(email)
    Assertions.assertTrue(result)
}

Code Coverage 작업 시 흔한 실수

가장 흔한 실수는 테스트 품질을 분석하지 않고 백분율을 쫓는 것입니다. 팀이 테스트를 위해 테스트를 작성하기 시작합니다: getter와 setter 확인, 다른 수준에서 커버리지 중복, 사소한 메서드 테스트. 이것은 높은 백분율을 제공하지만 실제 품질을 개선하지는 않습니다.

잘못된 안전감

높은 Code Coverage는 애플리케이션이 잘 테스트되었다는 잘못된 느낌을 줄 수 있습니다. 테스트는 코드 라인을 실행할 수 있지만 결과의 정확성을 검증하지 않을 수 있습니다. 예: 테스트가 할인 계산 메서드를 호출하지만 금액을 확인하지 않는 경우 — 라인이 실행되고 커버리지는 증가하지만 버그는 발견되지 않습니다.

경계 케이스 무시

일반적인 실수는 “해피 패스”(happy path)만 테스트하고 경계 케이스(빈 목록, null 값, 최대 숫자, 잘못된 형식)를 무시하는 것입니다. 대부분의 버그는 경계와 예외에서 발생합니다. Branch coverage는 누락된 분기를 식별하는 데 도움이 되지만 경계 값 검증을 보장하지는 않습니다.

돌연변이 테스팅 — 테스트 품질 검증

돌연변이 테스팅(Mutation Testing)은 소스 코드에 돌연변이(인공 오류)를 도입하고 테스트가 실패하는지 확인하는 테스트 품질 평가 방법입니다. Pitest는 Java 및 Kotlin을 위한 인기 있는 돌연변이 테스팅 도구입니다. 테스트가 돌연변이에서 실패하지 않으면 해당 조건을 검증하지 않고 있음을 의미합니다.

Pitest 작동 원리

Pitest는 돌연변이체를 생성합니다 — >가 >=로, true가 false로 대체되거나 메서드 호출이 제거된 소스 코드의 수정된 복사본입니다. 그런 다음 각 돌연변이체에 대해 테스트가 실행됩니다. 테스트가 통과하면 돌연변이체가 살아남은 것이며, 테스트가 해당 시나리오를 커버하지 않음을 의미합니다. 테스트가 실패하면 돌연변이체가 죽은 것이며 테스트가 유효합니다.

groovy
// build.gradle — Pitest 설정
plugins {
    id 'info.solidsoft.pitest' version '1.15.0'
}

pitest {
    targetClasses = ['com.example.app.*']
    targetTests = ['com.example.app.*Test']
    threads = 4
    outputFormats = ['HTML', 'XML']
    mutationThreshold = 80
    coverageThreshold = 85
}

돌연변이 유형

Pitest는 다양한 유형의 돌연변이를 지원합니다: 조건 연산자 변경(== → !=, < → <=), 메서드 호출 제거, 반환 값 대체(true → false), 산술 연산 변경(+ → -), 증가 연산 돌연변이(i++ → i--). 더 많은 유형의 돌연변이가 테스트에 의해 죽을수록 테스트 스위트는 더 신뢰할 수 있습니다.

돌연변이 점수 목표

목표 돌연변이 점수는 80% 이상입니다. 이는 인공 오류의 80%가 테스트에 의해 감지됨을 의미합니다. 90%의 코드 커버리지가 테스트가 버그를 찾는다는 것을 보장하지 않습니다 — 돌연변이 테스팅이 더 객관적인 평가를 제공합니다. Pitest는 CI에서 품질 게이트로 통합되어 돌연변이 점수가 임계값 아래로 떨어지면 빌드를 차단할 수 있습니다.

CI/CD에 Code Coverage 통합

CI/CD에서 Code Coverage를 자동으로 제어하기 위해 품질 게이트(Quality Gate)가 사용됩니다 — 위반 시 빌드를 불안정으로 표시하거나 거부하는 임계값입니다. SonarQube는 메트릭 조합(커버리지(≥80%), 버그 수, 취약점 및 중복 코드)을 기반으로 품질 게이트를 구성할 수 있습니다.

GitHub Actions에서 품질 게이트 설정

GitHub Actions에서 Code Coverage는 작업 단계를 통해 통합됩니다: 커버리지로 테스트 실행 → Codecov에 보고서 업로드 → 임계값 확인. Codecov는 자동으로 PR에 커버리지 차이를 댓글로 달아 어떤 라인이 변경되었고 전체 백분율에 어떻게 영향을 미쳤는지 보여줍니다. 커버리지가 떨어지면 추가 테스트가 작성될 때까지 PR이 차단됩니다.

yaml
# GitHub Actions — Codecov에 커버리지 업로드
- name: Run Tests with Coverage
  run: ./gradlew testDebugUnitTest jacocoTestReport

- name: Upload to Codecov
  uses: codecov/codecov-action@v4
  with:
    files: ./app/build/reports/jacoco/jacocoTestReport.xml
    flags: unittests
    fail_ci_if_error: true

- name: Check Coverage Threshold
  run: |
    coverage=$(grep -oP 'branchCoverage="\K[0-9.]+' report.xml)
    if (( $(echo "$coverage < 80" | bc -l) )); then
      echo "Coverage $coverage% is below 80% threshold"
      exit 1
    fi

보고 및 시각화

JaCoCo 및 XCCov의 HTML 보고서에는 커버리지 시각적 강조 표시가 포함됩니다: 녹색 — 실행된 라인, 빨간색 — 실행되지 않음. SonarQube는 추가로 파일, 클래스, 메서드 및 라인 수준에서 커버리지를 표시하며, 스프린트별 커버리지 변경 내역도 보여줍니다. 이는 리팩토링 및 테스트 추가에 대한 결정을 내리는 데 도움이 됩니다.

자주 묻는 질문

어느 정도의 Code Coverage 백분율이 좋은 것으로 간주되나요?

모바일 프로젝트의 경우 비즈니스 로직에 대해 70~80%, UI 구성 요소에 대해 50~60%의 커버리지가 좋은 것으로 간주됩니다. 80%를 넘으면 테스트 비용이 이점을 초과하기 시작합니다. 백분율은 목표가 아니라 지표이며, 다른 모듈은 다른 목표 수준을 가질 수 있음을 기억하는 것이 중요합니다.

Line Coverage와 Branch Coverage의 차이점은 무엇인가요?

Line Coverage는 실행된 코드 라인 수를 보여줍니다. Branch Coverage는 테스트된 분기(if-else, switch) 수를 보여줍니다. if가 있는 라인은 실행될 수 있지만 true 분기만 테스트되고 false는 테스트되지 않을 수 있습니다. Branch Coverage가 더 엄격하며 더 많은 누락된 시나리오를 발견합니다.

CI/CD에 Code Coverage를 통합하려면 어떻게 해야 하나요?

CI/CD에서 커버리지는 품질 게이트를 통해 통합됩니다: 커버리지가 임계값 아래로 떨어지면 빌드가 차단됩니다. Android의 경우 JaCoCo + SonarQube가 사용되고, iOS의 경우 xcodebuild -enableCodeCoverage와 .xccovreport 파싱이 사용됩니다. GitHub Actions에는 Codecov용 기성 액션이 있습니다.

Jetpack Compose에 대한 커버리지를 측정할 수 있나요?

네, JaCoCo는 표준 JVM 커버리지 메커니즘을 통해 Jetpack Compose를 지원합니다. 그러나 Compose 코드에는 JaCoCo가 완전히 커버하지 못할 수 있는 생성된 lambda 표현식이 많이 포함되어 있습니다. 필터를 통해 생성된 compose 코드를 보고서에서 제외하는 것이 좋습니다.

잘못된 커버리지를 피하려면 어떻게 해야 하나요?

잘못된 커버리지는 테스트가 코드를 실행하지만 결과를 검증하지 않을 때 발생합니다. 해결책: 중요한 시나리오마다 assertion 검사를 작성하고, 돌연변이 테스팅(Pitest)을 사용하여 테스트 품질을 검증하며, 백분율뿐만 아니라 어떤 분기가 커버되었는지도 분석합니다.

요약

  • Code Coverage — 테스트에 의해 실행된 코드의 비율을 보여주지만 버그가 없음을 보장하지 않는 메트릭
  • Line 및 Branch coverage — 주요 메트릭; Branch가 더 엄격하며 테스트되지 않은 분기를 발견
  • JaCoCo — Android용 표준 도구, XCCov — iOS용, 둘 다 Gradle 및 Xcode와 통합
  • 목표 커버리지 비즈니스 로직의 경우 70~80% — 품질과 비용의 최적 균형
  • TDD 및 매개변수화 — 테스트 중복 없이 커버리지를 높이는 효과적인 방법
  • SonarQube 및 Codecov — CI/CD에서 중앙 집중식 모니터링 및 품질 게이트를 위한 플랫폼
  • 핵심 규칙: 백분율을 쫓지 말고 중요한 위험과 경계 케이스를 커버하라

턴키 방식의 모바일 애플리케이션을 개발해 드립니다

IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.

프로젝트 논의

더 읽어보기