Post

Pitest

Pitest (PITest, PIT Mutation Testing) 는 자바 기반의 Mutation Testing 도구로, 코드의 테스트 커버리지뿐만 아니라 테스트의 효율성을 평가하는 데 사용됩니다. 일반적인 코드 커버리지는 테스트가 코드의 각 부분을 실행했는지 확인하지만, Pitest는 테스트가 코드의 동작을 올바르게 검증하는지도 평가합니다.

Mutation Testing이란?

Mutation Testing은 코드를 변형(뮤테이션)하여 테스트의 견고성을 측정하는 기법입니다. 변형된 코드(뮤턴트)가 올바르게 테스트에 의해 검출(실패)된다면, 테스트가 효과적으로 작성되었다고 판단할 수 있습니다.

Pitest의 작동 방식

  1. 기본 코드 분석: Pitest는 코드와 테스트를 분석하여 적용 가능한 뮤턴트 연산자를 선택합니다.
  2. 뮤턴트 생성: 코드에 다양한 변형(뮤턴트)을 적용합니다.
    • 조건문 반전 (> → < 또는 ==)
    • 산술 연산자 변경 (+ → -)
    • 리턴 값 수정 (리턴 값 변경)
    • 상수 변경 (1 → 0)
  3. 테스트 실행: 생성된 뮤턴트를 포함한 코드를 기존 테스트 케이스로 실행하여 테스트가 실패하는지 확인합니다.
  4. 결과 분석:
    • 죽은 뮤턴트 (Killed Mutant): 테스트가 실패하여 뮤턴트가 검출된 경우.
    • 살아남은 뮤턴트 (Survived Mutant): 테스트가 통과하여 검출되지 않은 경우.
    • 무의미한 뮤턴트 (Equivalent Mutant): 논리적으로 기존 코드와 동일한 변형(검출 불가능).

Pitest의 주요 기능

  1. 효율적인 테스트 평가:
    • 테스트 커버리지뿐만 아니라, 테스트가 얼마나 신뢰할 수 있는지를 평가.
  2. 자동화된 프로세스:
    • Maven, Gradle과 쉽게 통합 가능하여 CI/CD 파이프라인에 적용.
  3. 플러그인 지원:
    • JUnit, TestNG 등 다양한 테스트 프레임워크를 지원.
  4. 자세한 리포트:
    • 생존한 뮤턴트, 죽은 뮤턴트, 테스트 커버리지 등의 리포트 제공.

Pitest를 사용해야 하는 이유

1
2
3
4
5
6
1.	**테스트 품질 향상:**
* 	단순히 코드 라인을 실행하는 것이 아닌, 코드의 로직을 실제로 검증하는 테스트를 작성하도록 유도.
2.	**버그 검출 능력 강화:**
* 	테스트가 놓친 잠재적 결함을 찾아낼 수 있음.
3.	**CI/CD 파이프라인 강화:**
* 	테스트 신뢰성을 높여 프로덕션 품질 개선.

Java, Spring, Gradle 환경에서 Pitest 사용하기

Gradle에서 Pitest 설정

1. Pitest 플러그인 추가

Pitest Gradle 플러그인을 build.gradle 파일에 추가하세요.

Groovy DSL (build.gradle):

1
2
3
plugins {
    id 'info.solidsoft.pitest' version '1.9.11' // 최신 버전 확인
}

2. Pitest 설정 추가

Pitest를 build.gradle에 구성합니다.

Groovy DSL (build.gradle):

1
2
3
4
5
6
7
pitest {
    testPlugin = 'junit5' // JUnit 5 사용 시
    targetClasses = ['com.yourpackage.*'] // 테스트할 클래스 패키지 지정
    threads = 4 // 병렬 실행 쓰레드 수
    mutationThreshold = 80 // 뮤턴트 커버리지 목표 (퍼센트)
    verbose = true // 상세 로그 출력 활성화
}

3. 플러그인 의존성 추가

테스트 프레임워크에 맞는 플러그인을 추가하세요.

JUnit 5 예시:

1
2
3
dependencies {
    pitest 'org.pitest:pitest-junit5-plugin:1.1.2' // JUnit 5 플러그인
}

Pitest 실행

Gradle 명령어를 사용해 Pitest를 실행하세요:

1
./gradlew pitest

실행 결과

결과는 기본적으로 build/reports/pitest 디렉토리에 HTML 형식으로 생성됩니다. 브라우저에서 파일을 열어 결과를 확인하세요.


결과 리포트 이해하기

  • Mutation Coverage: 죽은 뮤턴트의 비율.
  • Survived Mutants: 테스트가 검출하지 못한 뮤턴트 (테스트 부족 가능성 표시).
  • Killed Mutants: 테스트가 검출한 뮤턴트.
  • No Coverage: 테스트로 실행되지 않은 코드.

Gradle 프로젝트에서 최적화

1. 테스트 성능 최적화

threads 값을 늘려 병렬로 테스트를 실행하세요:

1
threads = 8

2. 제외할 클래스나 메서드 지정

테스트가 필요 없는 코드를 제외하세요:

1
2
excludedClasses = ['com.yourpackage.util.*'] // 제외할 클래스 패턴
excludedMethods = ['toString', 'hashCode'] // 제외할 메서드

3. 목표 커버리지 설정

목표 커버리지 기준을 설정하여 기준 미달 시 빌드가 실패하도록 구성하세요:

1
mutationThreshold = 85 // 목표 뮤턴트 커버리지

Pitest의 장점

  1. 로직 테스트 강화: 생존 뮤턴트를 분석해 테스트의 빈틈을 찾아낼 수 있습니다.
  2. CI/CD 통합: CI 파이프라인에서 정기적으로 테스트를 실행해 품질을 유지합니다.
  3. 리팩토링 검증: 리팩토링 전후의 Pitest 결과를 비교하여 테스트 효율성을 유지합니다.

Pitest 결과 해석

1
2
3
* 	**Mutation Coverage:** 뮤턴트가 죽은 비율 (높을수록 좋음).
* 	**Survived Mutants:** 생존한 뮤턴트. 이 숫자가 높으면 테스트를 강화해야 함.
* 	**Killed Mutants:** 테스트가 잡아낸 뮤턴트.
This post is licensed under CC BY 4.0 by the author.