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
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
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
51
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
170
Accessibility on Apple Platforms: Beyond VoiceOver
basthomas
0
190
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
ローカルLLMでどこまでコードが書けるか -縮小版 / How much code can be written on a local LLM Shortened
kishida
2
190
技術記事、 専門家としてのプログラマ、 言語化
mizchi
14
7.5k
Claude Opus 4.6以後の受託開発エンジニアの変化(Claude Code開発ノウハウ大公開スペシャルbyクラスメソッド)
iidatakuma
1
780
Generative UI & AI-Assistants for Your Angular Solutions
manfredsteyer
PRO
1
190
鹿野さんに聞く!『TypeScriptコードレシピ集』で磨く実践力
tonkotsuboy_com
4
1.1k
ソフトウェア設計に溶けるインフラ ― AWS CDK のインフラ認識論
konokenj
2
540
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
260
AWS CDK を「作」ってみた 〜フルスクラッチで見えた CDK の裏側〜 / aws-cdk-from-scratch
gotok365
3
430
共通化で考えるべきは、実装より公開する型だった
codeegg
0
250
PHP Application における Kubernetes 内 gRPC 通信
ganchiku
0
480
Performance Engineering for Everyone
elenatanasoiu
0
270
「正の参照」と 「負の導出」で組む ハーネスエンジニアリング
cottpan
1
140
Featured
See All Featured
The browser strikes back
jonoalderson
0
1.4k
The Invisible Side of Design
smashingmag
301
52k
The SEO identity crisis: Don't let AI make you average
varn
0
510
4 Signs Your Business is Dying
shpigford
187
22k
Are puppies a ranking factor?
jonoalderson
1
3.7k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.8k
Design of three-dimensional binary manipulators for pick-and-place task avoiding obstacles (IECON2024)
konakalab
0
490
XXLCSS - How to scale CSS and keep your sanity
sugarenia
249
1.3M
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.8k
Why Our Code Smells
bkeepers
PRO
340
58k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
287
14k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
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