Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Network Testing in Swift with DVR
Search
Sam Soffes
October 08, 2015
Programming
0
6.5k
Network Testing in Swift with DVR
Walkthrough of how to use DVR and the design behind it. Given at Realm on 2015-10-08.
Sam Soffes
October 08, 2015
Tweet
Share
More Decks by Sam Soffes
See All by Sam Soffes
Starting a Mobile Design System
soffes
0
110
Building Functional Apps in Swift for iOS & OS X
soffes
5
13k
Go
soffes
2
590
Favorites
soffes
2
800
Seesaw — Under the Playground
soffes
2
400
Ubiquitously Connected to the World
soffes
0
200
API First, Then Apps
soffes
3
350
Building Realtime Apps
soffes
6
7.7k
Dispatch Awesome
soffes
8
920
Other Decks in Programming
See All in Programming
動作確認やテストで漏れがちな観点3選
starfish719
6
1k
Amazon ECS とマイクロサービスから考えるシステム構成
hiyanger
2
570
第3回関東Kaggler会_AtCoderはKaggleの役に立つ
chettub
3
1k
SwiftUI Viewの責務分離
elmetal
PRO
1
240
PHP ステートレス VS ステートフル 状態管理と並行性 / php-stateless-stateful
ytake
0
100
苦しいTiDBへの移行を乗り越えて快適な運用を目指す
leveragestech
0
650
pylint custom ruleで始めるレビュー自動化
shogoujiie
0
120
2024年のkintone API振り返りと2025年 / kintone API look back in 2024
tasshi
0
220
Flutter × Firebase Genkit で加速する生成 AI アプリ開発
coborinai
0
160
Pythonでもちょっとリッチな見た目のアプリを設計してみる
ueponx
1
570
Rubyで始める関数型ドメインモデリング
shogo_tksk
0
120
『GO』アプリ バックエンドサーバのコスト削減
mot_techtalk
0
150
Featured
See All Featured
StorybookのUI Testing Handbookを読んだ
zakiyama
28
5.5k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
44
7k
How to train your dragon (web standard)
notwaldorf
91
5.8k
The World Runs on Bad Software
bkeepers
PRO
67
11k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
29
2.4k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
21
2.5k
Fantastic passwords and where to find them - at NoRuKo
philnash
51
3k
For a Future-Friendly Web
brad_frost
176
9.5k
Fontdeck: Realign not Redesign
paulrobertlloyd
83
5.4k
Bash Introduction
62gerente
611
210k
The Cult of Friendly URLs
andyhume
78
6.2k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
356
29k
Transcript
DVR Networking tes-ng in Swi/.
Hi, I'm @soffes.
DVR is this thing I made when I worked at
Venmo.
Inspired by VCR for Ruby.
Records networking and plays it back in tests.
Using DVR
// Example XCTest func testTimeline() { let expectation = expectationWithDescription("Networking")
// Your network client let client = APIClient() client.getTimeline { success in XCTAssertTrue(success) expectation.fulfill() } waitForExpectationsWithTimeout(1, handler: nil) }
// DVR Session let dvr = Session(cassetteName: "timeline") // Pass
into initializer let client = APIClient(session: dir)
class APIClient { let session: NSURLSession init(session: NSURLSession = NSURLSession.sharedSession())
{ self.session = session } }
func getTimeline(completion: Bool -> Void) { let request = NSURLRequest(URL:
timelineURL) session.dataTaskWithRequest(request) { _, _, _ completion(true) }.resume() }
DVR Internals
class Session: NSURLSession { let cassetteName: String let backingSession: NSURLSession
init(cassetteName: StringbackingSession: NSURLSession = NSURLSession.sharedSession()) { self.cassetteName = cassetteName self.backingSession = backingSession super.init() } override func dataTaskWithRequest(request: NSURLRequest) -> NSURLSessionDataTask { return SessionDataTask(session: self, request: request) } }
Call resume() & then magic.
class SessionDataTask: NSURLSessionDataTask { override func resume() { // Playback
cassette on disk or record } }
Casse%es are stored as JSON.
{ "name" : "example", "interactions" : [ { "recorded_at" :
1434688721.440751, "request" : { "method" : "GET", "url" : "http:\/\/example.com" } "response" : { "body" : "hello", "status" : 200, "url" : "http:\/\/example.com\/", "headers" : { "Cache-Control" : "max-age=604800", "Content-Type" : "text\/plain", "Last-Modified" : "Fri, 09 Aug 2013 23:54:35 GMT", "Content-Length" : "5" } } } ] }
Why this over mocks?
Mocks are inherently fragile. You have to couple your tes7ng
code with the implementa7on details of your test. — Dave Abrahams, Protocol-Oriented Programming in Swi3
class DisabledSession: NSURLSession { override func dataTaskWithRequest(request: NSURLRequest, completionHandler: (NSData?,
NSURLResponse?, NSError?) -> Void) -> NSURLSessionDataTask? { XCTFail("Networking disabled") return nil } }
github.com/venmo/DVR
Thanks