본문으로 건너뛰기
cccskills
무료GitHub에 공개

golden-test-management

Golden-fixture contract discipline: locations, bless workflow, env vars, volatile-field scrubbing, failure-artifact triage. Use when a golden/snapshot test fails or a new golden fixture is added.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

설치 방법 보기

포함된 파일(1)

  • SKILL.md7.5 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

Golden Test Management

Golden contracts enforce compatibility for telemetry, diagnostics events, strategy-probe progress/report payloads, and exported data. Fixtures are read-only by default -- tests fail on unexpected diffs. Bless with RIPDPI_BLESS_GOLDENS=1 to update.

Full documentation: docs/testing.md (Golden contracts section).

Fixture Locations

LayerLocationExamples
Rustnative/rust/crates/{crate}/tests/golden/android-support, ripdpi-android, ripdpi-tunnel-android, ripdpi-monitor-engine
JVMcore/{module}/src/test/resources/golden/engine, service, diagnostics
Android instrumentationapp/src/androidTest/assets/golden/Copies of JVM fixtures for on-device smoke tests

Environment Variables

VariablePurposeDefault
RIPDPI_BLESS_GOLDENSSet to any value to write fixtures instead of comparingNot set (read-only)
RIPDPI_GOLDEN_ARTIFACT_DIROverride diff artifact output directorytarget/golden-diffs (Rust), build/golden-diffs/ (JVM)

Blessing Workflow

Bless All Telemetry/Logging Goldens

bash scripts/tests/bless-telemetry-goldens.sh

This script:

  1. Blesses Rust goldens (android-support, ripdpi-android, ripdpi-tunnel-android, ripdpi-monitor-engine)
  2. Blesses JVM goldens (NativeTelemetryGoldenTest, ServiceTelemetryGoldenTest)
  3. Syncs instrumentation fixtures (copies JVM fixtures to app/src/androidTest/assets/golden/)

Bless Specific Crate/Module

# Rust
RIPDPI_BLESS_GOLDENS=1 cargo test --locked -p ripdpi-android --manifest-path native/rust/Cargo.toml

# Kotlin
RIPDPI_BLESS_GOLDENS=1 ./gradlew :core:engine:testDebugUnitTest --tests "*.NativeTelemetryGoldenTest"

After Blessing

  1. Review diffs: git diff -- verify changes are intentional
  2. Commit with explanation of why the golden changed
  3. If instrumentation fixtures were affected, verify the sync step ran

Failure Artifacts

On mismatch, both Rust and JVM support libraries write three files:

FileContent
{name}.expectedThe golden fixture content
{name}.actualWhat the test produced
{name}.diffUnified diff between expected and actual

Rust: Written to target/golden-diffs/ (or RIPDPI_GOLDEN_ARTIFACT_DIR). JVM: Written to {module}/build/golden-diffs/.

Support Libraries

Rust: golden-test-support Crate

use golden_test_support::{assert_text_golden, canonicalize_json, canonicalize_json_with};

// Simple text comparison
assert_text_golden(env!("CARGO_MANIFEST_DIR"), "tests/golden/output.json", &actual);

// JSON with key sorting
let canonical = canonicalize_json(&json_string)?;
assert_text_golden(env!("CARGO_MANIFEST_DIR"), "tests/golden/data.json", &canonical);

// JSON with custom scrubbing
let canonical = canonicalize_json_with(&json_string, |value| {
    // Remove volatile fields like timestamps
    scrub_timestamps(value);
})?;
assert_text_golden(env!("CARGO_MANIFEST_DIR"), "tests/golden/data.json", &canonical);

Kotlin: GoldenContractSupport Object

Located in core/engine/src/test/kotlin/com/poyka/ripdpi/core/GoldenContractSupport.kt:

// JSON comparison with canonical key ordering
GoldenContractSupport.assertJsonGolden(
    "snapshot.json",
    json.encodeToString(serializer, data),
)

// JSON with custom scrubbing
GoldenContractSupport.assertJsonGolden(
    "snapshot.json",
    json.encodeToString(serializer, data),
    ::scrubVolatileFields,  // (JsonElement) -> JsonElement
)

// Plain text comparison
GoldenContractSupport.assertTextGolden("output.txt", actualText)

Scrubbing Volatile Fields

Fields that change between runs must be scrubbed for deterministic comparison:

Scrubbed (non-deterministic):

  • Timestamps (serviceStartedAt, lastFailureAt, updatedAt, capturedAt, createdAt)
  • Generated session IDs
  • Loopback ports
  • Absolute temp paths
  • Archive-time dynamic file names

