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
Writing Testable Code
Search
Bas Broek
November 28, 2019
Programming
150
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Writing Testable Code
Workshop at The Swift Alps 2019
Bas Broek
November 28, 2019
More Decks by Bas Broek
See All by Bas Broek
Roasting Your App's Accessibility
basthomas
0
53
Building an Accessibility Culture, One Step at a Time (Leeds)
basthomas
0
150
Building an Accessibility Culture, One Step at a Time
basthomas
1
120
Building a modern subscription experience on iOS
basthomas
0
220
Not an afterthought: accessibility from start to finish
basthomas
0
180
Accessibility on Apple Platforms: Beyond VoiceOver
basthomas
0
200
No Touch(screen) Required: Voice & Keyboard Accessibility
basthomas
0
190
Dancing with Dinosaurs: Objective-C and Swift Interop
basthomas
0
200
Effective Pull Request Reviews
basthomas
0
450
Other Decks in Programming
See All in Programming
関東Kaggler会_NVIDIA_Nemotron_コンペ_振り返り
rick_ds
0
500
torikago - Ruby::Boxで照らすモジュラモノリスの実行境界
se4weed
1
350
Claude Code全社展開のためにやったことn選~プラグイン302個・コミッター271人を支えるために~
kenchan
5
1.4k
VibeCodingからAgenticWorkflowへ
starfish719
0
340
言葉の格闘技のススメ~紙とペンと言葉から始める、キャリアの描き方~
progresscicada
2
140
ITヒヤリハットを整理してみた ~ライフサイクルと原因から考える再発防止策~
koukimiura
1
140
PHP Application における Kubernetes 内 gRPC 通信
ganchiku
0
590
「人を評価する AI」の設計と実装
ryoyanara
0
180
言語を使う側から、作る側へ。 自作 Lisp で得た新たな気づき。
andpad
0
160
yield再入門 #phpcon
o0h
PRO
0
990
Foundation Models frameworkで画像分析
ryodeveloper
1
600
生成AIで帳票OCRが「簡単に」作れる時代になった?
kon_shou
0
660
Featured
See All Featured
Hiding What from Whom? A Critical Review of the History of Programming languages for Music
tomoyanonymous
3
1.1k
Navigating Algorithm Shifts & AI Overviews - #SMXNext
aleyda
1
1.5k
Fashionably flexible responsive web design (full day workshop)
malarkey
408
67k
Bridging the Design Gap: How Collaborative Modelling removes blockers to flow between stakeholders and teams @FastFlow conf
baasie
0
640
Making the Leap to Tech Lead
cromwellryan
135
10k
Efficient Content Optimization with Google Search Console & Apps Script
katarinadahlin
PRO
1
790
Leveraging Curiosity to Care for An Aging Population
cassininazir
1
460
Jamie Indigo - Trashchat’s Guide to Black Boxes: Technical SEO Tactics for LLMs
techseoconnect
PRO
0
590
Designing for Timeless Needs
cassininazir
1
430
What’s in a name? Adding method to the madness
productmarketing
PRO
24
4.1k
Designing for humans not robots
tammielis
254
26k
職位にかかわらず全員がリーダーシップを発揮するチーム作り / Building a team where everyone can demonstrate leadership regardless of position
madoxten
64
56k
Transcript
Writing Testable Code 1 — @basthomas
Tests, what are they good for? 2 — @basthomas
What do you want to verify? 3 — @basthomas
How do you want to verify it? 4 — @basthomas
Dependency injection: three ways 5 — @basthomas
class Network { let urlSession: URLSession init(urlSession: URLSession = .shared)
{ self.urlSession = urlSession } } 6 — @basthomas
class Network { var urlSession = URLSession.shared } 7 —
@basthomas
class Network { func request(using urlSession: URLSession = .shared) {
} } 8 — @basthomas
Mocking through Protocols 9 — @basthomas
protocol UIApplicationProtocol { func canOpenURL(_ url: URL) -> Bool func
open( _ url: URL, options: [UIApplication.OpenExternalURLOptionsKey : Any], completionHandler completion: ((Bool) -> Void)? ) } extension UIApplication: UIApplicationProtocol {} 10 — @basthomas
Mocking through Subclassing 11 — @basthomas
class URLSessionDataTaskMock: URLSessionDataTask { private let closure: () -> Void
init(closure: @escaping () -> Void) { self.closure = closure } override func resume() { closure() } } 12 — @basthomas
class URLSessionMock: URLSession { var data: Data? var error: Error?
override func dataTask( with url: URL, completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void ) -> URLSessionDataTask { let data = self.data let error = self.error return URLSessionDataTaskMock { completionHandler(data, nil, error) } } } 13 — @basthomas
Custom asserts 14 — @basthomas
func assertManyThings( cookie: Cookie, file: StaticString = #file, line: UInt
= #line ) { XCTAssertTrue(cookie.isDoughy, file: file, line: line) XCTAssertLessThan(cookie.calories, 200, file: file, line: line) } 15 — @basthomas
XCTest 16 — @basthomas
XCTUnwrap XCTNoThrow 17 — @basthomas
Let's talk about "flaky" 18 — @basthomas
19 — @basthomas
Make sure your architecture takes testability into account 20 —
@basthomas
Tests, Code, Documentation 21 — @basthomas
Treat your test code like your real code 22 —
@basthomas
Reviews of tests, not reviews with tests 23 — @basthomas
"Your" turn: let's take a look at something you want
to have covered with tests 24 — @basthomas