Skip to content
Back to skills

Experiment Sdk Testing

ASecurity

Umbrella for experimentation-SDK test harnesses: the shared offline-datafile / hermetic-init pattern (commit a point-in-time flag/experiment config fixture, initialize the SDK with no network, pin arms per test, assert assignment integrity), with per-vendor references for Statsig (localMode + overrideGate), Optimizely (datafile + forced decisions), Split.io / Harness FME (localhost mode + features map or YAML fixture), Amplitude Experiment (local evaluation + bootstrap), and VWO (settings fil...

  • 10 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added October 12, 2026
testingpythonrustrailstestingapi

Works with

  • cli
  • api

Security analysis

A100/100

Pro scans all 9 files and shows the line behind each finding

Scanned October 12, 2026

npx -y skills add testland/qa --skill experiment-sdk-testing --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Experiment Sdk Testing?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Experiment Sdk Testing
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/testland-experiment-sdk-testing/badge)](https://www.skillsdirectory.com/skills/testland-experiment-sdk-testing)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: experiment-sdk-testing
description: "Umbrella for experimentation-SDK test harnesses: the shared offline-datafile / hermetic-init pattern (commit a point-in-time flag/experiment config fixture, initialize the SDK with no network, pin arms per test, assert assignment integrity), with per-vendor references for Statsig (localMode + overrideGate), Optimizely (datafile + forced decisions), Split.io / Harness FME (localhost mode + features map or YAML fixture), Amplitude Experiment (local evaluation + bootstrap), and VWO (settings file + deterministic bucketing). Use when writing tests for application code instrumented with any of these five experimentation SDKs; for experiment DESIGN gates use ab-test-validity-checklist, and to read results use experiment-results-interpreter."
---

# experiment-sdk-testing

## Overview

Every major experimentation SDK ships the same hermetic-test mechanism
under a different name: a **point-in-time config fixture** (datafile,
settings file, flag payload, features map) that the SDK evaluates locally,
so tests make zero network calls, pollute no production analytics, and stay
deterministic. The vendor-specific mechanics differ only in how the fixture
is loaded and how an arm is pinned.

## Routing table

| SDK | Offline mechanism | Arm pinning | Reference |
|---|---|---|---|
| Statsig | `localMode: true` | `overrideGate` / `overrideConfig` | [references/statsig.md](references/statsig.md) |
| Optimizely | JSON datafile fixture | `set_forced_decision` | [references/optimizely.md](references/optimizely.md) (+ [optimizely-recipes.md](references/optimizely-recipes.md)) |
| Split.io / Harness FME | `authorizationKey: 'localhost'` + features map / YAML | Per-key fixture entry (no override API) | [references/split-io.md](references/split-io.md) (+ [split-io-example.md](references/split-io-example.md)) |
| Amplitude Experiment | LocalEvaluationClient + `bootstrap` | Fixture edit or `evaluateV2` mock | [references/amplitude.md](references/amplitude.md) |
| VWO | Settings file + `is_development_mode` | Deterministic bucketing on user ID | [references/vwo.md](references/vwo.md) |

## When to use

- Tests for code that reads a gate / experiment / variant from any of the
  five SDKs above.
- Assignment-integrity tests per `ab-test-validity-checklist` Step 3.
- CI pipelines that must run without vendor network access.

## The shared hermetic-init pattern

Regardless of vendor, the suite has the same five steps:

1. **Export and commit the config fixture** - the datafile / settings /
   flag payload the SDK would fetch, checked into `tests/fixtures/` and
   refreshed deliberately (drift between fixture and prod config is
   invisible otherwise).
2. **Initialize the SDK offline** - the vendor's no-network switch
   (`localMode`, datafile string, `'localhost'` key, `bootstrap`,
   `is_development_mode`).
3. **Pin the arm where the test needs one** - override API, forced
   decision, per-key fixture entry, or a deterministically-bucketed user
   ID.
4. **Assert on values and keys, never internal IDs** - variation keys and
   returned values survive environment changes; internal config IDs don't.
5. **Tear down** - shutdown / destroy the client so event-flush timers and
   handles don't leak across test files.

Plus two integrity tests every suite should carry:

- **Determinism** - the same user ID gets the same arm on repeated
  evaluation.
- **Distribution** - across many user IDs, more than one arm actually
  occurs (and, where the split is known, roughly matches it).

## Worked example (Optimizely datafile)

The team ships a `new_checkout_flow` flag with a `treatment_a` variation
and needs a deterministic test that a premium-plan user is routed into the
treatment:

```python
import json
from optimizely import optimizely

# Step 1-2: committed fixture, offline init - no SDK key, no network
with open("tests/fixtures/optimizely-datafile.json") as f:
    client = optimizely.Optimizely(f.read())

def test_premium_user_in_treatment():
    # Step 3: context carries the attributes targeting needs
    user = client.create_user_context("user-1", {"plan": "premium"})
    decision = user.decide("new_checkout_flow")
    # Step 4: assert on enabled + variation_key, not IDs
    assert decision.enabled is True
    assert decision.variation_key == "treatment_a"

def test_assignment_deterministic():
    user = client.create_user_context("user-1")
    d1 = user.decide("new_checkout_flow")
    d2 = user.decide("new_checkout_flow")
    assert d1.variation_key == d2.variation_key
```

The fixture drives the whole decision; the same shape translates to each
vendor via its reference above.

## Anti-patterns (all vendors)

| Anti-pattern | Why it fails | Fix |
|---|---|---|
| Live API key in tests | Production analytics polluted; rate limits; flakes | The vendor's offline switch |
| Fixture not version-controlled | Tests flake when prod config changes | Commit; refresh deliberately |
| Overrides / forced decisions leak across tests | Cross-test pollution | Per-test context + cleanup |
| Asserting on internal config / variation IDs | IDs change per environment | Assert keys and values |
| Skipping client shutdown / destroy | Event-flush timers and handles leak | Teardown in afterAll |
| Trusting one user ID to cover both arms | May bucket into one arm only | Distribution test across many IDs |

## Limitations

- **Fixtures are point-in-time.** Drift against the vendor UI is invisible
  until refreshed.
- **Offline modes don't validate the vendor's server-side analysis.**
  Platform statistics are the vendor's job; these tests cover your code's
  SDK interaction only.
- **Per-vendor gaps** (Statsig localMode still pings on some init paths;
  Split.io has no override API; Amplitude local evaluation lacks some flag
  types; VWO has no forced-decision API) are documented in each reference.

## References

- Per-vendor mechanics: [references/statsig.md](references/statsig.md),
  [references/optimizely.md](references/optimizely.md),
  [references/split-io.md](references/split-io.md),
  [references/amplitude.md](references/amplitude.md),
  [references/vwo.md](references/vwo.md).
- Experiment design gates: `ab-test-validity-checklist`.
- Reading results (peeking, guardrails, novelty): `experiment-results-interpreter`.
- SRM detection: `sample-ratio-mismatch-detector` agent.

Files in this skill

  • .tessl-plugin/plugin.json882 B
  • SKILL.md6.2 KB
  • references/amplitude.md5.4 KB
  • references/optimizely-recipes.md1.7 KB
  • references/optimizely.md5.7 KB
  • references/split-io-example.md1.4 KB
  • references/split-io.md10.8 KB
  • references/statsig.md4.9 KB
  • references/vwo.md4.6 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.