Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
TDD in iOS
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Dominik Hauser
December 04, 2019
Programming
48
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
TDD in iOS
German presentation about TDD in iOS
Dominik Hauser
December 04, 2019
Other Decks in Programming
See All in Programming
當我們開始不讀 Code - AI Agent 時代,Code Review 與 Clean Code 還剩下什麼?
jame2408
1
200
The Rails Doctrine Decade
koic
2
590
Jetpack Compose Mechanisms
skydoves
3
820
AWSに止められる覚悟してますか?
morizo_1984
2
530
AI時代のコードレビューは人に向けるな、仕組みに向けろ
texmeijin
5
3.7k
【加筆修正版】Laravel のアプリケーションをどこにデプロイするか #phpcon_ehime
akase244
0
150
S3 TablesのIcebergデータに、AIエージェントからアクセスしてみた / 20261016developersio2026joetsu-accessing-iceberg-in-s3tables-via-agent
kasacchiful
PRO
0
150
AWS CDKのカスタムリソースでContinuum(旧Security Agent)を実装した話 | Implementing Continuum (formerly Security Agent) via AWS CDK Custom Resource
akihisaikeda
2
150
パズルゲームの作り方 / how to make puzzle games
kaityo256
PRO
2
290
Simple Storage Service(S3) is not simple
iwatsukayura
0
290
見えないものを探る要求要件定義に必要な基本的思考 / invisible-requirement-thinking
minodriven
15
8.5k
設計次第でAIコードの読む量は減らせる / designing-for-code-reading
minodriven
35
17k
Featured
See All Featured
Navigating the Design Leadership Dip - Product Design Week Design Leaders+ Conference 2024
apolaine
2
480
The Cult of Friendly URLs
andyhume
79
7k
Impact Scores and Hybrid Strategies: The future of link building
tamaranovitovic
0
460
Bioeconomy Workshop: Dr. Julius Ecuru, Opportunities for a Bioeconomy in West Africa
akademiya2063
PRO
1
410
Noah Learner - AI + Me: how we built a GSC Bulk Export data pipeline
techseoconnect
PRO
0
460
Building Experiences: Design Systems, User Experience, and Full Site Editing
marktimemedia
1
630
<Decoding/> the Language of Devs - We Love SEO 2024
nikkihalliwell
1
360
What does AI have to do with Human Rights?
axbom
PRO
1
2.5k
Redefining SEO in the New Era of Traffic Generation
szymonslowik
1
480
WCS-LA-2024
lcolladotor
0
890
The #1 spot is gone: here's how to win anyway
tamaranovitovic
4
1.2k
Hiding What from Whom? A Critical Review of the History of Programming languages for Music
tomoyanonymous
3
1.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