Files
llm-wiki/raw/interviews/archunit-manual-importer-vs-analyzeclasses.md
T

44 lines
3.9 KiB
Markdown

---
title: interview-prep / archunit-manual-importer-vs-analyzeclasses
source_type: interview-prep
status: raw
related_branches: [feature-test-taxonomy-fixture-contract, feature-architecture-enforcement-rules]
related_projects: [ca-skeleton]
tags: [interview-prep, ca-skeleton, archunit, test-taxonomy, do-not-include-tests, manual-importer]
created: 2026-06-19
status_label: collecting
---
# interview-prep: archunit-manual-importer-vs-analyzeclasses
> Layer: `raw/interviews/` — 면접 질문 원본 수집·연구 노트. 다듬어진 답변은 `/interviewize` 후 `wiki/interview/` 에 별도 작성.
## Parent / 부모
- [[raw/branch-notes/feature-test-taxonomy-fixture-contract]] — Task 2 에서 "contract·architecture 레벨 test 는 Testcontainers 의존 금지" rule 을 구현할 때 부딪힌 핵심 결정.
## 질문 / Question
- 질문 원문: ArchUnit 에서 `@AnalyzeClasses(importOptions = DoNotIncludeTests.class)``new ClassFileImporter().importPackages(...)` 를 각각 언제 쓰나요? 규칙의 _대상_ 이 test 코드 자체일 때 왜 `@AnalyzeClasses` 만으로는 안 되나요?
- 출처: 예상 질문 (실 면접 아님).
- 받은 날짜·맥락: 아직 없음 — 2026-06-19 test-taxonomy-fixture-contract 구현에서 도출.
## 질문 의도 추론 / Why this question
- 핵심 평가 대상:
- ArchUnit 의 import scope 가 _규칙이 무엇을 볼 수 있는가_ 를 결정한다는 것을 이해하는지. 규칙 본문(`noClasses().should()...`)만 보고 "왜 안 잡히지?" 를 import 설정에서 진단할 수 있는지.
- production 규칙과 test-에-대한 규칙을 한 suite 에 섞었을 때 생기는 vacuous-pass 위험을 인지하는지.
## 답변 골자 / Answer skeleton (raw)
- ca-tmpl 의 production 아키텍처 suite(`CleanArchitectureTest`, `DisabledAdapterArchitectureTest`, `NamingConventionTest`)는 전부 `@AnalyzeClasses(packages = "dev.caskeleton", importOptions = ImportOption.DoNotIncludeTests.class)` — production bytecode 만 본다. 그래야 "domain 은 Spring 의존 금지" 같은 규칙이 test util 의 Spring import 때문에 오탐하지 않는다.
- 그런데 test-taxonomy 계약(§테스트 계약 #4: "contract·architecture _테스트_ 가 Testcontainers 에 의존하면 실패")은 _대상이 test 클래스_ 다. `DoNotIncludeTests` 가 그 클래스를 import 단계에서 제거하므로 `@AnalyzeClasses` 규칙은 영원히 빈 subject 를 받아 vacuously pass 한다.
- 해법: 규칙을 `static final ArchRule` 필드로 정의하고, 별도 `@Test` 에서 `new ClassFileImporter().importPackages("dev.caskeleton.bootstrap.contract")` 로 test bytecode 를 명시적으로 로드해 `rule.evaluate(corpus)` 를 직접 호출한다. `ArchitectureViolationFixtureTest` 가 violation fixture 를 같은 방식으로 로드하는 패턴과 동일하다.
- `importPackages``.class` 바이트를 직접 읽어 JVM class loading 을 하지 않으므로 `testCompileOnly` 타입(Testcontainers 등)이 runtime 에 resolve 되지 않아도 안전하다.
- vacuity 방어: 규칙을 정의했으면 _반드시_ positive control 을 둔다 — 본 작업에서는 Testcontainers 를 실제로 쓰는 `bootstrap.integration` 패키지에 같은 규칙을 평가해 `hasViolation() == true` 를 단언했다. (관련: [[raw/interviews/archunit-static-analysis-limits]], [[raw/blog-topics/archunit-violations-as-data-pattern-2026-05-28]])
## 더 팔 거리 / Follow-ups
- `allowEmptyShould(true)` 를 언제 쓰고 왜 위험한가 (빈 subject 를 의도적으로 허용 → positive control 없으면 vacuous). 관련 errors: [[raw/errors/archunit-empty-should-anchor-2026-05-27]].
- production 규칙(`production_code_does_not_depend_on_test_fixtures`)은 `DoNotIncludeTests` 위에서 동작하는데 어떻게 meta-verify 했나 → fixtureleak violation 패키지를 manual importer 로 로드해 같은 rule 객체를 평가.