Files
llm-wiki/raw/blog-topics/archunit-testcompileonly-fixture-annotation-pattern-2026-06-02.md

98 lines
4.2 KiB
Markdown

---
title: testCompileOnly 타입을 ArchUnit fixture 에서 안전하게 참조하기 — annotation-only 패턴
source_type: blog-topic
status: raw
related_branches: [feature-streaming-response-contract]
related_projects: [ca-tmpl]
tags: [blog-topic, ca-tmpl, archunit, gradle, testcompileonly, fixture]
created: 2026-06-02
status_label: ready-for-canonical
target_audience: backend-engineer
inspiration_url:
archive_url:
---
# testCompileOnly 타입을 ArchUnit fixture 에서 안전하게 참조하기
## Parent
- [[raw/branch-notes/feature-streaming-response-contract]]
## 글감 요약
ArchUnit violations-as-data 패턴에서 금지 타입을 `testCompileOnly` 로만 선언할 때 발생하는 `NoClassDefFoundError` 와, **annotation-only 참조** 로 해결하는 패턴.
### 핵심 발견
- `testCompileOnly` jar 는 compile-time 에만 존재 → JUnit 이 class 로드 시 superclass resolve 불가 → `NoClassDefFoundError`.
- ArchUnit 의 `ClassFileImporter` 는 바이트코드 직접 파싱 → class loading 불필요. 문제는 JUnit 스캐닝.
- **annotation 참조** 는 JVM 이 class load 시 즉시 resolve 하지 않으므로 안전.
- `@EnableWebSocket` (spring-websocket) 을 annotation 으로만 달면: (1) ArchUnit 이 `org.springframework.web.socket..` 의존 탐지 성공, (2) runtime classpath 에 jar 없어도 class 로드 성공.
### 독자
Spring Boot + Gradle 멀티모듈 + ArchUnit 조합에서 architecture enforcement 를 구현하는 백엔드 개발자.
### 구성 아이디어
1. 문제: violations-as-data fixture 와 `testCompileOnly` 충돌
2. 원인 분석: JVM class loading vs ArchUnit bytecode parsing
3. 해결: annotation-only 참조 패턴
4. 추가 발견: `jakarta.websocket-api` server-only jar 이슈
5. 패턴 정리표 (annotation / method return type / extends 별 `testCompileOnly` 안전성)
## 트리거 / Trigger
- 트리거 유형: `branch-work`
- 트리거 날짜: 2026-06-02
- 트리거 연결 노트: [[raw/branch-notes/feature-streaming-response-contract]]
## 글감 / Topic seed
- 한 문장 요지: `testCompileOnly` 금지 타입을 ArchUnit fixture에서 검출하려면 class loading을 유발하지 않는 annotation-only 참조가 안전하다.
- 예상 제목 후보:
- ArchUnit fixture에서 testCompileOnly 타입을 안전하게 참조하기
- JVM class loading과 ArchUnit bytecode parsing의 차이
## 핵심 주장 후보 / Claim candidates
- 사실 후보:
- `testCompileOnly` jar는 JUnit class loading 시점에는 없을 수 있다.
- ArchUnit importer는 bytecode를 직접 읽으므로 annotation 참조만으로 dependency detection이 가능하다.
- 의견/해석 후보:
- violations-as-data fixture는 runtime classpath 안정성까지 고려해야 한다.
## Outline seed
1. `testCompileOnly` fixture가 `NoClassDefFoundError`를 만드는 경로를 설명한다.
2. annotation-only 참조가 왜 class loading을 덜 유발하는지 정리한다.
3. streaming/WebSocket ban rule fixture에 적용할 때의 한계를 적는다.
## Canonical 전환 후보 / Canonical extraction candidates
- `wiki/projects/ca-tmpl/streaming-response-support.md` 후보:
- streaming/WebSocket ban ArchUnit fixture 안정화 글감.
- `wiki/projects/ca-tmpl/skeleton-governance-registry-verification-test-scorecard.md` 후보:
- ArchUnit fixture/testing pattern 글감.
- 필요한 추가 검증:
- 현재 fixture가 annotation-only 패턴으로 유지되는지.
## Sources / 근거 후보
- [[raw/branch-notes/feature-streaming-response-contract]]
## 미해결 / Unknown
- 아직 확인해야 할 사실: 현재 test runtime classpath와 fixture 참조 방식.
- 과장하면 안 되는 부분: annotation-only가 모든 `testCompileOnly` 참조를 안전하게 만든다고 일반화하지 않는다.
## Decision / 처리 결정
- 액션: `promote-to-canonical`
- 이유: `wiki/projects/ca-tmpl/streaming-response-support.md``wiki/projects/ca-tmpl/skeleton-governance-registry-verification-test-scorecard.md` 에 ArchUnit fixture 안정화 글감으로 반영한다.
- 다음 단계: streaming canonical은 verified지만, fixture classpath 세부는 blogify 전 재확인한다.
## Related / 관련
- 관련 branch: [[raw/branch-notes/feature-streaming-response-contract]]