**Property-Based Testing(PBT)**은 입력과 결과 간의 **일반적인 속성(Property)**을 정의하고, 테스트 프레임워크가 그 속성을 충족하는지를 무작위로 생성된 다양한 입력값에 대해 확인하는 방식의 테스트입니다. 단위 테스트처럼 특정 입력값만 확인하는 것이 아니라, 수천 개의 입력 조합을 자동으로 검사할 수 있다는 점에서 매우 강력합니다.
🔍 Property-Based Testing이란?
✅ 핵심 개념
- 속성(Property): 테스트 대상 함수나 로직이 항상 만족해야 하는 일반적인 법칙 또는 규칙.
- 입력값 자동 생성: PBT 프레임워크가 다양한 입력값을 무작위로 생성.
- Fail case 축소(Shrinking): 실패한 입력값이 발생했을 때, 실패를 재현할 수 있는 최소 입력값으로 줄여서 디버깅을 쉽게 함.
🆚 단위 테스트와의 비교
| 항목 | 단위 테스트 (Example-based) | 속성 기반 테스트 (Property-based) |
|---|---|---|
| 입력값 | 고정된 사례 수동 지정 | 자동 생성된 다양한 값 |
| 테스트 범위 | 제한적 | 매우 광범위 |
| 유지보수 | 로직 변경 시 테스트 추가 필요 | Property만 잘 정의하면 자동 적용 |
| 실패 시 디버깅 | 명확한 입력값 | 축소 과정 필요 |
🧪 Spring Boot에서 Property-Based Test 사용하는 방법
Spring Boot 자체는 JUnit을 기반으로 한 단위 테스트가 기본이며, PBT는 외부 라이브러리를 사용해서 통합하는 것이 일반적입니다. 가장 널리 쓰이는 Java 기반 라이브러리는 다음과 같습니다:
1. jqwik 사용
jqwik은 Java와 JUnit 5를 기반으로 한 property-based 테스트 프레임워크입니다.
🔧 Maven 의존성 추가:
<dependency>
<groupId>net.jqwik</groupId>
<artifactId>jqwik</artifactId>
<version>1.8.0</version>
<scope>test</scope>
</dependency>
✍️ 예시 코드:
import net.jqwik.api.*;
class StringProperties {
@Property
boolean reverseOfReverseIsOriginal(@ForAll String input) {
return new StringBuilder(new StringBuilder(input).reverse().toString()).reverse().toString().equals(input);
}
@Property
boolean lengthIsNonNegative(@ForAll String input) {
return input.length() >= 0;
}
}
➕ Spring과 함께 사용하기:
Spring Boot 테스트와 @SpringBootTest를 섞을 수도 있지만, 일반적으로 Pure Function, 즉 순수 함수 테스트에 주로 사용되므로, Spring Context를 불러오지 않고 테스트하는 것이 일반적입니다.
2. QuickTheories 또는 JUnit-Quickcheck도 있음
하지만 jqwik은 JUnit5와의 통합성이 좋아 요즘 가장 많이 사용됩니다.
💡 언제 Property-Based Testing을 도입하면 좋을까?
- 복잡한 입력 조합이 가능한 알고리즘 (ex. 정렬, 수학 연산, 시리얼라이저 등)
- 다양한 경계 조건을 확인하고 싶은 경우
- 입력의 범위가 넓고, 오류가 특정한 조건에서만 발생하는 경우
- 예시 기반 테스트로 커버되지 않는 잠재적 버그를 잡고 싶을 때
📌 정리
- Property-Based Testing은 다양한 자동 생성된 입력값에 대해 “항상 성립해야 하는 속성”을 검증하는 테스트 방식입니다.
- Spring Boot에서는 주로 jqwik과 같은 외부 라이브러리를 통해 사용하며, JUnit5와 잘 통합됩니다.
- 시스템의 복잡한 로직이나 입력 조합에 대한 강건성을 확보하고 싶을 때 매우 유용합니다.