Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
How (not) to A/B Test
Search
Kyle Bashour
March 27, 2019
Programming
270
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
How (not) to A/B Test
Deck from my talk given at the SLUG meetup! Video here:
https://youtu.be/NVQuBow1B10
Kyle Bashour
March 27, 2019
Other Decks in Programming
See All in Programming
PumaからFalconに移行したRailsアプリケーションでの実践
falcon8823
0
170
UnityでSystem.Net.WebSocketsなWebSocketサーバが動かないのでUnity Monoのコードを覗いてみた / about implementing websocket server with unity mono
drumath2237
1
610
作って学ぶSpring BootのAuto Configuration / JJUG Night Seminar 2026-10-19
rshindo
0
150
[JA] Domain Modeling with Vanilla Rails: 「操作」から再考するRailsの設計論
yasaichi
0
210
パズルゲームの作り方 / how to make puzzle games
kaityo256
PRO
2
290
Verilogで学ぶCPU自作入門
uyuki234
8
4.1k
なぜCTOを降りてFDEを選んだのか?〜なぜプロダクト企業がFDEで顧客の現場に踏み込むのか〜
gonta
1
210
AWSに止められる覚悟してますか?
morizo_1984
2
540
Optunaを作ったときにやりたかったこと、その後 (2026/10/16, Optuna Meetup #3)
iwiwi
1
430
contenteditable と日本語入力に向き合う
colorful12
0
200
HTML-in-Canvasで作る未来のWeb UI表現
clockmaker
5
5.1k
Simple Storage Service(S3) is not simple
iwatsukayura
0
290
Featured
See All Featured
Fireside Chat
paigeccino
43
4.1k
Docker and Python
trallard
47
4.2k
Everyday Curiosity
cassininazir
0
350
Building AI with AI
inesmontani
PRO
1
1.3k
Raft: Consensus for Rubyists
vanstee
142
7.8k
How to train your dragon (web standard)
notwaldorf
96
6.9k
Code Review Best Practice
trishagee
74
20k
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
Self-Hosted WebAssembly Runtime for Runtime-Neutral Checkpoint/Restore in Edge–Cloud Continuum
chikuwait
0
890
What's in a price? How to price your products and services
michaelherold
247
13k
Into the Great Unknown - MozCon
thekraken
41
2.8k
Odyssey Design
rkendrick25
PRO
2
870
Transcript
How (not) to A/B Test Lessons learned in experimentation at
Lyft Kyle Bashour • @kylebshr • 27 March 2019
What is an A/B test? @kylebshr
Hypothesis @kylebshr
Hypothesis @kylebshr
Experiment Setup FeatureFlag.yellowSignUpButton.on { button.setStyle(background: .yellow, text: .black) } .off
{ button.setStyle(background: .blue, text: .white) } @kylebshr
Experiment Setup // App launch: download assignment FeatureFlag.yellowSignUpButton.on { button.setStyle(background:
.yellow, text: .black) } .off { button.setStyle(background: .blue, text: .white) } @kylebshr
Experiment Setup // App launch: download assignment // Only expose
once feature flag is accessed FeatureFlag.yellowSignUpButton.on { button.setStyle(background: .yellow, text: .black) } .off { button.setStyle(background: .blue, text: .white) } @kylebshr
Monitor Results @kylebshr
Ship It! @kylebshr
A/B Testing Products @kylebshr
Lyft.app @kylebshr
Project X @kylebshr
Implementation @kylebshr
Implementation @kylebshr
Implementation @kylebshr
Implementation @kylebshr
Implementation @kylebshr
Sidenote @UIApplicationMain class MyAppDelegate: UIResponder, UIApplicationDelegate {...} @kylebshr
Sidenote // main.swift import UIKit UIApplicationMain( CommandLine.argc, CommandLine.unsafeArgv, nil, //
Or a UIApplication subclass NSStringFromClass(MyAppDelegate.self) ) @kylebshr
Implementation @kylebshr
Results @kylebshr
What’s broken? And why? @kylebshr
It’s hard to maintain two apps @kylebshr
@kylebshr
Demand Graph Redesign @kylebshr
Implementation protocol GraphDisplaying { func display(_ data: [Int]) func bezierCurve(from
points: [Int]) ... } class BarGraphView: UIView, GraphDisplaying {...} @kylebshr
Implementation typealias GraphView = UIView & GraphDisplaying final class DemandGraphView:
UIView { private let graphView: GraphView override init(frame: CGRect) { self.graphView = BarGraphView() super.init(frame: frame) } func display(_ model: DemandViewModel) { self.graphView.display(model.demand) } } @kylebshr
Implementation class InteractiveBarGraphView: UIView, GraphDisplaying {...} @kylebshr
Implementation final class DemandGraphView: UIView { private let graphView: GraphView
override init(frame: CGRect) { if FeatureFlag.demandGraphV2.getValue() { self.graphView = InteractiveBarGraphView() } else { self.graphView = BarGraphView() } super.init(frame: frame) } func display(_ model: DemandViewModel) { self.graphView.display(model.demand) } } @kylebshr
Results @kylebshr
What does a good A/B test look like? @kylebshr
Driver Home Redesign @kylebshr
Driver Home Redesign @kylebshr
Implementation // DriverHomeViewController.swift private let newsFeedViewController = NewsfeedFeedViewController() override func
viewDidLoad() { self.setUpNewsFeedPanel() } @kylebshr
Implementation private lazy var newsFeedViewController = NewsfeedFeedViewController() private lazy var
incentivesViewController = IncentivesViewController() override func viewDidLoad() { FeatureFlag.homeTabIncentives.on { self.setUpIncentivesPanel() } .off { self.setUpNewsFeedPanel() } } @kylebshr
Results @kylebshr
Swift Recap • Learned what @UIApplicationMain does • Protocols can
help with clean A/B structure • In other cases, lazy instantiation can help @kylebshr
A/B Testing Recap • Limit scope • Solid hypothesis •
Build for shipping @kylebshr
Thanks for listening! Questions? @kylebshr
@kylebshr