Testing
Weva has ~1900 NUnit tests, all written to run headlessly — the layers
above the render-backend boundary have no Unity dependency, so the suite runs
either in the Unity Test Runner (once the package is added to a project) or via
standalone dotnet tools that link the same source.
Suite layout
Tests live under Packages/com.weva/Tests/:
Tests/Runtime/— the bulk, organized by subsystem:Parsing/(HTML),Css/(Parsing, Selectors, Values, Cascade, Animation, Container),Layout/(Block, Inline, Flex, Grid, Positioning, Scrolling, Tables, Incremental),Paint/,Rendering/(Backend, URP, batcher, stencil),Text/(Atg, Sdf, TextCore, Tmp),Components/(+ Scoping),Binding/,Events/,Reactive/,Goldens/.Tests/Editor/— Preview rasterizer and source-generator tests.
Coverage convention (from MEMORY/PLAN): each new component gets extensive
NUnit coverage, not smoke tests. The incremental path of every stage is tested
to produce results identical to the from-scratch "naive" oracle.
Running headlessly with dotnet
Two standalone runners under Tools/ link the package source directly so you
don't need to open Unity:
Tools/TestVerifyAll/— reflects over the test assembly and runs the NUnit cases across the Layout / Css / Paint / Components / Binding / Events / Reactive / Goldens / Parsing namespaces. Run withdotnet run -c Releasefrom that directory; pass a substring to filter to matching fixtures. It also has--debug-snap/--debug-sticky/--debug-anchorentry points for targeted layout dumps.Tools/BaselineGen/— golden-image orchestration and headless checks. Subcommands:selfcheck(rasterizer primitive smoke tests),verify(assert goldens),layoutalloc(allocation regression),inline-split-check,layout-build-bench,reactive-paint-check,layout-dump. The default run regenerates baselines (also gated byUNITYUI_REGENERATE_GOLDENS=1).
Golden-image tests
Tests/Runtime/Goldens/ runs Parser → Cascade → Layout (with deterministic
mono font metrics) → Converter → a headless SoftwareRasterizer
(IRenderBackend) and compares the PNG output against committed baselines. A
hand-rolled PNG writer/reader keeps it dependency-free. GoldenRunner
orchestrates; set UNITYUI_REGENERATE_GOLDENS=1 to refresh baselines after an
intentional visual change.
Layout-vs-Chrome audit
Layout fidelity is checked against headless Chrome (Puppeteer) rather than hand-authored expectations:
Tools/Layout/extract-chrome-layout.mjs <html> [w] [h]loads a sample in headless Chrome, walks the body in DOM order, and emits onegetBoundingClientRectrecord per element to<html>.chrome-layout.json, keyed by document-order index so it aligns 1:1 with Weva'sBoxtree walk. Full doc or fragment input both work (fragments are wrapped, pulling in the sibling.css).Tools/Layout/capture-all-chrome-layouts.mjsbatch-captures every sample.- The audit aligns DOM order and buckets each block-level rect deviation as ok (≤2px), minor (≤6px), or MAJOR (>6px). Results live in SAMPLE_AUDIT.md.
Caveat: Weva's font metrics differ from Chrome's by design (Segoe UI default, not Arial — see Text & Fonts), so a few px of line-height difference cascades into uniform y-shifts. Those
font-driftrows are accepted divergence; only structural deltas are treated as bugs.
Perf benches
Tests/Runtime/Bench/ holds the standardized benches (CascadeBench,
LayoutBench, PaintBench, EndToEndBench), all [Test, Explicit("perf")]
so they're off the default pass. Tools/PerfBench/ is the standalone runner:
dotnet run -c Release -- all emits a markdown table; --baseline <path.json>
compares against a prior run. Fixtures scale from 100 cards to 5000 elements.
Profiling
Runtime/Profiling/UIProfilerMarkers.cs declares ProfilerMarkers for every
pipeline phase (Weva.Cascade.*, Weva.Layout.*, Weva.Paint.*, etc.). They
compile to no-ops outside UNITY_EDITOR || DEVELOPMENT_BUILD unless
UNITYUI_PROFILE is defined; in instrumented builds the breakdown shows up in
the Unity Profiler under Scripting.
Weva