Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up
for free
Writing Testable Code
Bas Broek
November 28, 2019
Programming
0
19
Writing Testable Code
Workshop at The Swift Alps 2019
Bas Broek
November 28, 2019
Tweet
Share
More Decks by Bas Broek
See All by Bas Broek
basthomas
0
8
basthomas
0
12
basthomas
0
110
basthomas
0
79
basthomas
0
16
basthomas
0
79
basthomas
0
27
basthomas
1
280
basthomas
0
90
Other Decks in Programming
See All in Programming
mehowte
0
180
joergneumann
0
140
saten
1
180
maito1201
0
140
konstantin_diener
0
130
numeroanddev
1
230
line_developers_tw2
0
4.4k
koheisakata
0
110
madai0517
1
200
boriswilhelms
0
130
sters
2
140
panini
1
160
Featured
See All Featured
paulrobertlloyd
71
3.6k
cromwellryan
104
6.2k
sachag
446
36k
sachag
267
17k
iamctodd
19
2k
tammielis
237
23k
jponch
103
5.1k
marcelosomers
221
15k
hannesfritz
28
950
chrislema
173
14k
moore
125
21k
wjessup
339
16k
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