프로세스 및 기법 관련
Code Coverage(코드 커버리지)는 소프트웨어 테스팅에서 “얼마나 많은 코드가 실제로 테스트되었는가?”를 측정하는 중요한 지표입니다.
소프트웨어 개발 과정에서 우리는 테스트를 통해 코드의 동작을 확인하고 결함을 예방하려고 합니다. 하지만 모든 코드가 제대로 테스트되고 있는지 어떻게 알 수 있을까요? 바로 코드 커버리지가 이를 알려줍니다.
코드 커버리지는 작성된 코드 중 테스트로 검증된 부분의 비율을 나타냅니다. 예를 들어, “코드 커버리지 80%“는 전체 코드의 80%가 테스트되었다는 의미입니다. 마치 책을 읽다가 책갈피를 꽂아놓고, “지금까지 80% 읽었어!“라고 말하는 것과 비슷합니다. 책 전체를 읽어야 내용을 완전히 이해할 수 있듯이, 소프트웨어도 모든 코드를 테스트하는 것이 이상적입니다.
1. 정의
Code Coverage는 작성된 코드 중 테스트가 실행된 코드의 비율을 측정하는 지표입니다.
• 테스트로 실행된 부분과 그렇지 않은 부분을 확인할 수 있습니다.
• 개발자나 QA 엔지니어는 이를 통해 테스트의 포괄성을 평가하고, 테스트가 미흡한 영역을 보완할 수 있습니다.
2. 왜 중요한가?
• 결함 예방: 테스트되지 않은 코드는 예상치 못한 결함의 원인이 될 가능성이 높습니다.
• 테스트 품질 평가: 코드 커버리지는 테스트가 코드의 주요 부분을 얼마나 잘 검증하고 있는지 보여줍니다.
코드 커버리지는 테스트의 범위를 측정하는 다양한 방법이 있습니다. 여기서 몇 가지 대표적인 유형을 소개합니다.
1. Statement Coverage (문장 커버리지)
• 코드에서 각 문장이 실행되었는지 확인합니다.
• 예: “if-else 문”에서 if와 else 각각의 블록이 실행되었는지 검사
2. Branch Coverage (분기 커버리지)
• 조건문에서 발생 가능한 모든 분기(Branch)가 테스트되었는지 확인합니다.
• 예: if (x > 0)에서 x > 0인 경우와 그렇지 않은 경우 모두 실행되었는지 평가
3. Function Coverage (함수 커버리지)
• 코드의 각 함수가 최소 한 번 이상 호출되었는지 확인합니다.
• 예: calculateTotal() 함수가 테스트에서 실행되었는지 확인
4. Path Coverage (경로 커버리지)
• 코드 내 모든 가능한 경로(Path)가 실행되었는지 확인합니다.
• 복잡한 로직에서는 경로 수가 많아 모든 경로를 테스트하기 어렵지만, 매우 높은 수준의 커버리지를 보장합니다.
예 1: 로그인 기능 테스트
아래는 간단한 로그인 코드입니다.
테스트 시나리오를 통해 코드 커버리지를 계산해봅시다.
1. 테스트 1: 올바른 username과 password 입력
• 실행 경로: if username == "admin" → if password == "1234" → return "Welcome!"
• 커버리지: 전체 코드의 일부만 테스트
2. 테스트 2: 올바른 username과 잘못된 password 입력
• 실행 경로: if username == "admin" → else → return "Incorrect password."
• 커버리지: 추가적인 코드 경로 테스트
3. 테스트 3: 잘못된 username 입력
• 실행 경로: else → return "User not found."
• 커버리지: 모든 분기와 문장 테스트, 100% 코드 커버리지 달성!
이처럼 다양한 테스트 케이스를 작성해 코드의 모든 부분이 실행되도록 해야 완벽한 커버리지를 달성할 수 있습니다.
1. 테스트 범위 시각화
• 코드 커버리지는 테스트가 실행된 영역과 실행되지 않은 영역을 시각적으로 보여줍니다.
• 이를 통해 누락된 테스트를 식별하고, 테스트를 보완할 수 있습니다.
2. 결함 예방
• 테스트되지 않은 코드는 결함이 숨어있을 가능성이 높습니다.
• 코드 커버리지를 통해 미검증 코드를 확인하고 테스트를 추가하면, 결함 예방에 큰 도움이 됩니다.
3. 테스트 품질 향상
• 코드 커버리지는 단순히 테스트를 많이 작성했는지 확인하는 것이 아니라, 테스트가 얼마나 효과적인지를 평가하는 데 유용합니다.
4. 개발자와 QA 간 협업 촉진
• 개발자와 QA는 코드 커버리지를 통해 테스트의 현황을 공유하고, 품질 목표를 함께 설정할 수 있습니다.
1. 100% 커버리지가 완벽한 테스트를 보장하지 않음
• 코드 커버리지가 높더라도, 모든 결함을 발견할 수 있는 것은 아닙니다.
• 예: 테스트는 모든 분기를 커버했지만, 데이터 유효성 검사 결함을 놓칠 수 있음.
2. 커버리지 달성에 치중할 위험
• 테스트의 질보다 양에 집중하다 보면, 테스트 케이스의 효과성이 떨어질 수 있습니다.
• 예: 코드 실행만을 목적으로 작성된 테스트는 결함을 놓칠 수 있음.
3. 복잡한 로직의 테스트 어려움
• Path Coverage와 같은 고급 커버리지를 달성하려면 테스트가 복잡해지고, 리소스가 많이 필요합니다.
1. 테스트 설계 역량 강화
• 주니어 QA는 코드 커버리지를 활용해 누락된 테스트 영역을 식별하고, 효율적인 테스트 케이스 작성법을 배울 수 있습니다.
2. 코드 분석 능력 향상
• 코드 커버리지를 이해하면서, QA는 코드의 흐름과 구조를 더 잘 파악할 수 있습니다.
3. 테스트 도구 활용 경험
• Code Coverage 도구(SonarQube, JaCoCo, Istanbul 등)를 사용하면서 실무에서 요구되는 자동화 역량을 강화할 수 있습니다.
Code Coverage는 소프트웨어 품질을 평가하고 개선하는 데 필수적인 도구입니다.
단순히 숫자에 집중하기보다, 코드 커버리지를 통해 테스트가 놓치고 있는 영역을 발견하고, 이를 보완하여 품질을 높이는 것이 중요합니다.
주니어 QA 엔지니어는 코드 커버리지를 학습하고 활용함으로써, 테스트 설계 능력과 코드 이해력을 함께 키울 수 있는 강력한 무기를 얻게 됩니다.