- 3-tier dependency direction diagram + architecture rule - Module table reorganized by tier (Generic / HmEG-aware / EgBim) - Milestones: first E2E, raw scenario E2E (#14), 3-tier split, 126 tests - Gap status (A~H done, Gap I deferred with Player fallback strategy) - Directory tree updated to reflect post-refactor layout Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
121 lines
7.4 KiB
Markdown
121 lines
7.4 KiB
Markdown
# recordingtest
|
|
|
|
사내 WPF 3D 편집 응용(자체 엔진 **HmEG**, MEF plugin 아키텍처)에 대한 **사용자 입력 회귀 테스트 자동화 도구**.
|
|
도구 자체이지 SUT가 아니다. 자세한 운영 지침은 [CLAUDE.md](CLAUDE.md), 현재 진행 상태는 [PROGRESS.md](PROGRESS.md), 다음 할 일은 [PLAN.md](PLAN.md)를 참고.
|
|
|
|
## 핵심 전략 — Golden-file 회귀
|
|
|
|
수동 테스트 입력을 레코딩 → 리플레이 → 결과 저장 파일을 정규화 후 baseline과 diff. ApprovalTests 패턴과 동형이며 SUT 코드 변경 협조를 최소화하기 위한 의도적 선택이다.
|
|
|
|
```
|
|
[수동 테스트] → 입력 레코드 + 결과 파일 A (approved baseline)
|
|
[회귀 시점] → 입력 리플레이 → 결과 파일 B → normalize → diff(A, B)
|
|
```
|
|
|
|
## 3계층 아키텍처
|
|
|
|
본 도구는 **EG-BIM Modeler 외 다양한 WPF 응용**을 대상으로 하고, 사용자 WPF 응용군 대다수가 자체 3D 엔진 **HmEG**를 공유한다. 따라서 코드는 엄격히 3계층으로 분리된다 (의존 방향 단방향, 자세한 규칙은 [CLAUDE.md §8.1](CLAUDE.md)):
|
|
|
|
```
|
|
App-specific (e.g. EgBim) ──→ HmEG-aware ──→ Generic
|
|
(특정 앱만) (HmEG 호스팅 앱 공통) (임의 WPF 앱)
|
|
```
|
|
|
|
`Recordingtest.Architecture.Tests` 가 `Assembly.GetReferencedAssemblies()` 검사로 빌드 시점에 규칙을 강제한다. 새 SUT를 추가할 때는 App-specific 계층에 플러그인 진입점 + 어댑터만 작성하고 Generic + HmEG-aware 전부 재사용.
|
|
|
|
## 모듈 구성
|
|
|
|
### Generic tier — 임의 WPF 응용
|
|
|
|
| 모듈 | 책임 | 상태 |
|
|
|------|------|------|
|
|
| [Recordingtest.Bridge.Abstractions](src/Recordingtest.Bridge.Abstractions/) | `IEngineStateProvider`/`CameraSnapshot`/`SceneSnapshot` 등 SUT-중립 인터페이스 | ✓ |
|
|
| [Recordingtest.SutProber](src/Recordingtest.SutProber/) | SUT 정적 probe (plugin/Json/assembly 카탈로그) | PoC pass |
|
|
| [Recordingtest.Recorder](src/Recordingtest.Recorder/) | 입력 캡처 (UIA element path + offset + 키/마우스/포커스) | PoC pass |
|
|
| [Recordingtest.Player](src/Recordingtest.Player/) | 시나리오 재생, 비동기 동기화, null-target fallback | PoC pass |
|
|
| [Recordingtest.Normalizer](src/Recordingtest.Normalizer/) | 결과 파일 정규화 (timestamp/GUID/path/float/order) | PoC pass |
|
|
| [Recordingtest.DiffReporter](src/Recordingtest.DiffReporter/) | approved vs received diff 리포트 | PoC pass |
|
|
| [Recordingtest.Runner](src/Recordingtest.Runner/) | 5-모듈 E2E 파이프라인 + 실패 triage | PoC pass |
|
|
|
|
### HmEG-aware tier — HmEG 호스팅 앱 공통
|
|
|
|
| 모듈 | 책임 | 상태 |
|
|
|------|------|------|
|
|
| [Recordingtest.Hmeg.Bridge](src/Hmeg/Recordingtest.Hmeg.Bridge/) | `HmegDirectStateProvider` — HmEG 공개 API(Space/HmEGViewport/ISelectable)로 상태 읽기. 앱에 람다로 진입점 주입 | v3 wired |
|
|
| [Recordingtest.Hmeg.Catalog](src/Hmeg/Recordingtest.Hmeg.Catalog/) | HmEG 정적 분석 카탈로그 | PoC pass |
|
|
| [Recordingtest.Hmeg.Bridge.Client](src/Hmeg/Recordingtest.Hmeg.Bridge.Client/) | `/scene` `/camera` `/selection` HTTP 클라이언트 | v2 pass |
|
|
|
|
### App-specific tier — 현재 SUT: EG-BIM Modeler
|
|
|
|
| 모듈 | 책임 | 상태 |
|
|
|------|------|------|
|
|
| [Recordingtest.Sut.EgBim.PluginHost](src/Sut/EgBim/Recordingtest.Sut.EgBim.PluginHost/) | MEF 진입점(`EditorPlugin` 상속), `BridgeHttpServer` 부팅, `HmegDirectStateProvider` 람다에 `RootSpace`/`View`/`AppManager.FileManager.CurrentFile` 주입 | v3 wired |
|
|
|
|
## 작업 사이클 — Planner / Generator / Evaluator
|
|
|
|
Anthropic harness design 원칙을 채택. 같은 에이전트가 생성과 평가를 겸하지 않는다.
|
|
|
|
1. `/contract <name>` — Sprint Contract 작성 (`docs/contracts/<name>.md`, 검증 가능한 DoD)
|
|
2. Generator — 계약 기준으로 구현
|
|
3. `/evaluate <name>` — 독립 evaluator가 채점, pass 시에만 PROGRESS.md 갱신
|
|
|
|
## 기술 스택
|
|
|
|
- **언어**: C# / .NET (SUT와 동일 생태계)
|
|
- **UI 자동화**: [FlaUI](https://github.com/FlaUI/FlaUI) 1순위, Win32 low-level hook hybrid
|
|
- **시나리오 포맷**: YAML/JSON (git diff 친화적)
|
|
- **베이스라인**: `*.approved.{ext}` / `*.received.{ext}`
|
|
|
|
## 주요 이정표
|
|
|
|
- **2026-04-08 — 첫 E2E 성공** 🎉 Smoke 2회차에서 수동 테스트 시나리오 → 재생 → SUT에 Box geometry 생성 확인 (box-v5-clean.yaml).
|
|
- **2026-04-08 — Raw 시나리오 E2E 성공** 🎉 수동 cleanup 없이 recorder 원본 `box-v6.yaml`이 그대로 재생되어 Box 생성 (이슈 #14). Player에 null-target fallback, SUT foreground 능동 대기, 선두 alt+tab 노이즈 자동 skip, 스텝 간 타이밍 보존 추가.
|
|
- **2026-04-09 — 3-tier 분리 완료** — Generic / HmEG-aware / App-specific 물리적 분리, `Recordingtest.Architecture.Tests`가 의존 그래프 강제. 같은 날 engine-bridge v3 EgBim 람다 실 wire-up (코드 쪽 완료, 라이브 검증 대기).
|
|
- **126 단위 테스트** green (Recorder/Player/Normalizer/DiffReporter/Runner/Hmeg.* /Sut.EgBim.* /Architecture)
|
|
|
|
자세한 과정은 [docs/history/](docs/history/), 결정 근거는 [docs/contracts/](docs/contracts/) + [docs/hmeg-api-survey.md](docs/hmeg-api-survey.md) 참고.
|
|
|
|
## Gap 현황 (주요)
|
|
|
|
- **Gap A~H** (smoke 1~2회차) — 전부 fix (#11/#12/#13/#14)
|
|
- **Gap I (recorder root-cause)** — EG-BIM Modeler의 CommandBox 등 핵심 입력 컨트롤이 AutomationPeer를 노출하지 않아 UIA 외부에서 본질적으로 식별 불가. **deferred**. 현재는 Player null-target fallback(Type→OS 포커스 / Click→raw_coord)이 공식 우회 전략. 근본 해소는 generic WPF DLL injection 또는 SUT-side AutomationPeer 부착 PoC가 선결.
|
|
|
|
## 디렉터리
|
|
|
|
```
|
|
recordingtest/
|
|
├── src/
|
|
│ ├── Recordingtest.Bridge.Abstractions/ # Generic — 인터페이스
|
|
│ ├── Recordingtest.Recorder/ # Generic
|
|
│ ├── Recordingtest.Player/ # Generic
|
|
│ ├── Recordingtest.Normalizer/ # Generic
|
|
│ ├── Recordingtest.DiffReporter/ # Generic
|
|
│ ├── Recordingtest.Runner/ # Generic
|
|
│ ├── Recordingtest.SutProber/ # Generic
|
|
│ ├── Hmeg/
|
|
│ │ ├── Recordingtest.Hmeg.Bridge/ # HmEG-aware
|
|
│ │ ├── Recordingtest.Hmeg.Catalog/ # HmEG-aware
|
|
│ │ ├── Recordingtest.Hmeg.Bridge.Client/ # HmEG-aware
|
|
│ │ └── Recordingtest.Hmeg.Catalog.Probe/ # HmEG-aware CLI
|
|
│ └── Sut/
|
|
│ └── EgBim/
|
|
│ └── Recordingtest.Sut.EgBim.PluginHost/ # App-specific
|
|
├── tests/ # 같은 계층 구조로 미러링 + Architecture.Tests
|
|
├── scenarios/ # 시나리오 YAML (box-v*.yaml)
|
|
├── docs/
|
|
│ ├── contracts/ # Sprint Contracts + evaluations
|
|
│ ├── history/ # 작업 히스토리
|
|
│ ├── sut-catalog/ # sut-prober 산출물
|
|
│ ├── engine-catalog/ # HmEG 후보 카탈로그 (정적 분석)
|
|
│ ├── hmeg-api-survey.md # HmEG public API 조사 메모
|
|
│ └── guides/ # smoke test, deploy 가이드
|
|
├── CLAUDE.md # 에이전트 운영 지침 + §8.1 3-tier 규칙
|
|
├── PROGRESS.md # 완료 상태 (세션 간 공유 메모리)
|
|
└── PLAN.md # 우선순위 큐
|
|
```
|
|
|
|
## 저장소
|
|
|
|
- Origin: https://gitea.hmac.kr/kimminsung/recordingtest
|
|
- 이슈/PR은 동일 Gitea, 커밋 메시지에 `#N` 참조
|