Zum Hauptinhalt springen
Dieser Leitfaden führt Sie durch einen A/B-Test, der zwei Varianten eines Checkout-Flows in einer mobilen App vergleicht. Die primäre Metrik ist die Sitzungsdauer (Sekunden); die sekundäre Metrik ist die Anzahl der abgeschlossenen Schritte.

Experimentdaten

// Variant A (control): original checkout flow
val controlDurationSec = doubleArrayOf(
    34.2, 41.5, 38.7, 45.1, 36.9, 42.3, 39.8, 44.6, 37.4, 40.1,
    43.2, 35.8, 41.9, 38.3, 46.0, 39.5, 42.7, 37.1, 40.8, 44.3
)

// Variant B (treatment): simplified checkout flow
val treatmentDurationSec = doubleArrayOf(
    29.1, 33.8, 31.5, 35.2, 28.7, 32.4, 30.9, 34.6, 29.8, 33.1,
    31.2, 27.5, 34.0, 30.3, 36.1, 31.8, 33.5, 28.9, 32.7, 35.8
)

Schritt 1: Beide Gruppen zusammenfassen

val controlSummary = controlDurationSec.describe()
val treatmentSummary = treatmentDurationSec.describe()

controlSummary.mean                // control average
treatmentSummary.mean              // treatment average
controlSummary.standardDeviation   // control spread
treatmentSummary.standardDeviation // treatment spread

Schritt 2: Annahmen prüfen

Normalität

val controlNormality = shapiroWilkTest(controlDurationSec)
val treatmentNormality = shapiroWilkTest(treatmentDurationSec)

controlNormality.pValue
treatmentNormality.pValue

Varianzhomogenität

val variances = leveneTest(controlDurationSec, treatmentDurationSec)
variances.pValue

Schritt 3: Test auswählen und durchführen

// Welch's t-test (default: equalVariances = false)
val result = tTest(controlDurationSec, treatmentDurationSec)

result.statistic
result.pValue
result.confidenceInterval // 95% CI for the difference in means
result.isSignificant()    // true if p < 0.05
Wenn der Levene-Test gleiche Varianzen bestätigt hat:
val equalVar = tTest(
    controlDurationSec,
    treatmentDurationSec,
    equalVariances = true
)
equalVar.pValue

Einseitige Tests

Wenn Sie erwarten, dass die Behandlung die Sitzungsdauer verkürzt:
val oneSided = tTest(
    controlDurationSec,
    treatmentDurationSec,
    alternative = Alternative.GREATER // control > treatment
)
oneSided.pValue

Schritt 4: Zweite Metrik testen

Wenden Sie denselben Workflow auf die sekundäre Metrik an.
// Number of completed checkout steps per session
val controlSteps = doubleArrayOf(
    3.0, 4.0, 3.0, 5.0, 3.0, 4.0, 4.0, 5.0, 3.0, 4.0,
    4.0, 3.0, 4.0, 3.0, 5.0, 4.0, 4.0, 3.0, 4.0, 5.0
)
val treatmentSteps = doubleArrayOf(
    5.0, 5.0, 4.0, 5.0, 5.0, 5.0, 4.0, 5.0, 5.0, 5.0,
    4.0, 5.0, 5.0, 4.0, 5.0, 5.0, 5.0, 4.0, 5.0, 5.0
)

// Discrete step counts are typically non-normal
shapiroWilkTest(controlSteps).pValue

val stepsResult = mannWhitneyUTest(controlSteps, treatmentSteps)
stepsResult.pValue
stepsResult.isSignificant()

Schritt 5: Korrelation zwischen Metriken

Prüfen Sie, ob die beiden Metriken innerhalb jeder Gruppe zusammenhängen.
// Within the treatment group: do faster sessions correlate with more completed steps?
val correlation = spearmanCorrelation(treatmentDurationSec, treatmentSteps)

correlation.coefficient // negative means shorter sessions correlate with more steps
correlation.pValue
Spearman-Korrelation wird hier bevorzugt, da eine der Metriken (Schritte) ordinal ist.

Gepaarter Vorher/Nachher-Vergleich

Wenn dieselben Nutzer vor und nach einer Änderung gemessen werden, verwenden Sie gepaarte Tests.
val beforeMs = doubleArrayOf(
    340.2, 415.0, 387.1, 451.3, 369.5, 423.8, 398.0, 446.2, 374.1, 401.5
)
val afterMs = doubleArrayOf(
    310.5, 380.2, 355.8, 410.7, 335.1, 392.4, 365.3, 405.9, 340.8, 371.6
)

val paired = pairedTTest(beforeMs, afterMs)
paired.pValue
paired.confidenceInterval

// Non-parametric alternative
val wilcoxon = wilcoxonSignedRankTest(beforeMs, afterMs)
wilcoxon.pValue
Last modified on March 22, 2026