5.4 KiB
title, source_type, status, related_branches, related_projects, tags, created, status_label, target_audience, inspiration_url, archive_url
| title | source_type | status | related_branches | related_projects | tags | created | status_label | target_audience | inspiration_url | archive_url | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| blog-topic / test-taxonomy-archunit-enforcement-2026-06-19 | blog-topic | raw |
|
|
|
2026-06-19 | ready-for-canonical | backend-engineer |
blog-topic: test-taxonomy-archunit-enforcement-2026-06-19
Layer:
raw/blog-topics/— 채용공고가 아닌 작업·학습·트러블슈팅에서 나온 블로그 글감 원석. canonical 정제 전 raw 후보이며,wiki/blog/직접 생성 근거가 아니다.
Parent / 부모
- raw/branch-notes/feature-test-taxonomy-fixture-contract — 6-level test taxonomy 계약을 문서 에서 빌드가 강제하는 규칙 으로 옮긴 구현(2026-06-19).
트리거 / Trigger
- 트리거 유형:
branch-work - 트리거 날짜: 2026-06-19
- 트리거 연결 노트: raw/branch-notes/feature-test-taxonomy-fixture-contract — §테스트 계약 #4 와 D6/D7 drift 를 ArchUnit 규칙으로 닫은 작업.
글감 / Topic seed
테스트 분류(unit/contract/architecture/slice/integration/smoke)를 README 에 적어두는 것과, 잘못된 레벨에 놓인 테스트를 빌드가 거부 하게 만드는 것은 다르다. 후자를 ArchUnit 으로 구현한 사례.
핵심 3개 규칙:
-
레벨 경계 = 의존 경계로 강제: "contract·architecture 레벨 테스트는 Testcontainers 에 의존하면 실패." Testcontainers 를 쓰던
bootstrap/contract/테스트 5개는 사실 integration 테스트가 contract 디렉터리에 mis-file 된 것 →bootstrap/integration/으로 재분류한 뒤,..contract../..architecture..패키지가org.testcontainers..에 의존하면 fail 하는 규칙을 추가. 이렇게 하면 "5분 fast-feedback 게이트(unit+contract+architecture)" 가 컨테이너 기동 비용에 오염되는 것을 빌드가 막는다. -
Spring slice annotation 혼용 금지: Spring 공식이
@WebMvcTest+@DataJpaTest혼용을 "not supported" 로 명시(SB-SLICE-C2) → 한 클래스에 두 slice annotation 이 붙으면 fail. -
fixture 가 production classpath 로 새지 않게:
..fixtures..패키지에 대한 production 코드 의존을 차단.
왜 흥미로운가 / Why it's worth writing
- "테스트 분류는 컨벤션" 이라는 통념을 깨는 구체적 메커니즘.
@Tag보다 강하게, import graph 자체로 레벨을 강제한다. - ArchUnit 함정 2개를 실제로 다룬다:
@AnalyzeClasses(DoNotIncludeTests)는 test 클래스를 못 본다 → 규칙 대상이 test 자체일 땐 manualClassFileImporter가 필요. (raw/interviews/archunit-manual-importer-vs-analyzeclasses)allowEmptyShould(true)+ positive control: 규칙이 진짜로 발화하는지 증명하지 않으면 vacuous pass. 본 작업은 Testcontainers 를 실제로 쓰는 integration 패키지에 규칙을 평가해hasViolation()==true로 non-vacuity 를 못박았다. (raw/blog-topics/archunit-violations-as-data-pattern-2026-05-28)
곁가지 / Tangents
- DIR_LEVEL drift("integration test 가 contract 폴더에 있다")처럼, 디렉터리 이름과 테스트 레벨 이 어긋나면 fast-feedback 게이트 설계가 조용히 무너진다는 운영 교훈.
- 이 글감은 cross-branch raw/branch-notes/feature-ci-quality-gates-contract(5분 budget 게이트의 CI 구현 owner)와 묶어 "테스트 피라미드를 CI 가 강제하는 법" 으로 확장 가능.
핵심 주장 후보 / Claim candidates
- 사실 후보:
- test taxonomy는 package/import graph로도 강제할 수 있다.
- contract/architecture level에서 Testcontainers dependency를 금지하면 fast-feedback gate 오염을 줄일 수 있다.
- 의견/해석 후보:
- test level은 이름표가 아니라 실행 비용과 dependency boundary의 계약이다.
Outline seed
- README taxonomy와 build-enforced taxonomy의 차이를 설명한다.
- Testcontainers dependency, slice annotation, fixtures leak rule을 나눠 설명한다.
- manual
ClassFileImporter와 non-vacuity positive control의 필요성을 정리한다.
Canonical 전환 후보 / Canonical extraction candidates
wiki/projects/ca-tmpl/skeleton-governance-registry-verification-test-scorecard.md후보:- test taxonomy ArchUnit enforcement 글감.
- 필요한 추가 검증:
- 현재 test taxonomy rule과 relocated integration test evidence.
Sources / 근거 후보
- raw/branch-notes/feature-test-taxonomy-fixture-contract
- raw/interviews/archunit-manual-importer-vs-analyzeclasses
- raw/blog-topics/archunit-violations-as-data-pattern-2026-05-28
미해결 / Unknown
- 아직 확인해야 할 사실: CI 5min budget과 ArchUnit rule이 실제로 연결되어 release-blocking인지.
- 과장하면 안 되는 부분: 테스트 품질 전체를 보장한다고 쓰지 않고 level misplacement 방지로 제한한다.
Decision / 처리 결정
- 액션:
promote-to-canonical - 이유:
wiki/projects/ca-tmpl/skeleton-governance-registry-verification-test-scorecard.md에 test taxonomy ArchUnit enforcement 글감으로 반영한다. - 다음 단계: blogify 전 hosted CI와 local architecture test evidence를 분리한다.