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
TDD in iOS
Search
Dominik Hauser
December 04, 2019
Programming
0
39
TDD in iOS
German presentation about TDD in iOS
Dominik Hauser
December 04, 2019
Tweet
Share
Other Decks in Programming
See All in Programming
DDD, necessary but insufficient: physical design principles for microservices
cer
PRO
0
2.2k
9年開発を牽引して見えてきた、共通化すべきものと個別でつくるもの ~プログラム言語~
shinout
1
280
Kotlinを用いたDSL的な設計手法と使用上の注意
kohii00
3
530
Prepare for Jakarta EE 11 - Performance and Developer Productivity
ivargrimstad
0
530
WasmOS: Wasmを実行する自作Microkernel
riru
0
370
両面どころかインフラもTSでできるよ ~ 全方位TypeScriptによるプロダクト開発 ~
myfinder
9
2.5k
オブジェクトしこう
okuramasafumi
2
130
document.write再考
brn
5
2.5k
WebComponentsで フレームワークを1ページに共存させる
webuilder240
0
150
WinUI 3デモ - "CommunityToolkit.Mvvm"NuGetパッケージ編
andrewkeepcoding
0
140
マイ隙間家具OSSたちのご紹介
karupanerura
2
160
オブジェクト指向のリ・オリエンテーション~歴史を振り返り、AI時代に向きなおる~
hanyudaeiiti
2
220
Featured
See All Featured
YesSQL, Process and Tooling at Scale
rocio
160
13k
Building Effective Engineering Teams - LeadDev
addyosmani
25
1.8k
Making Projects Easy
brettharned
106
5.4k
We Have a Design System, Now What?
morganepeng
42
6.7k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
12
1.4k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
6
950
[RailsConf 2023] Rails as a piece of cake
palkan
21
3.8k
How GitHub (no longer) Works
holman
301
140k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
153
14k
For a Future-Friendly Web
brad_frost
170
8.9k
The Mythical Team-Month
searls
214
42k
Happy Clients
brianwarren
91
6.3k
Transcript
TDD und iOS Dominik Hauser, @dasdom
The quality and performance achieved could not have been done
without the use of unit testing. — Bill Bumgarner (bbum), über Core Data 1.0
Vorteile
Vorteile1 · Refaktorierbarkeit · Schnelles Feedback · Gedankenstütze · Doppelte
Buchführung · Regressionsschutz 1 Von (subjektiv) wichtig nach unwichtig
Planning/Feedback Loops Release Plan Code Iteration Plan Acceptance Test Stand
Up Meeting Pair Negotiation Unit Test Pair Programming Months Weeks Days One day Hours Minutes Seconds DonWells (CC BY-SA 3.0)
Wie? Red Green Refactor
Warum so wenig Tests?
"Was soll denn da kaputt gehen?"
if index-1 < userNames.count { nameLabel.text = userNames[index] } else
{ nameLabel.text = "Unknown" }
if index-1 < userNames.count { nameLabel.text = userNames[index] } else
{ nameLabel.text = "Unknown" }
class TableViewCell: UITableViewCell { let label = UILabel() override init(style:
UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) addSubview(label) } }
class TableViewCell: UITableViewCell { let label = UILabel() override init(style:
UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) addSubview(label) } }
"Was soll denn da kaputt gehen?" 1. That can’t happen.
2. That doesn’t happen on my machine. 3. That shouldn’t happen. 4. Why does that happen? 5. Oh, I see. 6. How did that ever work?2 2 Mike W. Cremer
"Machen wir nach dem Release."
RELEASE 1.0 TESTS RELEASE 1.1 Login Login Tests User User
Tests Logout Logout Tests Password reset Password Tests Blocking of users Blocking tests ... ...
RELEASE 1.0 RELEASE 1.1 TESTS Login Login Tests User User
Tests Logout Logout Tests Password reset Password Tests Blocking of users Blocking tests ... ...
RELEASE 1.0 RELEASE 1.1 RELEASE 1.1.1 Login User Logout Password
reset Blocking of users ... ...
Nach den Release ist vor den Release
"UI kann man nicht testen."
func test_viewHasLabel() { sut.loadViewIfNeeded() XCTAssertTrue(sut.label.isDescendant(of: sut.view)) }
func test_loadingView_registersCell() { // when sut.loadViewIfNeeded() // then let cell
= sut.tableView.dequeueReusableCell( withIdentifier: "Cell", for: IndexPath(row: 0, section: 0)) XCTAssertNotNil(cell) XCTAssertTrue(cell is Cell) }
func test_showNext_pushesViewController() { // given let navControllerMock = NavigationControllerMock( rootViewController:
sut) let user = User(name: "Foobar") // when sut.showNext(with: user) // then let detailController = navControllerMock.lastPushedVC as! DetailViewController XCTAssertEqual(detailController.user, user) }
"UI kann man nicht testen." Kann man
Tips & Tricks
Dependency Injection (Inversion of Control)
Zum Beispiel: Constructor Injection let defaultsStub = DefaultsStub(boolToReturn: false) let
user = User(defaults: defaultsStub)
Ausserdem · Constructor Injection · Setter Injection · Interface Injection
Abstraktion
Abstraktion Beispiel: Alerts protocol Alerter { func presentOKAlert(on: UIViewController, title:
String, message: String, okAction: ()->Void) }
View laden func test_foo() { // given ... // when
view loads sut.loadViewIfNeeded() // then ... }
viewWill/DidAppear func test_foo() { // given ... // when view
appears sut.beginAppearanceTransition(true, animated: false) sut.endAppearanceTransition() // then ... }
Modal presentation func test_presentationOfViewController() { // given let window =
UIWindow(frame: CGRect(x: 0, y: 0, width: 300, height: 300)) window.rootViewController = sut window.makeKeyAndVisible() // when sut.showNext() // then XCTAssertTrue(sut.presentedViewController is DetailViewController) }
Bestehender Code Wie anfangen?
Bug ➜ Test
Neues Feature ➜ Test
pragprog.com/book/jrlegios/ ios-unit-testing-by-example
Promolink http://leanpub.com/ tdd_ios_gimme_the_cod e/c/macdev
None
Promolink http://leanpub.com/ tdd_ios_gimme_the_cod e/c/macdev
Ende
Ende!
None