A/B Test Analyzer
Overview
This skill helps design and analyze controlled online experiments (A/B and A/B/n tests) with statistical rigor and honest interpretation. It covers the full lifecycle: hypothesis framing, sample-size and duration planning, choosing the right test, computing p-values and confidence intervals, and avoiding the traps that produce false wins.
Keywords: A/B test, split test, experiment, hypothesis, sample size, power, MDE, minimum detectable effect, statistical significance, p-value, confidence interval, conversion rate, lift, two-proportion z-test, t-test, chi-square, peeking, multiple comparisons, Simpson's paradox, SRM, novelty effect.
Use this skill whenever someone wants to plan an experiment, decide if a result is real, or sanity-check an analysis someone else did.
Core Mental Model
- An A/B test estimates a causal effect by randomizing units (usually users) into control and treatment.
- You are testing a null hypothesis (no difference) against an alternative (there is a difference). A p-value is
P(data this extreme or more | null is true) — NOT the probability the null is true, and NOT the probability your variant is better.
- Two error types: Type I (false positive, rate = alpha, typically 0.05) and Type II (false negative, rate = beta; power = 1 - beta, typically 0.80).
- You must fix sample size and test duration BEFORE you start. Stopping when significant ("peeking") inflates the false-positive rate dramatically.
Workflow
Follow these steps in order. Do not skip planning steps even when only asked to "analyze results" — verify the plan was sound first.
Frame the hypothesis. Turn the vague goal into a falsifiable statement: "Changing X will increase metric M from baseline b by at least the MDE, because [mechanism]." Identify ONE primary metric (the Overall Evaluation Criterion / OEC). Pre-register guardrail metrics. See references/methodology.md for OEC selection.
Pick the metric type.
- Binary / rate (conversion, click, signup) → two-proportion test.
- Continuous (revenue per user, time on page, order value) → Welch's t-test (means).
- More than 2 variants → chi-square (rates) or ANOVA-style + correction.
Set the design parameters.
- Baseline rate or baseline mean (
b).
- Minimum Detectable Effect (MDE): the smallest lift worth detecting. Express relative (e.g. +5%) and convert to absolute.
- alpha (default 0.05), power (default 0.80), one- vs two-sided (almost always two-sided).
Compute required sample size and duration. Run scripts/abtest.py size. Divide required N per arm by daily eligible traffic per arm to get duration in days. Round duration UP to full weeks to cover weekday/weekend seasonality (min 1 week, ideally 2).
Run the test untouched for the full pre-planned duration. No peeking-with-action. (You may monitor guardrails for catastrophic harm only.)
Validate data quality BEFORE looking at the result.
- Sample Ratio Mismatch (SRM): is the actual split close to the planned split? Run
scripts/abtest.py srm. If p < 0.001, the experiment is broken — do NOT trust the result.
- Check for logging bugs, bot traffic, and that randomization was at the right unit.
Run the significance test. Use scripts/abtest.py prop (rates) or scripts/abtest.py ttest (means). Report: effect size (absolute + relative lift), confidence interval, p-value, and whether it crossed alpha.
Interpret honestly. A non-significant result is NOT proof of no effect — report the CI to show what effects are still plausible. A significant result with a CI that includes trivially small lifts may not be worth shipping. See references/interpretation-guide.md.
Account for multiplicity. If you tested multiple metrics or variants, apply a correction (Bonferroni or Benjamini-Hochberg). See references/methodology.md.
Write it up. Use templates/experiment-report.md so decisions are reproducible and reviewable.
Choosing the Test (decision table)
| Metric |
Variants |
Test |
Script command |
| Rate / proportion |
2 |
Two-proportion z-test |
abtest.py prop |
| Rate / proportion |
>2 |
Chi-square (then pairwise + correction) |
abtest.py chisq |
| Continuous mean |
2 |
Welch's t-test |
abtest.py ttest |
| Continuous mean |
>2 |
ANOVA + post-hoc (use a stats lib) |
external |
| Any |
— |
Sample size planning |
abtest.py size |
| Any |
— |
SRM / sanity check |
abtest.py srm |
Quick Worked Example
Baseline conversion 10%, want to detect a relative +5% (→ 10.5% absolute), alpha 0.05, power 0.80, two-sided:
python scripts/abtest.py size --baseline 0.10 --mde-rel 0.05 --alpha 0.05 --power 0.80
→ ~ 58,000 users per arm. At 4,000 eligible users/arm/day → ~15 days → round to 2 full weeks.
After the test, control 5,800/58,000 = 10.00%, treatment 6,150/58,000 = 10.60%:
python scripts/abtest.py prop --c-conv 5800 --c-n 58000 --t-conv 6150 --t-n 58000
→ absolute lift +0.60pp, relative +6.0%, 95% CI on absolute difference, and a p-value. Decide using the CI, not just the p-value. See examples/conversion-test.md for the full walkthrough.
Best Practices
- Pre-register: hypothesis, primary metric, MDE, sample size, duration, and the decision rule BEFORE launch.
- Randomize at the right unit (usually user, not session/pageview) and keep it consistent across the funnel.
- Run for whole weeks; account for day-of-week and novelty effects.
- Report effect size + confidence interval first; treat the p-value as secondary.
- Use one primary OEC; everything else is a guardrail or exploratory.
- Always run an SRM check before trusting any result.
- Prefer two-sided tests; one-sided needs strong justification.
Common Pitfalls
- Peeking / optional stopping: checking daily and stopping at first significance turns a 5% false-positive rate into 20-30%+. Fix sample size up front, or use a proper sequential/Bayesian method.
- p-hacking / metric shopping: testing 20 metrics and reporting the one with p<0.05. Correct for multiplicity.
- Simpson's paradox: an aggregate winner can lose in every segment if traffic mix differs. Check key segments; beware mixing pre/post populations.
- Sample Ratio Mismatch: a broken split (e.g. 52/48 instead of 50/50) signals a bug that biases everything.
- Confusing significance with importance: with huge N, trivially small lifts become "significant." Use the MDE and the CI.
- Confusing non-significance with "no effect": underpowered tests fail to detect real effects. Report the CI.
- Novelty/primacy effects: early behavior differs from steady state; don't conclude from day 1-2.
- Multiple comparisons across variants: A/B/C/D testing without correction inflates false positives.
See references/pitfalls-checklist.md for a pre-launch and pre-decision checklist to run every time.
Bundled Files
scripts/abtest.py — runnable, stdlib-only calculator: sample size, two-proportion z-test, Welch's t-test, chi-square, SRM. Run python scripts/abtest.py --help.
references/methodology.md — deep dive on hypotheses, OEC, power, MDE, multiplicity corrections, sequential testing, Bayesian alternative.
references/interpretation-guide.md — how to read p-values, CIs, and what each outcome (sig/non-sig × big/small effect) actually means for a ship decision.
references/pitfalls-checklist.md — copy-paste checklist for design and analysis review.
templates/experiment-report.md — fill-in template for documenting an experiment.
examples/conversion-test.md — a complete end-to-end worked example.
1---2name: ab-test-analyzer3description: Designs and analyzes A/B tests end-to-end — frames a sharp hypothesis, computes required sample size and test duration, runs significance tests (two-proportion z-test, Welch's t-test, chi-square), reports confidence intervals and lift, and flags common pitfalls like peeking, multiple comparisons, and Simpson's paradox. Use this skill when the user mentions A/B testing, split testing, experiment design, conversion-rate experiments, statistical significance, p-values, sample size or power calculations, "did this experiment win", minimum detectable effect (MDE), or asks to interpret experiment results honestly. Includes a runnable stats script (scripts/abtest.py).4license: MIT5---67# A/B Test Analyzer89## Overview10This skill helps design and analyze controlled online experiments (A/B and A/B/n tests) with statistical rigor and honest interpretation. It covers the full lifecycle: hypothesis framing, sample-size and duration planning, choosing the right test, computing p-values and confidence intervals, and avoiding the traps that produce false wins.1112Keywords: A/B test, split test, experiment, hypothesis, sample size, power, MDE, minimum detectable effect, statistical significance, p-value, confidence interval, conversion rate, lift, two-proportion z-test, t-test, chi-square, peeking, multiple comparisons, Simpson's paradox, SRM, novelty effect.1314Use this skill whenever someone wants to plan an experiment, decide if a result is real, or sanity-check an analysis someone else did.1516## Core Mental Model17- An A/B test estimates a **causal effect** by randomizing units (usually users) into control and treatment.18- You are testing a **null hypothesis** (no difference) against an **alternative** (there is a difference). A p-value is `P(data this extreme or more | null is true)` — NOT the probability the null is true, and NOT the probability your variant is better.19- Two error types: **Type I** (false positive, rate = alpha, typically 0.05) and **Type II** (false negative, rate = beta; **power** = 1 - beta, typically 0.80).20- **You must fix sample size and test duration BEFORE you start.** Stopping when significant ("peeking") inflates the false-positive rate dramatically.2122## Workflow23Follow these steps in order. Do not skip planning steps even when only asked to "analyze results" — verify the plan was sound first.24251. **Frame the hypothesis.** Turn the vague goal into a falsifiable statement: "Changing X will increase metric M from baseline b by at least the MDE, because [mechanism]." Identify ONE primary metric (the Overall Evaluation Criterion / OEC). Pre-register guardrail metrics. See `references/methodology.md` for OEC selection.26272. **Pick the metric type.**28 - Binary / rate (conversion, click, signup) → two-proportion test.29 - Continuous (revenue per user, time on page, order value) → Welch's t-test (means).30 - More than 2 variants → chi-square (rates) or ANOVA-style + correction.31323. **Set the design parameters.**33 - Baseline rate or baseline mean (`b`).34 - Minimum Detectable Effect (MDE): the smallest lift worth detecting. Express relative (e.g. +5%) and convert to absolute.35 - alpha (default 0.05), power (default 0.80), one- vs two-sided (almost always two-sided).36374. **Compute required sample size and duration.** Run `scripts/abtest.py size`. Divide required N per arm by daily eligible traffic per arm to get duration in days. Round duration UP to full weeks to cover weekday/weekend seasonality (min 1 week, ideally 2).38395. **Run the test untouched** for the full pre-planned duration. No peeking-with-action. (You may monitor guardrails for catastrophic harm only.)40416. **Validate data quality BEFORE looking at the result.**42 - Sample Ratio Mismatch (SRM): is the actual split close to the planned split? Run `scripts/abtest.py srm`. If p < 0.001, the experiment is broken — do NOT trust the result.43 - Check for logging bugs, bot traffic, and that randomization was at the right unit.44457. **Run the significance test.** Use `scripts/abtest.py prop` (rates) or `scripts/abtest.py ttest` (means). Report: effect size (absolute + relative lift), confidence interval, p-value, and whether it crossed alpha.46478. **Interpret honestly.** A non-significant result is NOT proof of no effect — report the CI to show what effects are still plausible. A significant result with a CI that includes trivially small lifts may not be worth shipping. See `references/interpretation-guide.md`.48499. **Account for multiplicity.** If you tested multiple metrics or variants, apply a correction (Bonferroni or Benjamini-Hochberg). See `references/methodology.md`.505110. **Write it up.** Use `templates/experiment-report.md` so decisions are reproducible and reviewable.5253## Choosing the Test (decision table)54| Metric | Variants | Test | Script command |55|---|---|---|---|56| Rate / proportion | 2 | Two-proportion z-test | `abtest.py prop` |57| Rate / proportion | >2 | Chi-square (then pairwise + correction) | `abtest.py chisq` |58| Continuous mean | 2 | Welch's t-test | `abtest.py ttest` |59| Continuous mean | >2 | ANOVA + post-hoc (use a stats lib) | external |60| Any | — | Sample size planning | `abtest.py size` |61| Any | — | SRM / sanity check | `abtest.py srm` |6263## Quick Worked Example64Baseline conversion 10%, want to detect a relative +5% (→ 10.5% absolute), alpha 0.05, power 0.80, two-sided:6566```67python scripts/abtest.py size --baseline 0.10 --mde-rel 0.05 --alpha 0.05 --power 0.8068```69→ ~ 58,000 users per arm. At 4,000 eligible users/arm/day → ~15 days → round to 2 full weeks.7071After the test, control 5,800/58,000 = 10.00%, treatment 6,150/58,000 = 10.60%:72```73python scripts/abtest.py prop --c-conv 5800 --c-n 58000 --t-conv 6150 --t-n 5800074```75→ absolute lift +0.60pp, relative +6.0%, 95% CI on absolute difference, and a p-value. Decide using the CI, not just the p-value. See `examples/conversion-test.md` for the full walkthrough.7677## Best Practices78- Pre-register: hypothesis, primary metric, MDE, sample size, duration, and the decision rule BEFORE launch.79- Randomize at the right unit (usually user, not session/pageview) and keep it consistent across the funnel.80- Run for whole weeks; account for day-of-week and novelty effects.81- Report effect size + confidence interval first; treat the p-value as secondary.82- Use one primary OEC; everything else is a guardrail or exploratory.83- Always run an SRM check before trusting any result.84- Prefer two-sided tests; one-sided needs strong justification.8586## Common Pitfalls87- **Peeking / optional stopping:** checking daily and stopping at first significance turns a 5% false-positive rate into 20-30%+. Fix sample size up front, or use a proper sequential/Bayesian method.88- **p-hacking / metric shopping:** testing 20 metrics and reporting the one with p<0.05. Correct for multiplicity.89- **Simpson's paradox:** an aggregate winner can lose in every segment if traffic mix differs. Check key segments; beware mixing pre/post populations.90- **Sample Ratio Mismatch:** a broken split (e.g. 52/48 instead of 50/50) signals a bug that biases everything.91- **Confusing significance with importance:** with huge N, trivially small lifts become "significant." Use the MDE and the CI.92- **Confusing non-significance with "no effect":** underpowered tests fail to detect real effects. Report the CI.93- **Novelty/primacy effects:** early behavior differs from steady state; don't conclude from day 1-2.94- **Multiple comparisons across variants:** A/B/C/D testing without correction inflates false positives.9596See `references/pitfalls-checklist.md` for a pre-launch and pre-decision checklist to run every time.9798## Bundled Files99- `scripts/abtest.py` — runnable, stdlib-only calculator: sample size, two-proportion z-test, Welch's t-test, chi-square, SRM. Run `python scripts/abtest.py --help`.100- `references/methodology.md` — deep dive on hypotheses, OEC, power, MDE, multiplicity corrections, sequential testing, Bayesian alternative.101- `references/interpretation-guide.md` — how to read p-values, CIs, and what each outcome (sig/non-sig × big/small effect) actually means for a ship decision.102- `references/pitfalls-checklist.md` — copy-paste checklist for design and analysis review.103- `templates/experiment-report.md` — fill-in template for documenting an experiment.104- `examples/conversion-test.md` — a complete end-to-end worked example.