Strict (must match exactly):

  • State and health values
  • Counters
  • Event order
  • Log level and message text
  • Route group and target metadata
  • Strategy signatures and recommendations
  • Per-lane TCP/QUIC/DNS metadata
  • Strategy-probe progress lane/candidate metadata
  • Audit assessment and target-selection metadata
  • Resolver metadata and fallback state

Kotlin Scrubbing Pattern

private fun scrubVolatileFields(value: JsonElement): JsonElement =
    when (value) {
        is JsonObject -> JsonObject(
            value.mapValues { (key, element) ->
                when (key) {
                    "serviceStartedAt", "lastFailureAt", "updatedAt",
                    "capturedAt", "createdAt" -> Json.parseToJsonElement("0")
                    else -> scrubVolatileFields(element)
                }
            },
        )
        else -> value
    }

Adding a New Golden Test

Rust

  1. Add golden-test-support to [dev-dependencies] in the crate's Cargo.toml:

    [dev-dependencies]
    golden-test-support = { path = "../golden-test-support" }
    
  2. Write the test:

    #[test]
    fn my_output_matches_golden() {
        let actual = produce_output();
        let canonical = canonicalize_json(&serde_json::to_string(&actual).unwrap()).unwrap();
        assert_text_golden(env!("CARGO_MANIFEST_DIR"), "tests/golden/my_output.json", &canonical);
    }
    
  3. Create initial fixture: RIPDPI_BLESS_GOLDENS=1 cargo test --locked -p my-crate my_output_matches_golden

  4. Review and commit the new fixture file.

Kotlin

  1. Write the test using GoldenContractSupport:

    @Test
    fun myOutputMatchesGolden() {
        val actual = produceOutput()
        GoldenContractSupport.assertJsonGolden("my_output.json", jsonEncode(actual))
    }
    
  2. Create initial fixture: RIPDPI_BLESS_GOLDENS=1 ./gradlew :module:testDebugUnitTest --tests "*.MyGoldenTest"

  3. Review and commit the new fixture file.

Instrumentation Sync

If the new golden is needed for Android instrumentation tests:

  1. Add a cp line to scripts/tests/bless-telemetry-goldens.sh
  2. Copy the JVM fixture to app/src/androidTest/assets/golden/

Common Mistakes

MistakeFix
Blessing without reviewing diffsAlways git diff after blessing. Unexpected changes may indicate bugs.
Forgetting to scrub volatile fieldsNew timestamp/ID fields cause non-deterministic failures. Add to scrub function.
Not explaining golden changes in commitGolden updates should always explain why the expected output changed.
Missing instrumentation syncJVM fixture updated but app/src/androidTest/assets/golden/ not. Run bless script or add cp manually.
Adding golden without canonicalize_jsonJSON key order is non-deterministic. Always canonicalize before comparing.
Hardcoding fixture pathRust: use env!("CARGO_MANIFEST_DIR"). Kotlin: GoldenContractSupport resolves repo root automatically.

See Also

  • docs/testing.md -- Full test stack documentation including golden contracts section
  • native/rust/crates/golden-test-support/src/lib.rs -- Rust support library source
  • core/engine/src/test/kotlin/.../GoldenContractSupport.kt -- Kotlin support library source
  • scripts/tests/bless-telemetry-goldens.sh -- Blessing script

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

RIPDPI's own Compose conventions: ViewModel pattern, Route/Screen split, DataStore->StateFlow, RipDpiThemeTokens. Use for how this app does Compose, not generic Compose API questions (see compose).

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

po4yka/RIPDPI812026년 10월 23일 업데이트

ADB-based RIPDPI device/emulator debugging: build/install/launch, logcat filtering, fixture port-forwarding, instrumented tests, crash/ANR triage. Use when debugging on a real device or emulator.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

po4yka/RIPDPI812026년 10월 23일 업데이트

RIPDPI Appium launch-contract reference: start routes and permission/service/data presets. Use when a test launches to the wrong screen or a new automation route is added. General flakiness: appium-test-debug.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

po4yka/RIPDPI812026년 10월 23일 업데이트

RIPDPI Appium test authoring: page objects, resource-id locators, assertions, wait tiers. Use when writing a new Appium test or page object, or adding coverage for a new screen.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

po4yka/RIPDPI812026년 10월 23일 업데이트

RIPDPI Appium failure triage: flaky tests, locator/session/wait issues, screenshot and element-tree debugging. Use when an Appium test fails or is flaky.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

po4yka/RIPDPI812026년 10월 23일 업데이트

Add or modify a GitHub Actions job. Use when editing a file under .github/workflows/. Not for running a workflow locally (local-ci-act) or release signing (release-signing).

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

po4yka/RIPDPI812026년 10월 23일 업데이트

po4yka의 스킬 모두 보기

이 스킬의 문제 신고